mirror of
https://github.com/simtactics/mysimulation.git
synced 2025-03-15 14:51:21 +00:00
Added BHAV support to FileHandler and iff2html
Split "chunk.c" functionality into bhav.h, bhav.c, stbl.h, stbl.c
This commit is contained in:
parent
4442056335
commit
02dff475c8
5 changed files with 82 additions and 286 deletions
|
@ -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
|
||||
)
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
||||
|
|
|
@ -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; i<StringData->LanguageSets[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; i<StringData->LanguageSets[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; i<StringData->LanguageSets[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; i<TotalPairCount; i++){
|
||||
IFFStringPairNode * Pair;
|
||||
unsigned length;
|
||||
Pair = malloc(sizeof(IFFStringPairNode));
|
||||
memset(Pair, 0, sizeof(IFFStringPairNode));
|
||||
Pair->Pair.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; LanguageSet<LanguageSetCount; LanguageSet++){
|
||||
unsigned i;
|
||||
IFFStringPairNode * PrevPair = NULL;
|
||||
|
||||
StringData->LanguageSets[LanguageSet].PairCount = read_uint16le(Buffer);
|
||||
Buffer += 2;
|
||||
if(StringData->LanguageSets[LanguageSet].PairCount == 0)
|
||||
continue;
|
||||
|
||||
for(i=0; i<StringData->LanguageSets[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){
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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, "<h2 id=\"chunk%u_%.4x\">%u [%s] (%.4X)%s%s <a href=\"#chunk%u_%.4x\">(Jump)</a></h2>\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, "</table>\n");
|
||||
}
|
||||
}
|
||||
else if (!strcmp(ChunkNode->Chunk.Type, "BHAV") )
|
||||
{
|
||||
IFF_TREETABLE * TreeTableData = (IFF_TREETABLE*) ChunkNode->Chunk.FormattedData;
|
||||
|
||||
fprintf(hFile, "<table>\n");
|
||||
fprintf(hFile, "<tr><td>Stream Version:</td><td>");
|
||||
switch(TreeTableData->StreamVersion){
|
||||
case 0x8000: fprintf(hFile, "<tt>0x8000</tt> (0)"); break;
|
||||
case 0x8001: fprintf(hFile, "<tt>0x8001</tt> (1)"); break;
|
||||
case 0x8002: fprintf(hFile, "<tt>0x8002</tt> (2)"); break;
|
||||
case 0x8003: fprintf(hFile, "<tt>0x8003</tt> (3)"); break;
|
||||
default: fprintf(hFile, "Unrecognized"); break;
|
||||
}
|
||||
fprintf(hFile, "</td></tr>\n");
|
||||
|
||||
fprintf(hFile, "<tr><td>Tree Version:</td><td>");
|
||||
fprintf(hFile, "<tt>%-#10X</tt> (%u)", TreeTableData->TreeVersion, TreeTableData->TreeVersion);
|
||||
fprintf(hFile, "</td></tr>\n");
|
||||
|
||||
fprintf(hFile, "<tr><td>Tree Type:</td><td>");
|
||||
fprintf(hFile, "<tt>%-#4X</tt> (%u)", TreeTableData->Type, TreeTableData->Type);
|
||||
fprintf(hFile, "</td></tr>\n");
|
||||
|
||||
fprintf(hFile, "<tr><td>Number of Parameters:</td><td>");
|
||||
fprintf(hFile, "<tt>%u</tt>", TreeTableData->NumParams);
|
||||
fprintf(hFile, "</td></tr>\n");
|
||||
|
||||
fprintf(hFile, "<tr><td>Number of Local Variables:</td><td>");
|
||||
fprintf(hFile, "<tt>%u</tt>", TreeTableData->NumLocals);
|
||||
fprintf(hFile, "</td></tr>\n");
|
||||
|
||||
fprintf(hFile, "<tr><td>Number of Tree Nodes:</td><td>");
|
||||
fprintf(hFile, "<tt>%u</tt>", (TreeTableData->NodesEnd - TreeTableData->NodesBegin));
|
||||
fprintf(hFile, "</td></tr>\n");
|
||||
|
||||
fprintf(hFile, "</table>\n");
|
||||
if(TreeTableData->StreamVersion >= 0x8000 && TreeTableData->StreamVersion <= 0x8003)
|
||||
{
|
||||
fprintf(hFile, "<br />\n");
|
||||
fprintf(hFile, "<table class=\"center\">\n");
|
||||
fprintf(hFile, "<tr><th>Node ID</th><th>Primitive #</th><th>Transition True</th><th>Transition False</th><th>Parameter 0</th><th>Parameter 1</th><th>Parameter 2</th><th>Parameter 3</th></tr>\n");
|
||||
|
||||
IFF_TREETABLENODE *currentNode;
|
||||
for (currentNode = TreeTableData->NodesBegin; currentNode != TreeTableData->NodesEnd; currentNode++)
|
||||
{
|
||||
fprintf(hFile, "<tr><td>%d</td>\n", (currentNode-TreeTableData->NodesBegin));
|
||||
fprintf(hFile, "<td>%d (%-#6X)</td>\n", currentNode->PrimitiveNumber, currentNode->PrimitiveNumber);
|
||||
if (currentNode->TransitionTrue < 253)
|
||||
fprintf(hFile, "<td>%d (%-#4X)</td>\n", currentNode->TransitionTrue, currentNode->TransitionTrue);
|
||||
else
|
||||
fprintf(hFile, "<td>%s</td>\n", currentNode->TransitionTrue == 253 ? "error" : currentNode->TransitionTrue == 254 ? "true" : "false");
|
||||
|
||||
|
||||
if (currentNode->TransitionFalse < 253)
|
||||
fprintf(hFile, "<td>%d (%-#4X)</td>\n", currentNode->TransitionFalse, currentNode->TransitionFalse);
|
||||
else
|
||||
fprintf(hFile, "<td>%s</td>\n", currentNode->TransitionFalse == 253 ? "error" : currentNode->TransitionFalse == 254 ? "true" : "false");
|
||||
fprintf(hFile, "<td>%d (%-#6X)</td>\n", currentNode->Parameters.Param0, currentNode->Parameters.Param0);
|
||||
fprintf(hFile, "<td>%d (%-#6X)</td>\n", currentNode->Parameters.Param1, currentNode->Parameters.Param1);
|
||||
fprintf(hFile, "<td>%d (%-#6X)</td>\n", currentNode->Parameters.Param2, currentNode->Parameters.Param2);
|
||||
fprintf(hFile, "<td>%d (%-#6X)</td>\n", currentNode->Parameters.Param3, currentNode->Parameters.Param3);
|
||||
}
|
||||
|
||||
fprintf(hFile, "</table>\n");
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(hFile, "</div>\n\n");
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue