diff --git a/Libraries/FileHandler/CMakeLists.txt b/Libraries/FileHandler/CMakeLists.txt index e4b532b..ef35be8 100644 --- a/Libraries/FileHandler/CMakeLists.txt +++ b/Libraries/FileHandler/CMakeLists.txt @@ -17,6 +17,8 @@ set(FILEHANDLER_MINOR 0) set(FILEHANDLER_SOURCES File.cpp Image.cpp + iff/chunks.c + iff/iff.c ) include_directories(${CMAKE_SOURCE_DIR}/Libraries/FileHandler) diff --git a/Libraries/FileHandler/iff/CMakeLists.txt b/Libraries/FileHandler/iff/CMakeLists.txt index 356c4fa..47c4fca 100644 --- a/Libraries/FileHandler/iff/CMakeLists.txt +++ b/Libraries/FileHandler/iff/CMakeLists.txt @@ -4,7 +4,6 @@ project(iff) set(IFF_SOURCES chunks.c iff.c - iffexport.c ) -add_executable(iffexport ${IFF_SOURCES}) \ No newline at end of file +add_executable(iffexport iffexport.c ${IFF_SOURCES}) \ No newline at end of file diff --git a/Libraries/FileHandler/iff/chunks.c b/Libraries/FileHandler/iff/chunks.c index 36f80e5..254b8e2 100644 --- a/Libraries/FileHandler/iff/chunks.c +++ b/Libraries/FileHandler/iff/chunks.c @@ -19,6 +19,239 @@ #include #include "iff.h" -int iff_read_rsmp(IFFChunk * ChunkInfo, const uint8_t * Buffer, unsigned MaxChunkSize, unsigned IFFSize){ +int iff_parse_chunk(IFFChunk * ChunkInfo, const uint8_t * Buffer){ + if(!strcmp(ChunkInfo->Type, "STR#")) + 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 - 64; + if(Size < 4) + 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; + + 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; +} + +int iff_parse_rsmp(IFFChunk * ChunkInfo, const uint8_t * Buffer, unsigned IFFSize){ return 1; } \ No newline at end of file diff --git a/Libraries/FileHandler/iff/iff.h b/Libraries/FileHandler/iff/iff.h index 2b630f9..67001f2 100644 --- a/Libraries/FileHandler/iff/iff.h +++ b/Libraries/FileHandler/iff/iff.h @@ -15,6 +15,14 @@ */ #ifndef read_uint32be + #define read_int32be(x) (signed)(((x)[0]<<(8*3)) | ((x)[1]<<(8*2)) | ((x)[2]<<(8*1)) | ((x)[3]<<(8*0))) + #define read_int24be(x) (signed)(((x)[0]<<(8*2)) | ((x)[1]<<(8*1)) | ((x)[2]<<(8*0))) + #define read_int16be(x) (signed)(((x)[0]<<(8*1)) | ((x)[1]<<(8*0))) + #define read_int8be(x) (signed)(((x)[0]<<(8*0))) + #define read_int32le(x) (signed)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1)) | ((x)[2]<<(8*2)) | ((x)[3]<<(8*3))) + #define read_int24le(x) (signed)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1)) | ((x)[2]<<(8*2))) + #define read_int16le(x) (signed)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1))) + #define read_int8le(x) (signed)(((x)[0]<<(8*0))) #define read_uint32be(x) (unsigned)(((x)[0]<<(8*3)) | ((x)[1]<<(8*2)) | ((x)[2]<<(8*1)) | ((x)[3]<<(8*0))) #define read_uint24be(x) (unsigned)(((x)[0]<<(8*2)) | ((x)[1]<<(8*1)) | ((x)[2]<<(8*0))) #define read_uint16be(x) (unsigned)(((x)[0]<<(8*1)) | ((x)[1]<<(8*0))) @@ -25,6 +33,10 @@ #define read_uint8le(x) (unsigned)(((x)[0]<<(8*0))) #endif +/* +** IFF file headers +*/ + typedef struct IFFChunk_struct { char Type[5]; @@ -55,6 +67,63 @@ typedef struct IFFFile_struct static const uint8_t Header_IFF[] = "IFF FILE 2.5:TYPE FOLLOWED BY SIZE\0 JAMIE DOORNBOS & MAXIS 1"; +/* +** 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 @@ -78,7 +147,9 @@ void iff_delete(IFFFile * IFFFileInfo); ** IFF chunk functions */ -int iff_read_rsmp(IFFChunk * ChunkInfo, const uint8_t * Buffer, unsigned MaxChunkSize, unsigned IFFSize); +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); #ifdef __cplusplus } diff --git a/Libraries/libvitaboy/Renderer.cpp b/Libraries/libvitaboy/Renderer.cpp index 644b33a..2dcfc1e 100644 --- a/Libraries/libvitaboy/Renderer.cpp +++ b/Libraries/libvitaboy/Renderer.cpp @@ -288,8 +288,7 @@ void AdvanceFrame(Skeleton_t& Skeleton, Animation_t& Animation, float TimeDelta) { float Duration = (float)Animation.Motions[0].FrameCount/30; AnimationTime += TimeDelta; - while(AnimationTime >= Duration) AnimationTime -= Duration; - if(AnimationTime<0) AnimationTime = 0; //Safe-guard against rounding error + AnimationTime = fmodf(AnimationTime, Duration); //Loop the animation for(unsigned i=0; i + + 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 +#include + +int main(){ + HMODULE dllmodule = LoadLibrary("TSOSimulatorClientD.dll"); + if(dllmodule == NULL){ + printf("TSOSimulatorClient: Error: Failed to load DLL \"TSOSimulatorClientD.dll\"."); + return -1; + } + + void * (__stdcall *GZDllGetGZCOMDirector)(void) = (void * (__stdcall *)(void)) GetProcAddress(dllmodule, "GZDllGetGZCOMDirector"); + if(GZDllGetGZCOMDirector == NULL){ + printf("TSOSimulatorClient: Error: Failed to find GZDllGetGZCOMDirector() in TSOSimulatorClientD.dll."); + return -1; + } + + printf("TSOSimulatorClient: Calling GZDllGetGZCOMDirector() ...\n"); + void * value = GZDllGetGZCOMDirector(); + printf("TSOSimulatorClient: Finished calling GZDllGetGZCOMDirector().\nThe value returned was: %p.\n", value); + + printf("TSOSimulatorClient: Exiting.\n"); + FreeLibrary(dllmodule); + return 0; +} \ No newline at end of file diff --git a/Tools/TSOSimulatorClient/TSOSimulatorClient.hpp b/Tools/TSOSimulatorClient/TSOSimulatorClient.hpp new file mode 100644 index 0000000..2d46b8a --- /dev/null +++ b/Tools/TSOSimulatorClient/TSOSimulatorClient.hpp @@ -0,0 +1,116 @@ +/* + TSOSimulatorClient.hpp - Copyright (c) 2012 Fatbag + + 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 + +DECLARE_INTERFACE(IMMDeviceCollection); +DECLARE_INTERFACE(IMMNotificationClient); +DECLARE_INTERFACE(IPropertyStore); + +/* +** IMMDevice +*/ + +DECLARE_INTERFACE_(IMMDevice, IUnknown) +{ + STDMETHOD(Activate) (REFIID iid, DWORD dwClsCtx, PROPVARIANT *pActivationParams, void **ppInterface); + STDMETHOD(OpenPropertyStore) (DWORD stgmAccess, IPropertyStore **ppProperties); + STDMETHOD(GetId) (LPWSTR *ppstrId); + STDMETHOD(GetState) (DWORD *pdwState); +}; + +/* +** IMMDeviceEnumerator +*/ + +enum EDataFlow +{ + eRender, + eCapture, + eAll +}; + +enum ERole +{ + eConsole, + eMultimedia, + eCommunications +}; + +DECLARE_INTERFACE_(IMMDeviceEnumerator, IUnknown) +{ + STDMETHOD(EnumAudioEndpoints) (EDataFlow dataFlow, DWORD dwStateMask, IMMDeviceCollection **ppDevices); + STDMETHOD(GetDefaultAudioEndpoint) (EDataFlow dataFlow, ERole role, IMMDevice **ppEndpoint); + STDMETHOD(GetDevice) (LPCWSTR pwstrId, IMMDevice **ppDevice); + STDMETHOD(RegisterEndpointNotificationCallback) (IMMNotificationClient *pClient); + STDMETHOD(UnregisterEndpointNotificationCallback) (IMMNotificationClient *pClient); +}; + +/* +** IAudioClient +*/ + +enum AUDCLNT_SHAREMODE +{ + AUDCLNT_SHAREMODE_SHARED, + AUDCLNT_SHAREMODE_EXCLUSIVE +}; + +enum AUDCLNT_STREAMFLAGS +{ + AUDCLNT_STREAMFLAGS_CROSSPROCESS = 0x00010000, + AUDCLNT_STREAMFLAGS_LOOPBACK = 0x00020000, + AUDCLNT_STREAMFLAGS_EVENTCALLBACK = 0x00040000, + AUDCLNT_STREAMFLAGS_NOPERSIST = 0x00080000, + AUDCLNT_STREAMFLAGS_RATEADJUST = 0x00100000, + AUDCLNT_SESSIONFLAGS_EXPIREWHENUNOWNED = 0x10000000, + AUDCLNT_SESSIONFLAGS_DISPLAY_HIDE = 0x20000000, + AUDCLNT_SESSIONFLAGS_DISPLAY_HIDEWHENEXPIRED = 0x40000000 +}; + +DECLARE_INTERFACE_(IAudioClient, IUnknown) +{ + STDMETHOD(Initialize) (AUDCLNT_SHAREMODE ShareMode, DWORD StreamFlags, LONGLONG hnsBufferDuration, + LONGLONG hnsPeriodicity, const WAVEFORMATEX *pFormat, LPCGUID AudioSessionGuid); + STDMETHOD(GetBufferSize) (UINT32 *pNumBufferFrames); + STDMETHOD(GetStreamLatency) (LONGLONG *phnsLatency); + STDMETHOD(GetCurrentPadding) (UINT32 *pNumPaddingFrames); + STDMETHOD(IsFormatSupported) (AUDCLNT_SHAREMODE ShareMode, const WAVEFORMATEX *pFormat, WAVEFORMATEX **ppClosestMatch); + STDMETHOD(GetMixFormat) (WAVEFORMATEX **ppDeviceFormat); + STDMETHOD(GetDevicePeriod) (LONGLONG *phnsDefaultDevicePeriod, LONGLONG *phnsMinimumDevicePeriod); + STDMETHOD(Start) (void); + STDMETHOD(Stop) (void); + STDMETHOD(Reset) (void); + STDMETHOD(SetEventHandle) (HANDLE eventHandle); + STDMETHOD(GetService) (REFIID riid, void **ppv); +}; + +/* +** IAudioRenderClient +*/ + +enum AUDCLNT_BUFFERFLAGS +{ + AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY = 0x1, + AUDCLNT_BUFFERFLAGS_SILENT = 0x2, + AUDCLNT_BUFFERFLAGS_TIMESTAMP_ERROR = 0x4 +}; + +DECLARE_INTERFACE_(IAudioRenderClient, IUnknown) +{ + STDMETHOD(GetBuffer) (UINT32 NumFramesRequested, BYTE **ppData); + STDMETHOD(ReleaseBuffer) (UINT32 NumFramesWritten, DWORD dwFlags); +}; \ No newline at end of file diff --git a/Tools/TSOSimulatorClient/compile.bat b/Tools/TSOSimulatorClient/compile.bat new file mode 100644 index 0000000..0561632 --- /dev/null +++ b/Tools/TSOSimulatorClient/compile.bat @@ -0,0 +1 @@ +gcc -Wall -Wextra -Wabi -pedantic -m32 -o TSOSimulatorClient.exe TSOSimulatorClient.cpp -mconsole \ No newline at end of file diff --git a/Tools/TSOSimulatorClient/memory map.txt b/Tools/TSOSimulatorClient/memory map.txt new file mode 100644 index 0000000..e0725af --- /dev/null +++ b/Tools/TSOSimulatorClient/memory map.txt @@ -0,0 +1,106 @@ +CPU Dump +Address Hex dump +10102AF8 C4 61 0D 10|94 61 0D 10|00 00 00 00|00 00 00 00| 0 +10102B08 08 7A 0D 10|F8 30 3D 00|F8 30 3D 00|00 31 3D 00| 4 +10102B18 00 00 00 00|00 00 00 00|00 00 00 00|70 3B 3D 00| 8 +10102B28 7C 3B 3D 00|80 3B 3D 00|10 10 10 00|E0 32 3D 00| 12 +10102B38 E4 35 3D 00|E4 35 3D 00|00 00 00 00|01 00 00 00| 16 +10102B48 A4 62 0D 10|78 62 0D 10|00 00 00 00|00 00 00 00| 20 +10102B58 08 7A 0D 10|10 31 3D 00|10 31 3D 00|18 31 3D 00| 24 +10102B68 00 00 00 00|00 00 00 00|00 00 00 00|00 00 00 00| 28 +10102B78 00 00 00 00|00 00 00 00|10 10 10 00|58 3C 3D 00| 32 +10102B88 5C 3F 3D 00|5C 3F 3D 00|0D 00 00 00|01 00 00 00| 36 +10102B98 00 00 00 00|00 00 00 00|08 7A 0D 10|08 09 3D 00| 40 +10102BA8 1D 09 3D 00|1E 09 3D 00|00 00 00 00|00 00 00 00| 44 +10102BB8 00 00 00 00|18 31 3D 00|80 3B 3D 00|88 0A 3D 00| 48 +10102BC8 A8 2D 3D 00|00 00 00 00|00 00 00 00|00 00 00 00| 52 +10102BD8 00 00 00 00|00 00 00 00|00 00 00 00|00 00 00 00| 56 +10102BE8 00 00 00 00|00 00 00 00|00 00 00 00|00 00 00 00| 60 +10102BF8 00 00 00 00|00 00 00 00|00 00 00 00|00 00 00 00| 64 +10102C08 10 0C 00 00|B0 3B 3D 00|40 3C 3D 00|00 00 00 00| 68 + +Offset: Meaning +0: Pointer to v-table 2 - 100D61C4 +1: Pointer to v-table 1 - 100D6194 + +2: 0 +3: 0 +4: Pointer to v-table 5 - 100D7A08 +5: Pointer +6: Pointer +7: Pointer +8: 0 +9: 0 +10: 0 +11: Pointer +12: Pointer +13: Pointer +14: Flags? - 0x00101010 +15: Pointer +16: Pointer +17: Pointer +18: 0 +19: 1 + +20: Pointer to v-table 4 - 100D62A4 +21: Pointer to v-table 3 - 100D6278 + +22: 0 +23: 0 +24: Pointer to v-table 5 - 100D7A08 +25: Pointer +26: Pointer +27: Pointer +28: 0 +29: 0 +30: 0 +31: 0 +32: 0 +33: 0 +34: Flags? - 0x00101010 +35: Pointer +36: Pointer +37: Pointer +38: 13 +39: 1 + +40: 0 +41: 0 +42: Pointer to v-table 5 - 100D7A08 +43: Pointer +44: Pointer +45: Pointer +46: 0 +47: 0 +48: 0 +49: Pointer +50: Pointer +51: Pointer +52: Pointer +53: 0 +54: 0 +55: 0 +56: 0 +57: 0 + +58: 0 +59: 0 +60: 0 +61: 0 +62: 0 +63: 0 +64: 0 +65: 0 +66: 0 +67: 0 +68: 3088 +69: Pointer +70: Pointer +71: 0 + +5 v-tables: +100D6194 (12 entries) +100D61C4 (17 entries) +100D6278 (11 entries) +100D62A4 (344 entries) +100D7A08 (695 entries) \ No newline at end of file diff --git a/Tools/iff2html/CMakeLists.txt b/Tools/iff2html/CMakeLists.txt index e69de29..3fedd07 100644 --- a/Tools/iff2html/CMakeLists.txt +++ b/Tools/iff2html/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 2.6) +project(iff2html) + +set(IFF2HTML_SOURCES + iff2html.c +) + +include_directories(${CMAKE_SOURCE_DIR}/Libraries/FileHandler) + +add_executable(iff2html ${IFF2HTML_SOURCES}) +target_link_libraries(iff2html FileHandler_shared) \ No newline at end of file diff --git a/Tools/iff2html/iff2html.c b/Tools/iff2html/iff2html.c index a5091d9..6c47bdc 100644 --- a/Tools/iff2html/iff2html.c +++ b/Tools/iff2html/iff2html.c @@ -17,24 +17,31 @@ #include #include #include -#include "iff.h" +#include + +#ifndef min + #define min(x,y) ((x) < (y) ? (x) : (y)) +#endif +#ifndef max + #define max(x,y) ((x) > (y) ? (x) : (y)) +#endif int main(int argc, char *argv[]){ - HANDLE hFile; + unsigned i; + FILE * hFile; int overwrite = 0; - char *InFile, *OutDirectory; - HANDLE ProcessHeap = GetProcessHeap(); + char *InFile, *OutFile = NULL; DWORD FileSize; - DWORD bytestransferred = 0; uint8_t * IFFData; - unsigned chunkcount, chunk = 0; + unsigned chunk = 0; IFFFile * IFFFileInfo; IFFChunkNode * ChunkNode; if(argc == 1 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")){ - printf("Usage: iff2html [-f] infile outfile\n" + printf("Usage: iff2html [-f] infile (outfile)\n" "Produce an HTML webpage describing an EA IFF file.\n" "Use -f to force overwriting without confirmation.\n" + "If outfile is unspecified, file.iff will output to file.html.\n" "\n" "Report bugs to .\n" "iff2html is maintained by the Niotso project.\n" @@ -45,10 +52,21 @@ int main(int argc, char *argv[]){ if(argc >= 4 && !strcmp(argv[1], "-f")){ overwrite++; InFile = argv[2]; - OutDirectory = argv[3]; - }else{ - InFile = argv[1]; - OutDirectory = argv[2]; + OutFile = argv[3]; + }else if(argc == 3){ + if(!strcmp(argv[1], "-f")){ + overwrite++; + InFile = argv[2]; + }else{ + InFile = argv[1]; + OutFile = argv[2]; + } + }else InFile = argv[1]; + if(OutFile == NULL){ + unsigned length = strlen(InFile); + OutFile = malloc(max(length+2, 6)); + strcpy(OutFile, InFile); + strcpy(max(OutFile+length-4, OutFile), ".html"); } /**** @@ -56,29 +74,29 @@ int main(int argc, char *argv[]){ */ hFile = CreateFile(InFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); - if(hFile == INVALID_HANDLE_VALUE){ - if(GetLastError() == ERROR_FILE_NOT_FOUND){ - printf("%sThe specified input file does not exist.", "iff2html: error: "); - return -1; - } - printf("%sThe input file could not be opened for reading.", "iff2html: error: "); + hFile = fopen(InFile, "rb"); + if(hFile == NULL){ + printf("%sThe specified input file does not exist or could not be opened for reading.", "iff2html: error: "); return -1; } - FileSize = GetFileSize(hFile, NULL); + fseek(hFile, 0, SEEK_END); + FileSize = ftell(hFile); if(FileSize < 64){ printf("%sNot a valid IFF file.", "iff2html: error: "); return -1; } - IFFData = HeapAlloc(ProcessHeap, HEAP_NO_SERIALIZE, FileSize); + fseek(hFile, 0, SEEK_SET); + + IFFData = malloc(FileSize); if(IFFData == NULL){ printf("%sMemory for this file could not be allocated.", "iff2html: error: "); return -1; } - if(!ReadFile(hFile, IFFData, FileSize, &bytestransferred, NULL) || bytestransferred != FileSize){ + if(!fread(IFFData, FileSize, 1, hFile)){ printf("%sThe input file could not be read.", "iff2html: error: "); return -1; } - CloseHandle(hFile); + fclose(hFile); /**** ** Load header information @@ -103,7 +121,200 @@ int main(int argc, char *argv[]){ return -1; } - chunkcount = IFFFileInfo->ChunkCount; + for(chunk = 1, ChunkNode = IFFFileInfo->FirstChunk; ChunkNode; ChunkNode = ChunkNode->NextChunk, chunk++){ + printf("Chunk %u:\n", chunk); + iff_parse_chunk(&ChunkNode->Chunk, ChunkNode->Chunk.Data); + } + /**** + ** Open the output file and write the header + */ + if(!overwrite){ + hFile = fopen(OutFile, "rb"); + if(hFile != NULL){ + /* File exists */ + char c; + fclose(hFile); + printf("File \"%s\" exists.\nContinue anyway? (y/n) ", OutFile); + c = getchar(); + if(c != 'y' && c != 'Y'){ + printf("\nAborted."); + return -1; + } + } + } + hFile = fopen(OutFile, "wb"); + if(hFile == NULL){ + printf("%sThe output file could not be opened for writing.", "iff2html: error: "); + return -1; + } + + /**** + ** We're splitting fprintf by line to guarantee compatibility; + ** even C99 compilers are only required to support 4096 byte strings in printf()-related functions + */ + fprintf(hFile, "\n"); + fprintf(hFile, "\n"); + fprintf(hFile, "\n"); + fprintf(hFile, "\n"); + fprintf(hFile, "\n"); + fprintf(hFile, "\n"); + fprintf(hFile, "\n", InFile); + fprintf(hFile, "\n"); + fprintf(hFile, "%s (iff2html)\n", InFile); + fprintf(hFile, "\n"); + fprintf(hFile, "\n"); + fprintf(hFile, "\n"); + fprintf(hFile, "

