mirror of
https://github.com/simtactics/niotso.git
synced 2025-03-15 08:11:22 +00:00
Added FCNS, GLOB, TMPL, and rsmp parsers to the iff library
This commit is contained in:
parent
bc51bb4aad
commit
783227a630
15 changed files with 484 additions and 74 deletions
|
@ -43,4 +43,4 @@ set_target_properties(FileHandler_shared PROPERTIES
|
|||
PREFIX ""
|
||||
IMPORT_PREFIX ""
|
||||
CLEAN_DIRECT_OUTPUT 1)
|
||||
target_link_libraries(FileHandler_shared kernel32 iff_static jpegturbo_static libmpg123_static libpng_static zlib_static)
|
||||
target_link_libraries(FileHandler_shared kernel32 far_static iff_static jpegturbo_static libmpg123_static libpng_static zlib_static)
|
|
@ -1,42 +0,0 @@
|
|||
# macros --------------------------------------------------------------------
|
||||
CC = gcc
|
||||
LD = gcc
|
||||
CFLAGS = -m32 -Wall -Wextra -Wabi -Os -march=i686 -fomit-frame-pointer -ffast-math -funsafe-loop-optimizations -fmerge-all-constants -g0 -fno-exceptions
|
||||
LDFLAGS = -m32 -s -fwhole-program
|
||||
|
||||
AR = ar rcs
|
||||
WINDRES = windres -F pe-i386
|
||||
|
||||
LIBRARY_OBJS = obj/libfar.o obj/qfsdecompress.o
|
||||
RESOURCE_OBJ = obj/resource.o
|
||||
FAREXTRACT_OBJ = obj/farextract.o
|
||||
|
||||
# These will rebuild the entire library upon edit.
|
||||
DEPS = Makefile \
|
||||
config.h \
|
||||
include/libfar.h
|
||||
|
||||
# dependencies --------------------------------------------------------------
|
||||
all: libfar.a libfar-10.dll farextract.exe
|
||||
|
||||
$(LIBRARY_OBJS): $(DEPS)
|
||||
|
||||
libfar.a: $(LIBRARY_OBJS)
|
||||
$(AR) $@ $(LIBRARY_OBJS)
|
||||
|
||||
libfar-10.dll: $(LIBRARY_OBJS) $(RESOURCE_OBJ)
|
||||
$(CC) $(LDFLAGS) -shared -o $@ $(LIBRARY_OBJS) $(RESOURCE_OBJ)
|
||||
|
||||
farextract.exe: libfar.a $(FAREXTRACT_OBJ)
|
||||
$(CC) $(LDFLAGS) -o $@ $(FAREXTRACT_OBJ) libfar.a
|
||||
|
||||
# make rules ----------------------------------------------------------------
|
||||
obj/%.o: %.c
|
||||
$(CC) -c -ansi -pedantic $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/%.o: %.rc
|
||||
$(WINDRES) -i $< -o $@
|
||||
|
||||
# maintenance ---------------------------------------------------------------
|
||||
clean:
|
||||
del /Q /S obj libfar.a libfar-10.dll farextract.exe
|
|
@ -106,29 +106,21 @@ int far_identify(const uint8_t * Buffer, unsigned FileSize)
|
|||
|
||||
FARFile * far_create_archive(int Type)
|
||||
{
|
||||
FARFile *ptr = malloc(sizeof(FARFile));
|
||||
FARFile *ptr = calloc(1, sizeof(FARFile));
|
||||
if(ptr == NULL) return NULL;
|
||||
|
||||
memset(ptr, 0, sizeof(FARFile));
|
||||
ptr->Type = Type;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
PersistFile * far_create_persist()
|
||||
{
|
||||
PersistFile *ptr = malloc(sizeof(PersistFile));
|
||||
if(ptr == NULL) return NULL;
|
||||
|
||||
memset(ptr, 0, sizeof(PersistFile));
|
||||
return ptr;
|
||||
return calloc(1, sizeof(PersistFile));
|
||||
}
|
||||
|
||||
FAREntryNode * far_add_entry(FARFile * FARFileInfo, int Position)
|
||||
{
|
||||
FAREntryNode *ptr = malloc(sizeof(FAREntryNode)), *node;
|
||||
FAREntryNode *ptr = calloc(1, sizeof(FAREntryNode)), *node;
|
||||
if(ptr == NULL) return NULL;
|
||||
memset(ptr, 0, sizeof(FAREntryNode));
|
||||
if(FARFileInfo == NULL) return ptr;
|
||||
|
||||
if(Position >= 0){
|
||||
|
|
|
@ -5,9 +5,12 @@ set(IFF_SOURCES
|
|||
cats.c
|
||||
iff.c
|
||||
bcon.c
|
||||
fcns.c
|
||||
glob.c
|
||||
rsmp.c
|
||||
str.c
|
||||
string.c
|
||||
tmpl.c
|
||||
trcn.c
|
||||
)
|
||||
|
||||
|
|
|
@ -26,12 +26,11 @@ int iff_parse_bcon(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
|||
|
||||
if(Size < 2)
|
||||
return 0;
|
||||
ChunkInfo->FormattedData = malloc(sizeof(IFF_BCON));
|
||||
ChunkInfo->FormattedData = calloc(1, sizeof(IFF_BCON));
|
||||
if(ChunkInfo->FormattedData == NULL)
|
||||
return 0;
|
||||
|
||||
BCONData = (IFF_BCON*) ChunkInfo->FormattedData;
|
||||
BCONData->Constants = NULL;
|
||||
BCONData->ConstantCount = read_uint8le(Buffer);
|
||||
BCONData->Flags = read_uint8le(Buffer + 1);
|
||||
if(BCONData->ConstantCount == 0)
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
fcns.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "iff.h"
|
||||
|
||||
int iff_parse_fcns(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
||||
IFFConstantList *List;
|
||||
unsigned Size = ChunkInfo->Size - 76;
|
||||
unsigned i;
|
||||
|
||||
if(Size < 16)
|
||||
return 0;
|
||||
ChunkInfo->FormattedData = calloc(1, sizeof(IFFConstantList));
|
||||
if(ChunkInfo->FormattedData == NULL)
|
||||
return 0;
|
||||
|
||||
List = ChunkInfo->FormattedData;
|
||||
List->Reserved = read_uint32le(Buffer);
|
||||
List->Version = read_uint32le(Buffer+4);
|
||||
memcpy(List->MagicNumber, Buffer+8, 4);
|
||||
List->MagicNumber[4] = 0x00;
|
||||
List->ConstantCount = read_uint32le(Buffer+12);
|
||||
if(List->Reserved != 0 || List->Version == 0 || List->Version > 2)
|
||||
return 0;
|
||||
|
||||
List->Constants = calloc(List->ConstantCount, sizeof(IFFConstant));
|
||||
if(List->Constants == NULL)
|
||||
return 0;
|
||||
|
||||
Buffer += 16; Size -= 16;
|
||||
for(i=0; i<List->ConstantCount; i++){
|
||||
IFFConstant * Constant = &List->Constants[i];
|
||||
unsigned s;
|
||||
for(s=0; s<2; s++){
|
||||
char ** string = (s==0) ? &Constant->Name : &Constant->Description;
|
||||
unsigned length;
|
||||
if(Size == 0) return 0;
|
||||
|
||||
if(List->Version < 2){
|
||||
/* C string */
|
||||
for(length=0; length != Size && Buffer[length]; length++);
|
||||
if(length == Size) return 0;
|
||||
|
||||
if(length != 0){
|
||||
*string = malloc(length+1);
|
||||
if(*string == NULL) return 0;
|
||||
strcpy(*string, (char*) Buffer);
|
||||
}
|
||||
|
||||
Buffer += length+1;
|
||||
Size -= length+1;
|
||||
|
||||
/* Skip past the 0xA3 character;
|
||||
** see global.iff chunk 546 for why you can't do modulo-2 to detect this */
|
||||
if(Size && *Buffer == 0xA3){
|
||||
Buffer++; Size--;
|
||||
}
|
||||
}else{
|
||||
/* Pascal string */
|
||||
length = read_uint8le(Buffer);
|
||||
Buffer++; Size--;
|
||||
if(length > 127){
|
||||
if(Size == 0) return 0;
|
||||
length = (length&127) | (read_uint8le(Buffer)<<7);
|
||||
Buffer++; Size--;
|
||||
}
|
||||
|
||||
if(length != 0){
|
||||
*string = malloc(length+1);
|
||||
if(*string == NULL) return 0;
|
||||
memcpy(*string, Buffer, length);
|
||||
(*string)[length] = 0x00;
|
||||
}
|
||||
|
||||
Buffer += length;
|
||||
Size -= length;
|
||||
}
|
||||
|
||||
if(s == 0){
|
||||
union { float f; uint32_t v; } value;
|
||||
if(Size < 4) return 0;
|
||||
value.v = read_uint32le(Buffer);
|
||||
Constant->Value = value.f;
|
||||
Buffer+=4; Size-=4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void iff_free_fcns(void * FormattedData){
|
||||
IFFConstantList * List = FormattedData;
|
||||
if(List->Constants){
|
||||
unsigned c;
|
||||
for(c=0; c<List->ConstantCount; c++){
|
||||
free(List->Constants[c].Name);
|
||||
free(List->Constants[c].Description);
|
||||
}
|
||||
free(List->Constants);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
glob.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "iff.h"
|
||||
|
||||
int iff_parse_glob(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
||||
char ** string = (char**) &ChunkInfo->FormattedData;
|
||||
unsigned Size = ChunkInfo->Size - 76;
|
||||
unsigned length;
|
||||
|
||||
if(Size == 0) return 0;
|
||||
|
||||
/* Try reading as a C string */
|
||||
for(length=0; length != Size && Buffer[length] && Buffer[length] != 0xA3; length++);
|
||||
|
||||
if(length != Size){
|
||||
if(length > 0){
|
||||
*string = malloc(length+1);
|
||||
if(*string == NULL) return 0;
|
||||
strcpy(*string, (char*) Buffer);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Try again as a Pascal string */
|
||||
length = Buffer[0];
|
||||
if(length >= Size) return 0;
|
||||
|
||||
if(length > 0){
|
||||
*string = malloc(length+1);
|
||||
if(*string == NULL) return 0;
|
||||
memcpy(*string, Buffer+1, length);
|
||||
(*string)[length] = 0x00;
|
||||
}
|
||||
return 1;
|
||||
}
|
|
@ -27,35 +27,49 @@
|
|||
int iff_parse_##x(IFFChunk *, const uint8_t *); \
|
||||
void iff_free_##x(void *)
|
||||
|
||||
int iff_parse_rsmp(IFFChunk * ChunkInfo, const uint8_t * Buffer, unsigned IFFSize);
|
||||
int iff_free_rsmp(void * FormattedData);
|
||||
iff_register(bcon);
|
||||
iff_register(str);
|
||||
iff_register(cats);
|
||||
iff_register(c_string);
|
||||
iff_register(glob);
|
||||
iff_register(fcns);
|
||||
iff_register(tmpl);
|
||||
iff_register(trcn);
|
||||
iff_register(rsmp);
|
||||
|
||||
/* The ordering of these chunk types must match throughout this block: */
|
||||
const char chunktypes[] =
|
||||
"STR#" "CTSS" "FAMs" "TTAs" "CST\0"
|
||||
"CATS"
|
||||
"FWAV"
|
||||
"GLOB"
|
||||
"BCON"
|
||||
"FCNS"
|
||||
"TMPL"
|
||||
"TRCN"
|
||||
"rsmp"
|
||||
;
|
||||
int (* const iff_parse_function[])(IFFChunk*, const uint8_t*) = {
|
||||
iff_parse_str, iff_parse_str, iff_parse_str, iff_parse_str, iff_parse_str,
|
||||
iff_parse_cats,
|
||||
iff_parse_c_string,
|
||||
iff_parse_glob,
|
||||
iff_parse_bcon,
|
||||
iff_parse_trcn
|
||||
iff_parse_fcns,
|
||||
iff_parse_tmpl,
|
||||
iff_parse_trcn,
|
||||
iff_parse_rsmp
|
||||
};
|
||||
void (* const iff_free_function[])(void*) = {
|
||||
iff_free_str, iff_free_str, iff_free_str, iff_free_str, iff_free_str,
|
||||
iff_free_cats,
|
||||
NULL,
|
||||
NULL,
|
||||
iff_free_bcon,
|
||||
iff_free_trcn
|
||||
iff_free_fcns,
|
||||
iff_free_tmpl,
|
||||
iff_free_trcn,
|
||||
iff_free_rsmp
|
||||
};
|
||||
/* End */
|
||||
|
||||
|
|
|
@ -80,6 +80,24 @@ typedef struct IFF_BCON_s
|
|||
uint16_t * Constants;
|
||||
} IFF_BCON;
|
||||
|
||||
/* FCNS chunk */
|
||||
|
||||
typedef struct IFFConstant_s
|
||||
{
|
||||
char * Name;
|
||||
float Value;
|
||||
char * Description;
|
||||
} IFFConstant;
|
||||
|
||||
typedef struct IFFConstantList_s
|
||||
{
|
||||
uint32_t Reserved;
|
||||
uint32_t Version;
|
||||
char MagicNumber[5];
|
||||
uint32_t ConstantCount;
|
||||
IFFConstant * Constants;
|
||||
} IFFConstantList;
|
||||
|
||||
/* STR# chunk */
|
||||
|
||||
enum IFFLanguage {
|
||||
|
@ -125,6 +143,20 @@ typedef struct IFF_STR_s
|
|||
IFFLanguageSet LanguageSets[20];
|
||||
} IFFString;
|
||||
|
||||
/* TMPL chunk */
|
||||
|
||||
typedef struct IFFTemplateField_s
|
||||
{
|
||||
char * Name;
|
||||
char Type[5];
|
||||
} IFFTemplateField;
|
||||
|
||||
typedef struct IFFTemplate_s
|
||||
{
|
||||
uint32_t FieldCount;
|
||||
IFFTemplateField * Fields;
|
||||
} IFFTemplate;
|
||||
|
||||
/* TRCN chunk */
|
||||
|
||||
typedef struct IFFRangeEntry_s
|
||||
|
@ -147,6 +179,33 @@ typedef struct IFFRangeSet_s
|
|||
IFFRangeEntry * Ranges;
|
||||
} IFFRangeSet;
|
||||
|
||||
/* rsmp chunk */
|
||||
|
||||
typedef struct IFFResource_s
|
||||
{
|
||||
uint32_t Offset;
|
||||
uint32_t ChunkID;
|
||||
uint16_t Flags;
|
||||
char * Label;
|
||||
} IFFResource;
|
||||
|
||||
typedef struct IFFResouceType_s
|
||||
{
|
||||
char Type[5];
|
||||
uint32_t ResourceCount;
|
||||
IFFResource * Resources;
|
||||
} IFFResourceType;
|
||||
|
||||
typedef struct IFFResourceMap_s
|
||||
{
|
||||
uint32_t Reserved;
|
||||
uint32_t Version;
|
||||
char MagicNumber[5];
|
||||
uint32_t IFFSize;
|
||||
uint32_t TypeCount;
|
||||
IFFResourceType * ResourceTypes;
|
||||
} IFFResourceMap;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
|
|
@ -18,9 +18,108 @@
|
|||
|
||||
#include "iff.h"
|
||||
|
||||
int iff_parse_rsmp(IFFChunk * ChunkInfo, const uint8_t * Buffer, unsigned IFFSize){
|
||||
return 0;
|
||||
int iff_parse_rsmp(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
||||
IFFResourceMap *Map;
|
||||
unsigned Size = ChunkInfo->Size - 76;
|
||||
unsigned i;
|
||||
|
||||
if(Size < 20)
|
||||
return 0;
|
||||
ChunkInfo->FormattedData = calloc(1, sizeof(IFFResourceMap));
|
||||
if(ChunkInfo->FormattedData == NULL)
|
||||
return 0;
|
||||
|
||||
Map = ChunkInfo->FormattedData;
|
||||
Map->Reserved = read_uint32le(Buffer);
|
||||
Map->Version = read_uint32le(Buffer+4);
|
||||
memcpy(Map->MagicNumber, Buffer+8, 4);
|
||||
Map->MagicNumber[4] = 0x00;
|
||||
Map->IFFSize = read_uint32le(Buffer+12);
|
||||
Map->TypeCount = read_uint32le(Buffer+16);
|
||||
if(Map->Reserved != 0 || Map->Version > 1)
|
||||
return 0;
|
||||
|
||||
Map->ResourceTypes = calloc(Map->TypeCount, sizeof(IFFResourceType));
|
||||
if(Map->ResourceTypes == NULL)
|
||||
return 0;
|
||||
|
||||
Buffer += 20; Size -= 20;
|
||||
for(i=0; i<Map->TypeCount; i++){
|
||||
IFFResourceType * Type = &Map->ResourceTypes[i];
|
||||
unsigned j;
|
||||
if(Size < 8) return 0;
|
||||
memcpy(Type->Type, Buffer, 4);
|
||||
Type->Type[4] = 0x00;
|
||||
Type->ResourceCount = read_uint32le(Buffer+4);
|
||||
Type->Resources = calloc(Type->ResourceCount, sizeof(IFFResource));
|
||||
if(Type->Resources == NULL)
|
||||
return 0;
|
||||
|
||||
Buffer += 8; Size -= 8;
|
||||
for(j=0; j<Type->ResourceCount; j++){
|
||||
IFFResource * Resource = &Type->Resources[j];
|
||||
unsigned length;
|
||||
if(Size < ((Map->Version == 0) ? 9 : 11)) return 0;
|
||||
Resource->Offset = read_uint32le(Buffer);
|
||||
Buffer += 4;
|
||||
if(Map->Version == 0){
|
||||
Resource->ChunkID = read_uint16le(Buffer);
|
||||
Buffer += 2; Size -= 2;
|
||||
}else{
|
||||
Resource->ChunkID = read_uint32le(Buffer);
|
||||
Buffer += 4; Size -= 4;
|
||||
}
|
||||
Resource->Flags = read_uint16le(Buffer);
|
||||
Buffer += 2;
|
||||
Size -= 4+2;
|
||||
|
||||
if(Map->Version == 0){
|
||||
/* C string */
|
||||
for(length=0; length != Size && Buffer[length]; length++);
|
||||
if(length == Size) return 0;
|
||||
|
||||
if(length != 0){
|
||||
Resource->Label = malloc(length+1);
|
||||
if(Resource->Label == NULL) return 0;
|
||||
strcpy(Resource->Label, (char*) Buffer);
|
||||
|
||||
Buffer += length;
|
||||
Size -= length;
|
||||
}
|
||||
Buffer++; Size--;
|
||||
}else{
|
||||
/* Pascal string */
|
||||
length = read_uint8le(Buffer);
|
||||
Buffer++; Size--;
|
||||
|
||||
if(length != 0){
|
||||
Resource->Label = malloc(length+1);
|
||||
if(Resource->Label == NULL) return 0;
|
||||
memcpy(Resource->Label, Buffer, length);
|
||||
Resource->Label[length] = 0x00;
|
||||
}
|
||||
|
||||
Buffer += length;
|
||||
Size -= length;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void iff_free_rsmp(void * FormattedData){
|
||||
IFFResourceMap * Map = FormattedData;
|
||||
if(Map->ResourceTypes){
|
||||
unsigned t;
|
||||
for(t=0; t<Map->TypeCount; t++){
|
||||
IFFResourceType * Type = &Map->ResourceTypes[t];
|
||||
if(Type->Resources){
|
||||
unsigned r;
|
||||
for(r=0; r<Type->ResourceCount; r++)
|
||||
free(Type->Resources[r].Label);
|
||||
free(Type->Resources);
|
||||
}
|
||||
}
|
||||
free(Map->ResourceTypes);
|
||||
}
|
||||
}
|
|
@ -23,9 +23,6 @@ int iff_parse_c_string(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
|||
unsigned Size = ChunkInfo->Size - 76;
|
||||
unsigned length;
|
||||
|
||||
if(Size == 0)
|
||||
return 0;
|
||||
|
||||
for(length=0; length != Size && Buffer[length]; length++);
|
||||
if(length == Size) return 0;
|
||||
|
||||
|
|
72
Libraries/FileHandler/iff/tmpl.c
Normal file
72
Libraries/FileHandler/iff/tmpl.c
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
tmpl.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "iff.h"
|
||||
|
||||
int iff_parse_tmpl(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
||||
IFFTemplate *Template;
|
||||
unsigned Size = ChunkInfo->Size - 76;
|
||||
unsigned FieldCount;
|
||||
unsigned i;
|
||||
const uint8_t * TempBuffer = Buffer;
|
||||
if(Size == 0) return 1;
|
||||
|
||||
/* Walk through a first-pass to find the total field count */
|
||||
for(FieldCount=0; Size; FieldCount++){
|
||||
unsigned length = *TempBuffer;
|
||||
|
||||
if(Size < 5 || length > Size-5)
|
||||
return 0;
|
||||
TempBuffer += length+5; Size -= length+5;
|
||||
}
|
||||
|
||||
ChunkInfo->FormattedData = malloc(sizeof(IFFTemplate));
|
||||
if(ChunkInfo->FormattedData == NULL)
|
||||
return 0;
|
||||
|
||||
Template = (IFFTemplate*) ChunkInfo->FormattedData;
|
||||
Template->FieldCount = FieldCount;
|
||||
Template->Fields = calloc(FieldCount, sizeof(IFFTemplateField));
|
||||
if(Template->Fields == NULL)
|
||||
return 0;
|
||||
|
||||
for(i=0; i<FieldCount; i++){
|
||||
IFFTemplateField * Field = &Template->Fields[i];
|
||||
unsigned length = *Buffer;
|
||||
Field->Name = malloc(length+1);
|
||||
if(Field->Name == NULL) return 0;
|
||||
memcpy(Field->Name, Buffer+1, length);
|
||||
Field->Name[length] = 0x00;
|
||||
Buffer += length+1;
|
||||
|
||||
memcpy(Field->Type, Buffer, 4);
|
||||
Buffer += 4;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void iff_free_tmpl(void * FormattedData){
|
||||
IFFTemplate * Template = FormattedData;
|
||||
if(Template->Fields){
|
||||
unsigned f;
|
||||
for(f=0; f<Template->FieldCount; f++)
|
||||
free(Template->Fields[f].Name);
|
||||
free(Template->Fields);
|
||||
}
|
||||
}
|
|
@ -26,7 +26,7 @@ int iff_parse_trcn(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
|||
|
||||
if(Size < 16)
|
||||
return 0;
|
||||
ChunkInfo->FormattedData = malloc(sizeof(IFFRangeSet));
|
||||
ChunkInfo->FormattedData = calloc(1, sizeof(IFFRangeSet));
|
||||
if(ChunkInfo->FormattedData == NULL)
|
||||
return 0;
|
||||
|
||||
|
@ -37,7 +37,7 @@ int iff_parse_trcn(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
|||
memcpy(RangeSet->MagicNumber, Buffer+8, 4);
|
||||
RangeSet->MagicNumber[4] = 0x00;
|
||||
RangeSet->RangeCount = read_uint32le(Buffer+12);
|
||||
if(RangeSet->Version > 2)
|
||||
if(RangeSet->Reserved != 0 || RangeSet->Version > 2)
|
||||
return 0;
|
||||
if(RangeSet->RangeCount == 0)
|
||||
return 1;
|
||||
|
@ -85,6 +85,11 @@ int iff_parse_trcn(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
|||
/* Pascal string */
|
||||
length = read_uint8le(Buffer);
|
||||
Buffer++; Size--;
|
||||
if(length > 127){
|
||||
if(Size == 0) return 0;
|
||||
length = (length&127) | (read_uint8le(Buffer)<<7);
|
||||
Buffer++; Size--;
|
||||
}
|
||||
|
||||
if(length != 0){
|
||||
*string = malloc(length+1);
|
||||
|
|
|
@ -113,7 +113,7 @@ static const int16_t XATable[] =
|
|||
int xa_decode(const uint8_t *__restrict InBuffer, uint8_t *__restrict OutBuffer, unsigned Frames, unsigned Channels)
|
||||
{
|
||||
channel_t Channel[8];
|
||||
memset(Channel, 0x00, sizeof(Channel));
|
||||
memset(Channel, 0, sizeof(Channel));
|
||||
if(Frames == 0) return 1;
|
||||
|
||||
while(1){
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#define max(x,y) ((x) > (y) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
void printsize(FILE * hFile, size_t FileSize){
|
||||
static void printsize(FILE * hFile, size_t FileSize){
|
||||
/* For our purposes, our units are best described in kB and MB, if not bytes */
|
||||
size_t temp = FileSize;
|
||||
unsigned position = 1;
|
||||
|
@ -237,6 +237,7 @@ int main(int argc, char *argv[]){
|
|||
fprintf(hFile, "th, td {\n");
|
||||
fprintf(hFile, " border: 1px #aaa solid;\n");
|
||||
fprintf(hFile, " padding: 0.2em;\n");
|
||||
fprintf(hFile, " white-space: pre-wrap;\n");
|
||||
fprintf(hFile, "}\n");
|
||||
fprintf(hFile, "\n");
|
||||
fprintf(hFile, ".center {\n");
|
||||
|
@ -352,7 +353,7 @@ int main(int argc, char *argv[]){
|
|||
}
|
||||
}else if(!strcmp(ChunkData->Type, "CATS")){
|
||||
/****
|
||||
** CATS parsing
|
||||
** Regular string pair
|
||||
*/
|
||||
|
||||
IFFStringPair * Pair = ChunkData->FormattedData;
|
||||
|
@ -363,7 +364,7 @@ int main(int argc, char *argv[]){
|
|||
(Pair->Key) != NULL ? Pair->Key : "",
|
||||
(Pair->Value) != NULL ? Pair->Value : "");
|
||||
fprintf(hFile, "</table>\n");
|
||||
}else if(!strcmp(ChunkData->Type, "FWAV")){
|
||||
}else if(!strcmp(ChunkData->Type, "FWAV") || !strcmp(ChunkData->Type, "GLOB")){
|
||||
/****
|
||||
** Regular string
|
||||
*/
|
||||
|
@ -379,7 +380,7 @@ int main(int argc, char *argv[]){
|
|||
|
||||
IFF_BCON * BCONData = ChunkData->FormattedData;
|
||||
fprintf(hFile, "<table>\n");
|
||||
fprintf(hFile, "<tr><td>Flags:</td><td><tt>%02X</tt> (%d)</td></tr>\n", BCONData->Flags, BCONData->Flags);
|
||||
fprintf(hFile, "<tr><td>Flags:</td><td><tt>%02X</tt> (%u)</td></tr>\n", BCONData->Flags, BCONData->Flags);
|
||||
fprintf(hFile, "</table>\n");
|
||||
if(BCONData->ConstantCount > 0){
|
||||
unsigned i;
|
||||
|
@ -391,6 +392,46 @@ int main(int argc, char *argv[]){
|
|||
fprintf(hFile, "<tr><td>%u</td><td>%u</td></tr>\n", i+1, BCONData->Constants[i]);
|
||||
fprintf(hFile, "</table>\n");
|
||||
}
|
||||
}else if(!strcmp(ChunkData->Type, "FCNS")){
|
||||
/****
|
||||
** FCNS parsing
|
||||
*/
|
||||
|
||||
IFFConstantList * List = ChunkData->FormattedData;
|
||||
fprintf(hFile, "<table>\n");
|
||||
fprintf(hFile, "<tr><td>Version:</td><td>%u</td></tr>\n", List->Version);
|
||||
fprintf(hFile, "</table>\n");
|
||||
if(List->ConstantCount > 0){
|
||||
IFFConstant * Constant;
|
||||
unsigned i;
|
||||
|
||||
fprintf(hFile, "<br />\n");
|
||||
fprintf(hFile, "<table class=\"center\">\n");
|
||||
fprintf(hFile, "<tr><th colspan=\"2\">Name</th><th>Value</th><th>Description</th></tr>\n");
|
||||
for(i=0, Constant=List->Constants; i<List->ConstantCount; i++, Constant++)
|
||||
fprintf(hFile, "<tr><td>%u</td><td>%s</td><td>%g</td><td>%s</td></tr>\n",
|
||||
i+1,
|
||||
Constant->Name ? Constant->Name : "",
|
||||
Constant->Value,
|
||||
Constant->Description ? Constant->Description : "");
|
||||
fprintf(hFile, "</table>\n");
|
||||
}
|
||||
}else if(!strcmp(ChunkData->Type, "TMPL")){
|
||||
/****
|
||||
** TMPL parsing
|
||||
*/
|
||||
|
||||
IFFTemplate * Template = ChunkData->FormattedData;
|
||||
IFFTemplateField * Field;
|
||||
unsigned i;
|
||||
fprintf(hFile, "<table class=\"center\">\n");
|
||||
fprintf(hFile, "<tr><th colspan=\"2\">Name</th><th>Type</th>\n");
|
||||
for(i=0, Field=Template->Fields; i<Template->FieldCount; i++, Field++)
|
||||
fprintf(hFile, "<tr><td>%u</td><td>%s</td><td>%s</td></tr>\n",
|
||||
i+1,
|
||||
Field->Name ? Field->Name : "",
|
||||
Field->Type ? Field->Type : "");
|
||||
fprintf(hFile, "</table>\n");
|
||||
}else if(!strcmp(ChunkData->Type, "TRCN")){
|
||||
/****
|
||||
** TRCN parsing
|
||||
|
@ -406,10 +447,11 @@ int main(int argc, char *argv[]){
|
|||
|
||||
fprintf(hFile, "<br />\n");
|
||||
fprintf(hFile, "<table class=\"center\">\n");
|
||||
fprintf(hFile, "<tr><th>Used yet</th><th>Default value</th><th>Name</th>"
|
||||
fprintf(hFile, "<tr><th colspan=\"2\">Used yet</th><th>Default value</th><th>Name</th>"
|
||||
"<th>Comment</th><th>Range is enforced</th><th>Minimum</th><th>Maximum</th></tr>\n");
|
||||
for(i=0, Range=RangeSet->Ranges; i<RangeSet->RangeCount; i++, Range++)
|
||||
fprintf(hFile, "<tr><td>%s</td><td>%u</td><td>%s</td><td>%s</td><td>%s</td><td>%u</td><td>%u</td></tr>\n",
|
||||
fprintf(hFile, "<tr><td>%u</td><td>%s</td><td>%u</td><td>%s</td><td>%s</td><td>%s</td><td>%u</td><td>%u</td></tr>\n",
|
||||
i+1,
|
||||
Range->IsUnused ? "No" : "Yes", Range->DefaultValue,
|
||||
Range->Name ? Range->Name : "",
|
||||
Range->Comment ? Range->Comment : "",
|
||||
|
@ -417,6 +459,8 @@ int main(int argc, char *argv[]){
|
|||
Range->RangeMin, Range->RangeMax);
|
||||
fprintf(hFile, "</table>\n");
|
||||
}
|
||||
}else{
|
||||
fprintf(hFile, "The contents of this chunk cannot be shown on this page.\n");
|
||||
}
|
||||
|
||||
fprintf(hFile, "</div>\n\n");
|
||||
|
|
Loading…
Add table
Reference in a new issue