diff --git a/Libraries/FileHandler/CMakeLists.txt b/Libraries/FileHandler/CMakeLists.txt index 0e53197..58d34a8 100644 --- a/Libraries/FileHandler/CMakeLists.txt +++ b/Libraries/FileHandler/CMakeLists.txt @@ -19,6 +19,8 @@ set(FILEHANDLER_SOURCES File.cpp Image.cpp cst/cst.c + iff/stbl.c + iff/bhav.c iff/chunks.c iff/iff.c ) diff --git a/Libraries/FileHandler/iff/CMakeLists.txt b/Libraries/FileHandler/iff/CMakeLists.txt index 47c4fca..1c364d4 100644 --- a/Libraries/FileHandler/iff/CMakeLists.txt +++ b/Libraries/FileHandler/iff/CMakeLists.txt @@ -2,7 +2,9 @@ cmake_minimum_required(VERSION 2.6) project(iff) set(IFF_SOURCES - chunks.c + bhav.c + stbl.c + chunks.c iff.c ) diff --git a/Libraries/FileHandler/iff/chunks.c b/Libraries/FileHandler/iff/chunks.c index fb99166..367b732 100644 --- a/Libraries/FileHandler/iff/chunks.c +++ b/Libraries/FileHandler/iff/chunks.c @@ -23,238 +23,12 @@ int iff_parse_chunk(IFFChunk * ChunkInfo, const uint8_t * Buffer){ if( !strcmp(ChunkInfo->Type, "STR#") || !strcmp(ChunkInfo->Type, "CTSS") || !strcmp(ChunkInfo->Type, "FAMs") || - !strcmp(ChunkInfo->Type, "TTAs") ) + !strcmp(ChunkInfo->Type, "TTAs") ) return iff_parse_str(ChunkInfo, Buffer); - return 0; -} - -int iff_parse_str(IFFChunk * ChunkInfo, const uint8_t * Buffer){ - /* No bounds checking yet */ - IFF_STR * StringData; - unsigned Size = ChunkInfo->Size - 76; - if(Size < 2) - return 0; - ChunkInfo->FormattedData = malloc(sizeof(IFF_STR)); - if(ChunkInfo->FormattedData == NULL) - return 0; - memset(ChunkInfo->FormattedData, 0, sizeof(IFF_STR)); - StringData = (IFF_STR*) ChunkInfo->FormattedData; - StringData->Format = read_int16le(Buffer); - Buffer += 2; - if(Size-2 < 2) /* TSO allows this; as seen in the animations chunk in personglobals.iff */ - return 1; - - switch(StringData->Format){ - - case 0: { - unsigned i; - IFFStringPairNode * PrevPair = NULL; - - StringData->LanguageSets[0].PairCount = read_uint16le(Buffer); - Buffer += 2; - if(StringData->LanguageSets[0].PairCount == 0) - return 1; - - for(i=0; iLanguageSets[0].PairCount; i++){ - IFFStringPairNode * CurrentPair; - unsigned length; - CurrentPair = malloc(sizeof(IFFStringPairNode)); - memset(CurrentPair, 0, sizeof(IFFStringPairNode)); - - if(i == 0) StringData->LanguageSets[0].FirstPair = CurrentPair; - else PrevPair->NextPair = CurrentPair; - CurrentPair->PrevPair = PrevPair; - - /* Key */ - length = read_uint8le(Buffer); - if(length != 0){ - CurrentPair->Pair.Key = malloc(length+1); - memcpy(CurrentPair->Pair.Key, Buffer+1, length); - CurrentPair->Pair.Key[length] = 0x00; - } - Buffer += length+1; - - PrevPair = CurrentPair; - } - StringData->LanguageSets[0].LastPair = PrevPair; - } return 1; - - case -1: { - unsigned i; - IFFStringPairNode * PrevPair = NULL; - - StringData->LanguageSets[0].PairCount = read_uint16le(Buffer); - Buffer += 2; - if(StringData->LanguageSets[0].PairCount == 0) - return 1; - - for(i=0; iLanguageSets[0].PairCount; i++){ - IFFStringPairNode * CurrentPair; - unsigned length; - CurrentPair = malloc(sizeof(IFFStringPairNode)); - memset(CurrentPair, 0, sizeof(IFFStringPairNode)); - - if(i == 0) StringData->LanguageSets[0].FirstPair = CurrentPair; - else PrevPair->NextPair = CurrentPair; - CurrentPair->PrevPair = PrevPair; - - /* Key */ - length = strlen((char*)Buffer); - if(length != 0){ - CurrentPair->Pair.Key = malloc(length+1); - strcpy(CurrentPair->Pair.Key, (char*)Buffer); - } - Buffer += length+1; - - PrevPair = CurrentPair; - } - StringData->LanguageSets[0].LastPair = PrevPair; - } return 1; - - case -2: { - unsigned i; - IFFStringPairNode * PrevPair = NULL; - - StringData->LanguageSets[0].PairCount = read_uint16le(Buffer); - Buffer += 2; - if(StringData->LanguageSets[0].PairCount == 0) - return 1; - - for(i=0; iLanguageSets[0].PairCount; i++){ - IFFStringPairNode * CurrentPair; - unsigned length; - CurrentPair = malloc(sizeof(IFFStringPairNode)); - memset(CurrentPair, 0, sizeof(IFFStringPairNode)); - - if(i == 0) StringData->LanguageSets[0].FirstPair = CurrentPair; - else PrevPair->NextPair = CurrentPair; - CurrentPair->PrevPair = PrevPair; - - /* Key */ - length = strlen((char*)Buffer); - if(length != 0){ - CurrentPair->Pair.Key = malloc(length+1); - strcpy(CurrentPair->Pair.Key, (char*)Buffer); - } - Buffer += length+1; - - /* Value */ - length = strlen((char*)Buffer); - if(length != 0){ - CurrentPair->Pair.Value = malloc(length+1); - strcpy(CurrentPair->Pair.Value, (char*)Buffer); - } - Buffer += length+1; - - PrevPair = CurrentPair; - } - StringData->LanguageSets[0].LastPair = PrevPair; - } return 1; - - case -3: { - unsigned i, TotalPairCount; - - TotalPairCount = read_uint16le(Buffer); - Buffer += 2; - if(TotalPairCount == 0) - return 1; - - for(i=0; iPair.LanguageSet = read_uint8le(Buffer) - 1; - Buffer++; - - /* Key */ - length = strlen((char*)Buffer); - if(length != 0){ - Pair->Pair.Key = malloc(length+1); - strcpy(Pair->Pair.Key, (char*)Buffer); - } - Buffer += length+1; - - /* Value */ - length = strlen((char*)Buffer); - if(length != 0){ - Pair->Pair.Value = malloc(length+1); - strcpy(Pair->Pair.Value, (char*)Buffer); - } - Buffer += length+1; - - /* Add the pair to the end of the associated language set */ - Pair->PrevPair = StringData->LanguageSets[0].LastPair; - if(StringData->LanguageSets[0].PairCount == 0) - StringData->LanguageSets[0].FirstPair = Pair; - else - StringData->LanguageSets[0].LastPair->NextPair = Pair; - StringData->LanguageSets[0].PairCount++; - StringData->LanguageSets[0].LastPair = Pair; - } - } return 1; - - case -4: { - unsigned LanguageSet; - unsigned LanguageSetCount = read_uint8le(Buffer); - Buffer++; - if(LanguageSetCount > 20) LanguageSetCount = 20; - - for(LanguageSet=0; LanguageSetLanguageSets[LanguageSet].PairCount = read_uint16le(Buffer); - Buffer += 2; - if(StringData->LanguageSets[LanguageSet].PairCount == 0) - continue; - - for(i=0; iLanguageSets[LanguageSet].PairCount; i++){ - IFFStringPairNode * CurrentPair; - unsigned length; - CurrentPair = malloc(sizeof(IFFStringPairNode)); - memset(CurrentPair, 0, sizeof(IFFStringPairNode)); - - if(i == 0) StringData->LanguageSets[LanguageSet].FirstPair = CurrentPair; - else PrevPair->NextPair = CurrentPair; - CurrentPair->PrevPair = PrevPair; - - Buffer++; /* Skip over LanguageSet */ - - /* Key */ - length = read_uint8le(Buffer); - if(length > 127){ - length = (length & 127) | (read_uint8le(Buffer+1) << 7); - Buffer++; - } - if(length != 0){ - CurrentPair->Pair.Key = malloc(length+1); - memcpy(CurrentPair->Pair.Key, Buffer+1, length); - CurrentPair->Pair.Key[length] = 0x00; - } - Buffer += length + 1; - - /* Value */ - length = read_uint8le(Buffer); - if(length > 127){ - length = (length & 127) | (read_uint8le(Buffer+1) << 7); - Buffer++; - } - if(length != 0){ - CurrentPair->Pair.Value = malloc(length+1); - memcpy(CurrentPair->Pair.Value, Buffer+1, length); - CurrentPair->Pair.Value[length] = 0x00; - } - Buffer += length + 1; - - PrevPair = CurrentPair; - } - StringData->LanguageSets[LanguageSet].LastPair = PrevPair; - } - } return 1; - - } - return 0; + else if (!strcmp(ChunkInfo->Type, "BHAV")) + return iff_parse_bhav(ChunkInfo, (const char *)Buffer); + else + return 0; } int iff_parse_rsmp(IFFChunk * ChunkInfo, const uint8_t * Buffer, unsigned IFFSize){ diff --git a/Libraries/FileHandler/iff/iff.h b/Libraries/FileHandler/iff/iff.h index 67001f2..ed53bda 100644 --- a/Libraries/FileHandler/iff/iff.h +++ b/Libraries/FileHandler/iff/iff.h @@ -13,6 +13,8 @@ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "stbl.h" +#include "bhav.h" #ifndef read_uint32be #define read_int32be(x) (signed)(((x)[0]<<(8*3)) | ((x)[1]<<(8*2)) | ((x)[2]<<(8*1)) | ((x)[3]<<(8*0))) @@ -71,59 +73,6 @@ static const uint8_t Header_IFF[] = "IFF FILE 2.5:TYPE FOLLOWED BY SIZE\0 JAMIE ** IFF chunk structs */ -/* STR# chunk */ - -enum IFFLanguage { - IFFLANG_DEFAULT = 0, - IFFLANG_EN_US = 1, - IFFLANG_EN_INTERNATIONAL = 2, - IFFLANG_FRENCH = 3, - IFFLANG_GERMAN = 4, - IFFLANG_ITALIAN = 5, - IFFLANG_SPANISH = 6, - IFFLANG_DUTCH = 7, - IFFLANG_DANISH = 8, - IFFLANG_SWEDISH = 9, - IFFLANG_NORWEGIAN = 10, - IFFLANG_FINNISH = 11, - IFFLANG_HEBREW = 12, - IFFLANG_RUSSIAN = 13, - IFFLANG_PORTUGUESE = 14, - IFFLANG_JAPANESE = 15, - IFFLANG_POLISH = 16, - IFFLANG_CHINESE_SIMPLIFIED = 17, - IFFLANG_CHINESE_TRADITIONAL = 18, - IFFLANG_THAI = 19, - IFFLANG_KOREAN = 20 -}; - -typedef struct IFFStringPair_struct -{ - uint8_t LanguageSet; - char * Key; - char * Value; -} IFFStringPair; - -typedef struct IFFStringPairNode_struct -{ - IFFStringPair Pair; - struct IFFStringPairNode_struct * PrevPair; - struct IFFStringPairNode_struct * NextPair; -} IFFStringPairNode; - -typedef struct IFFLanguageSet_struct -{ - uint16_t PairCount; - IFFStringPairNode * FirstPair; - IFFStringPairNode * LastPair; -} IFFLanguageSet; - -typedef struct IFF_STR_struct -{ - int16_t Format; - IFFLanguageSet LanguageSets[20]; -} IFF_STR; - #ifdef __cplusplus extern "C" { #endif @@ -150,6 +99,7 @@ void iff_delete(IFFFile * IFFFileInfo); int iff_parse_rsmp(IFFChunk * ChunkInfo, const uint8_t * Buffer, unsigned IFFSize); int iff_parse_chunk(IFFChunk * ChunkInfo, const uint8_t * Buffer); int iff_parse_str(IFFChunk * ChunkInfo, const uint8_t * Buffer); +int iff_parse_bhav(IFFChunk * ChunkInfo, const uint8_t * Buffer); #ifdef __cplusplus } diff --git a/Tools/iff2html/iff2html.c b/Tools/iff2html/iff2html.c index 05b8180..8906db3 100644 --- a/Tools/iff2html/iff2html.c +++ b/Tools/iff2html/iff2html.c @@ -272,7 +272,7 @@ int main(int argc, char *argv[]){ fprintf(hFile, "\n"); for(i=1, ChunkNode = IFFFileInfo->FirstChunk; ChunkNode; ChunkNode = ChunkNode->NextChunk, i++){ - IFF_STR * StringData = (IFF_STR*) ChunkNode->Chunk.FormattedData; + fprintf(hFile, "

%u [%s] (%.4X)%s%s (Jump)

\n", i, ChunkNode->Chunk.ChunkID, i, ChunkNode->Chunk.Type, ChunkNode->Chunk.ChunkID, (ChunkNode->Chunk.Label[0] != 0x00) ? " – " : "", ChunkNode->Chunk.Label, @@ -286,6 +286,8 @@ int main(int argc, char *argv[]){ !strcmp(ChunkNode->Chunk.Type, "FAMs") || !strcmp(ChunkNode->Chunk.Type, "TTAs") ){ + IFF_STR * StringData = (IFF_STR*) ChunkNode->Chunk.FormattedData; + /**** ** STR# parsing */ @@ -350,6 +352,72 @@ int main(int argc, char *argv[]){ fprintf(hFile, "\n"); } } + else if (!strcmp(ChunkNode->Chunk.Type, "BHAV") ) + { + IFF_TREETABLE * TreeTableData = (IFF_TREETABLE*) ChunkNode->Chunk.FormattedData; + + fprintf(hFile, "\n"); + fprintf(hFile, "\n"); + + fprintf(hFile, "\n"); + + fprintf(hFile, "\n"); + + fprintf(hFile, "\n"); + + fprintf(hFile, "\n"); + + fprintf(hFile, "\n"); + + fprintf(hFile, "
Stream Version:"); + switch(TreeTableData->StreamVersion){ + case 0x8000: fprintf(hFile, "0x8000 (0)"); break; + case 0x8001: fprintf(hFile, "0x8001 (1)"); break; + case 0x8002: fprintf(hFile, "0x8002 (2)"); break; + case 0x8003: fprintf(hFile, "0x8003 (3)"); break; + default: fprintf(hFile, "Unrecognized"); break; + } + fprintf(hFile, "
Tree Version:"); + fprintf(hFile, "%-#10X (%u)", TreeTableData->TreeVersion, TreeTableData->TreeVersion); + fprintf(hFile, "
Tree Type:"); + fprintf(hFile, "%-#4X (%u)", TreeTableData->Type, TreeTableData->Type); + fprintf(hFile, "
Number of Parameters:"); + fprintf(hFile, "%u", TreeTableData->NumParams); + fprintf(hFile, "
Number of Local Variables:"); + fprintf(hFile, "%u", TreeTableData->NumLocals); + fprintf(hFile, "
Number of Tree Nodes:"); + fprintf(hFile, "%u", (TreeTableData->NodesEnd - TreeTableData->NodesBegin)); + fprintf(hFile, "
\n"); + if(TreeTableData->StreamVersion >= 0x8000 && TreeTableData->StreamVersion <= 0x8003) + { + fprintf(hFile, "
\n"); + fprintf(hFile, "\n"); + fprintf(hFile, "\n"); + + IFF_TREETABLENODE *currentNode; + for (currentNode = TreeTableData->NodesBegin; currentNode != TreeTableData->NodesEnd; currentNode++) + { + fprintf(hFile, "\n", (currentNode-TreeTableData->NodesBegin)); + fprintf(hFile, "\n", currentNode->PrimitiveNumber, currentNode->PrimitiveNumber); + if (currentNode->TransitionTrue < 253) + fprintf(hFile, "\n", currentNode->TransitionTrue, currentNode->TransitionTrue); + else + fprintf(hFile, "\n", currentNode->TransitionTrue == 253 ? "error" : currentNode->TransitionTrue == 254 ? "true" : "false"); + + + if (currentNode->TransitionFalse < 253) + fprintf(hFile, "\n", currentNode->TransitionFalse, currentNode->TransitionFalse); + else + fprintf(hFile, "\n", currentNode->TransitionFalse == 253 ? "error" : currentNode->TransitionFalse == 254 ? "true" : "false"); + fprintf(hFile, "\n", currentNode->Parameters.Param0, currentNode->Parameters.Param0); + fprintf(hFile, "\n", currentNode->Parameters.Param1, currentNode->Parameters.Param1); + fprintf(hFile, "\n", currentNode->Parameters.Param2, currentNode->Parameters.Param2); + fprintf(hFile, "\n", currentNode->Parameters.Param3, currentNode->Parameters.Param3); + } + + fprintf(hFile, "
Node IDPrimitive #Transition TrueTransition FalseParameter 0Parameter 1Parameter 2Parameter 3
%d%d (%-#6X)%d (%-#4X)%s%d (%-#4X)%s%d (%-#6X)%d (%-#6X)%d (%-#6X)%d (%-#6X)
\n"); + } + } fprintf(hFile, "\n\n"); }