%s

\n", InFile); + fprintf(hFile, "\n"); + fprintf(hFile, "
Contents – %u chunks
\n", IFFFileInfo->ChunkCount); + fprintf(hFile, "
    \n"); + for(i=1, ChunkNode = IFFFileInfo->FirstChunk; ChunkNode; ChunkNode = ChunkNode->NextChunk, i++) + fprintf(hFile, "
  • %u [%s] (%.4X)%s%s
  • \n", + i, ChunkNode->Chunk.ChunkID, i, ChunkNode->Chunk.Type, ChunkNode->Chunk.ChunkID, + (ChunkNode->Chunk.Label[0] != 0x00) ? " – " : "", ChunkNode->Chunk.Label); + fprintf(hFile, "
\n"); + fprintf(hFile, "
\n"); + 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, + i, ChunkNode->Chunk.ChunkID); + fprintf(hFile, "
\n"); + + if(ChunkNode->Chunk.FormattedData == NULL){ + fprintf(hFile, "The contents of this chunk could not be parsed.\n"); + }else if(!strcmp(ChunkNode->Chunk.Type, "STR#")){ + /**** + ** STR# parsing + */ + fprintf(hFile, "\n"); + fprintf(hFile, "\n"); + fprintf(hFile, "
Format:"); + switch(StringData->Format){ + case 0: fprintf(hFile, "00 00 (0)"); break; + case -1: fprintf(hFile, "FF FF (−1)"); break; + case -2: fprintf(hFile, "FE FF (−2)"); break; + case -3: fprintf(hFile, "FD FF (−3)"); break; + case -4: fprintf(hFile, "FC FF (−4)"); break; + default: fprintf(hFile, "Unrecognized"); break; + } + fprintf(hFile, "
\n"); + if(StringData->Format >= -4 && StringData->Format <= 0){ + unsigned LanguageSet; + const char * LanguageStrings[] = { + "English (US)", + "English (International)", + "French", + "German", + "Italian", + "Spanish", + "Dutch", + "Danish", + "Swedish", + "Norwegian", + "Finnish", + "Hebrew", + "Russian", + "Portuguese", + "Japanese", + "Polish", + "Simplified Chinese", + "Traditional Chinese", + "Thai", + "Korean" + }; + fprintf(hFile, "
\n"); + fprintf(hFile, "\n"); + fprintf(hFile, "\n"); + + for(LanguageSet=0; LanguageSet<20; LanguageSet++){ + IFFStringPairNode * PairNode; + unsigned PairIndex; + if(StringData->LanguageSets[LanguageSet].PairCount == 0) + continue; + + fprintf(hFile, "\n", StringData->LanguageSets[LanguageSet].PairCount, + LanguageStrings[LanguageSet]); + for(PairIndex=1, PairNode = StringData->LanguageSets[LanguageSet].FirstPair; PairNode; + PairNode = PairNode->NextPair, PairIndex++) + fprintf(hFile, "\n", PairIndex, + (PairNode->Pair.Key) != NULL ? PairNode->Pair.Key : "", + (PairNode->Pair.Value) != NULL ? PairNode->Pair.Value : ""); + } + + fprintf(hFile, "
LanguageString pairs
%s%u%s%s
\n"); + } + } + + fprintf(hFile, "
\n\n"); + } + + fprintf(hFile, "
This page was generated by the use of iff2html.\n"); + fprintf(hFile, "The content of this page may be subject to copyright by the author(s) of the original iff file.
\n"); + fprintf(hFile, "\n"); + fprintf(hFile, ""); + fclose(hFile); return 0; } \ No newline at end of file diff --git a/Tools/iff2html/iff2html.html b/Tools/iff2html/iff2html.html new file mode 100644 index 0000000..c083e4e --- /dev/null +++ b/Tools/iff2html/iff2html.html @@ -0,0 +1,125 @@ + + + + + + + + +behavior.iff (iff2html) + + + +

behavior.iff

+
+
9809b96803833f2891ddd31e474795a9 (md5), 42.4kB (43,446 bytes)
+
Dumped by iff2html.
+ + + +

1 [STR#] (00DD) – neighbor data labels (Jump)

+
+ + +
Format:FC FF (−4)

+ + + + + + + + + + + + + +
LanguageString pairs
English (US)1person instance id4
2belongs in house4
3person age4
4relationship raw score4
5relationship score4
6friend count4
7house number4
8has telephone4
9has baby4
10family friend count4
+
+ +

2 [STR#] (00EA) – build mode types (Jump)

+
+ + +
Format:FC FF (−4)

+ + + + + + + + + + + +
LanguageString pairs
English (US)1none4
2door4
3window4
4stair4
5plant4
6fireplace4
7column4
8pool equipment4
+
+ + + + \ No newline at end of file diff --git a/Tools/iff2html/output.html b/Tools/iff2html/output.html deleted file mode 100644 index 462fd5f..0000000 --- a/Tools/iff2html/output.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - -behavior.iff (iff2html) - - - -

behavior.iff

-
-
9809b96803833f2891ddd31e474795a9 (md5), 42.4kB (43,446 bytes)
-
Dumped by iff2html.
- -
Contents – x chunks
- -
- - \ No newline at end of file