From f0c6668423bb81c07af8a1ccdd03007494a1c7a8 Mon Sep 17 00:00:00 2001 From: PeachyPeach <72323920+PeachyPeachSM64@users.noreply.github.com> Date: Sat, 25 Jun 2022 09:52:53 +0200 Subject: [PATCH] DynOS Bin Compression (#131) --- Makefile | 3 + data/dynos.cpp.h | 248 ++++++++++++++++++++++---------- data/dynos_bin_actor.cpp | 27 +++- data/dynos_bin_ambient_t.cpp | 10 +- data/dynos_bin_animation.cpp | 40 +++--- data/dynos_bin_behavior.cpp | 40 +++--- data/dynos_bin_col.cpp | 32 +++-- data/dynos_bin_compress.cpp | 222 ++++++++++++++++++++++++++++ data/dynos_bin_geo.cpp | 14 +- data/dynos_bin_gfx.cpp | 20 +-- data/dynos_bin_legacy.cpp | 6 +- data/dynos_bin_light_t.cpp | 10 +- data/dynos_bin_lights.cpp | 10 +- data/dynos_bin_lvl.cpp | 41 ++++-- data/dynos_bin_macro_object.cpp | 14 +- data/dynos_bin_movtex.cpp | 14 +- data/dynos_bin_movtexqc.cpp | 16 +-- data/dynos_bin_pointer.cpp | 24 ++-- data/dynos_bin_rooms.cpp | 14 +- data/dynos_bin_tex.cpp | 50 +++---- data/dynos_bin_texlist.cpp | 12 +- data/dynos_bin_trajectory.cpp | 14 +- data/dynos_bin_vtx.cpp | 84 +++++------ data/dynos_file.cpp | 10 -- 24 files changed, 665 insertions(+), 310 deletions(-) create mode 100644 data/dynos_bin_compress.cpp delete mode 100644 data/dynos_file.cpp diff --git a/Makefile b/Makefile index 912048ac..330ecf08 100644 --- a/Makefile +++ b/Makefile @@ -938,6 +938,9 @@ endif # Coop specific libraries +# Zlib +LDFLAGS += -lz + # Lua ifeq ($(WINDOWS_BUILD),1) ifeq ($(TARGET_BITS), 32) diff --git a/data/dynos.cpp.h b/data/dynos.cpp.h index fda42893..e2135333 100644 --- a/data/dynos.cpp.h +++ b/data/dynos.cpp.h @@ -65,6 +65,129 @@ enum { DOPT_CHOICEPARAM, }; +// +// DynOS Binary file struct +// + +class BinFile { +private: + void Grow(s32 newSize) { + if (newSize >= mCapacity) { + mCapacity = MAX(newSize, MAX(256, mCapacity * 2)); + u8 *newBuffer = (u8 *) calloc(mCapacity, 1); + if (mData) { + memcpy(newBuffer, mData, mSize); + free(mData); + } + mData = newBuffer; + } + mSize = MAX(mSize, newSize); + } + +public: + inline s32 Size() const { return mSize; } + inline s32 Offset() const { return mOffset; } + inline bool EoF() const { return mOffset >= mSize; } + inline void SetOffset(s32 aOffset) const { mOffset = aOffset; } + +public: + static BinFile *OpenR(const char *aFilename) { + FILE *f = fopen(aFilename, "rb"); + if (f) { + fseek(f, 0, SEEK_END); + BinFile *_BinFile = (BinFile *) calloc(1, sizeof(BinFile)); + _BinFile->mFilename = (const char *) memcpy(calloc(strlen(aFilename) + 1, 1), aFilename, strlen(aFilename)); + _BinFile->mReadOnly = true; + _BinFile->Grow(ftell(f)); + rewind(f); + fread(_BinFile->mData, 1, _BinFile->mSize, f); + fclose(f); + return _BinFile; + } + return NULL; + } + + static BinFile *OpenW(const char *aFilename) { + BinFile *_BinFile = (BinFile *) calloc(1, sizeof(BinFile)); + _BinFile->mFilename = (const char *) memcpy(calloc(strlen(aFilename) + 1, 1), aFilename, strlen(aFilename)); + _BinFile->mReadOnly = false; + return _BinFile; + } + + static BinFile *OpenB(const u8 *aBuffer, s32 aSize) { + BinFile *_BinFile = (BinFile *) calloc(1, sizeof(BinFile)); + _BinFile->mReadOnly = true; + _BinFile->Grow(aSize); + memcpy(_BinFile->mData, aBuffer, aSize); + return _BinFile; + } + + static void Close(BinFile *&aBinFile) { + if (aBinFile) { + if (!aBinFile->mReadOnly && aBinFile->mFilename && aBinFile->mData && aBinFile->mSize) { + FILE *f = fopen(aBinFile->mFilename, "wb"); + if (f) { + fwrite(aBinFile->mData, 1, aBinFile->mSize, f); + fclose(f); + } + } + if (aBinFile->mFilename) free((void *) aBinFile->mFilename); + if (aBinFile->mData) free(aBinFile->mData); + free(aBinFile); + } + } + +public: + template + T Read() const { + T _Item = { 0 }; + if (mOffset + sizeof(T) <= mSize) { + memcpy(&_Item, mData + mOffset, sizeof(T)); + mOffset += sizeof(T); + } + return _Item; + } + + template + T *Read(T *aBuffer, s32 aCount) const { + if (mOffset + aCount * sizeof(T) <= mSize) { + memcpy(aBuffer, mData + mOffset, aCount * sizeof(T)); + mOffset += aCount * sizeof(T); + } + return aBuffer; + } + + template + void Write(const T& aItem) { + if (!mReadOnly) { + Grow(mOffset + sizeof(T)); + memcpy(mData + mOffset, &aItem, sizeof(T)); + mOffset += sizeof(T); + } + } + + template + void Write(const T *aBuffer, s32 aCount) { + if (!mReadOnly) { + Grow(mOffset + aCount * sizeof(T)); + memcpy(mData + mOffset, aBuffer, aCount * sizeof(T)); + mOffset += aCount * sizeof(T); + } + } + + void Skip(s32 aAmount) const { + mOffset += aAmount; + } + +private: + const char *mFilename; + u8 *mData; + s32 mSize; + s32 mCapacity; + mutable s32 mOffset; + bool mReadOnly; +}; + // // DynOS Array // A vector-like array, implemented to be processed really fast, but cannot handle C++ complex classes like std::string @@ -171,15 +294,15 @@ public: inline bool Empty() const { return mCount == 0; } public: - void Read(FILE *aFile) { - s32 _Length = 0; fread(&_Length, sizeof(s32), 1, aFile); + void Read(BinFile *aFile) { + s32 _Length = aFile->Read(); Resize(_Length); - fread(mBuffer, sizeof(T), _Length, aFile); + aFile->Read(mBuffer, _Length); } - void Write(FILE *aFile) const { - fwrite(&mCount, sizeof(s32), 1, aFile); - fwrite(mBuffer, sizeof(T), mCount, aFile); + void Write(BinFile *aFile) const { + aFile->Write(mCount); + aFile->Write(mBuffer, mCount); } private: @@ -193,7 +316,7 @@ private: // A fixed-size string that doesn't require heap memory allocation // -#define STRING_SIZE 256 +#define STRING_SIZE 255 class String { public: inline String() : mCount(0) { @@ -315,15 +438,15 @@ public: } public: - void Read(FILE *aFile) { - fread(&mCount, sizeof(u8), 1, aFile); - fread(mBuffer, sizeof(char), mCount, aFile); + void Read(BinFile *aFile) { + mCount = aFile->Read(); + aFile->Read(mBuffer, mCount); mBuffer[mCount] = 0; } - void Write(FILE *aFile) const { - fwrite(&mCount, sizeof(u8), 1, aFile); - fwrite(mBuffer, sizeof(char), mCount, aFile); + void Write(BinFile *aFile) const { + aFile->Write(mCount); + aFile->Write(mBuffer, mCount); } s32 ParseInt() const { @@ -520,7 +643,6 @@ struct DynosOption : NoCopy { }; typedef bool (*DynosLoopFunc)(DynosOption *, void *); - struct BuiltinTexInfo { const char* identifier; const void* pointer; @@ -589,28 +711,6 @@ T *CopyBytes(const T *aPtr, u64 aSize) { return _Ptr; } -template -T ReadBytes(FILE* aFile) { - T _Item = { 0 }; - - // If we're at end of file. Just return the default. - if (feof(aFile)) { return _Item; } - - size_t nread = fread(&_Item, sizeof(T), 1, aFile); - // If we failed to read bytes. Print the error. - //if (nread != sizeof(T)) { perror("The following error occured when reading bytes"); } - return _Item; -} - -template -void WriteBytes(FILE* aFile, const T& aItem) { - size_t nwrote = fwrite(&aItem, sizeof(T), 1, aFile); - // If we failed to write bytes. Print the error. - //if (nwrote != sizeof(T)) { perror("The following error occured when writing bytes"); } -} - -void SkipBytes(FILE *aFile, size_t amount); - template void PrintNoNewLine(const char *aFmt, Args... aArgs) { printf(aFmt, aArgs...); @@ -869,79 +969,79 @@ char *DynOS_Read_Buffer(FILE* aFile, GfxData* aGfxData); s64 DynOS_Misc_ParseInteger(const String& _Arg, bool* found); void DynOS_Anim_ScanFolder(GfxData *aGfxData, const SysPath &aAnimsFolder); -void DynOS_Anim_Table_Write(FILE* aFile, GfxData* aGfxData); -void DynOS_Anim_Write(FILE* aFile, GfxData* aGfxData); -void DynOS_Anim_Load(FILE *aFile, GfxData *aGfxData); -void DynOS_Anim_Table_Load(FILE *aFile, GfxData *aGfxData); +void DynOS_Anim_Table_Write(BinFile* aFile, GfxData* aGfxData); +void DynOS_Anim_Write(BinFile* aFile, GfxData* aGfxData); +void DynOS_Anim_Load(BinFile *aFile, GfxData *aGfxData); +void DynOS_Anim_Table_Load(BinFile *aFile, GfxData *aGfxData); DataNode* DynOS_Col_Parse(GfxData* aGfxData, DataNode* aNode, bool aDisplayPercent); -void DynOS_Col_Write(FILE* aFile, GfxData* aGfxData, DataNode *aNode); -DataNode* DynOS_Col_Load(FILE *aFile, GfxData *aGfxData); +void DynOS_Col_Write(BinFile* aFile, GfxData* aGfxData, DataNode *aNode); +DataNode* DynOS_Col_Load(BinFile *aFile, GfxData *aGfxData); DataNode* DynOS_Col_LoadFromBinary(const SysPath &aFilename, const char *aCollisionName); void DynOS_Col_Generate(const SysPath &aPackFolder, Array> _ActorsFolders, GfxData *_GfxData); DataNode* DynOS_Geo_Parse(GfxData* aGfxData, DataNode* aNode, bool aDisplayPercent); -void DynOS_Geo_Write(FILE *aFile, GfxData *aGfxData, DataNode *aNode); +void DynOS_Geo_Write(BinFile *aFile, GfxData *aGfxData, DataNode *aNode); DataNode** DynOS_Geo_GetLoading(void); -void DynOS_Geo_Load(FILE *aFile, GfxData *aGfxData); +void DynOS_Geo_Load(BinFile *aFile, GfxData *aGfxData); DataNode* DynOS_Gfx_Parse(GfxData* aGfxData, DataNode* aNode); -void DynOS_Gfx_Write(FILE *aFile, GfxData *aGfxData, DataNode *aNode); -void DynOS_Gfx_Load(FILE *aFile, GfxData *aGfxData); +void DynOS_Gfx_Write(BinFile *aFile, GfxData *aGfxData, DataNode *aNode); +void DynOS_Gfx_Load(BinFile *aFile, GfxData *aGfxData); s64 DynOS_Gfx_ParseGfxConstants(const String& _Arg, bool* found); DataNode* DynOS_Lights_Parse(GfxData* aGfxData, DataNode* aNode); -void DynOS_Lights_Write(FILE* aFile, GfxData* aGfxData, DataNode *aNode); -void DynOS_Lights_Load(FILE *aFile, GfxData *aGfxData); +void DynOS_Lights_Write(BinFile* aFile, GfxData* aGfxData, DataNode *aNode); +void DynOS_Lights_Load(BinFile *aFile, GfxData *aGfxData); DataNode* DynOS_LightT_Parse(GfxData* aGfxData, DataNode* aNode); -void DynOS_LightT_Write(FILE* aFile, GfxData* aGfxData, DataNode *aNode); -void DynOS_LightT_Load(FILE *aFile, GfxData *aGfxData); +void DynOS_LightT_Write(BinFile* aFile, GfxData* aGfxData, DataNode *aNode); +void DynOS_LightT_Load(BinFile *aFile, GfxData *aGfxData); DataNode* DynOS_AmbientT_Parse(GfxData* aGfxData, DataNode* aNode); -void DynOS_AmbientT_Write(FILE* aFile, GfxData* aGfxData, DataNode *aNode); -void DynOS_AmbientT_Load(FILE *aFile, GfxData *aGfxData); +void DynOS_AmbientT_Write(BinFile* aFile, GfxData* aGfxData, DataNode *aNode); +void DynOS_AmbientT_Load(BinFile *aFile, GfxData *aGfxData); DataNode* DynOS_MacroObject_Parse(GfxData* aGfxData, DataNode* aNode, bool aDisplayPercent); -void DynOS_MacroObject_Write(FILE* aFile, GfxData* aGfxData, DataNode *aNode); -DataNode* DynOS_MacroObject_Load(FILE *aFile, GfxData *aGfxData); +void DynOS_MacroObject_Write(BinFile* aFile, GfxData* aGfxData, DataNode *aNode); +DataNode* DynOS_MacroObject_Load(BinFile *aFile, GfxData *aGfxData); DataNode* DynOS_Trajectory_Parse(GfxData* aGfxData, DataNode* aNode, bool aDisplayPercent); -void DynOS_Trajectory_Write(FILE* aFile, GfxData* aGfxData, DataNode *aNode); -DataNode* DynOS_Trajectory_Load(FILE *aFile, GfxData *aGfxData); +void DynOS_Trajectory_Write(BinFile* aFile, GfxData* aGfxData, DataNode *aNode); +DataNode* DynOS_Trajectory_Load(BinFile *aFile, GfxData *aGfxData); DataNode* DynOS_Movtex_Parse(GfxData* aGfxData, DataNode* aNode, bool aDisplayPercent); -void DynOS_Movtex_Write(FILE* aFile, GfxData* aGfxData, DataNode *aNode); -DataNode* DynOS_Movtex_Load(FILE *aFile, GfxData *aGfxData); +void DynOS_Movtex_Write(BinFile* aFile, GfxData* aGfxData, DataNode *aNode); +DataNode* DynOS_Movtex_Load(BinFile *aFile, GfxData *aGfxData); DataNode* DynOS_MovtexQC_Parse(GfxData* aGfxData, DataNode* aNode); -void DynOS_MovtexQC_Write(FILE* aFile, GfxData* aGfxData, DataNode *aNode); -DataNode* DynOS_MovtexQC_Load(FILE *aFile, GfxData *aGfxData); +void DynOS_MovtexQC_Write(BinFile* aFile, GfxData* aGfxData, DataNode *aNode); +DataNode* DynOS_MovtexQC_Load(BinFile *aFile, GfxData *aGfxData); DataNode* DynOS_Rooms_Parse(GfxData* aGfxData, DataNode* aNode); -void DynOS_Rooms_Write(FILE* aFile, GfxData* aGfxData, DataNode *aNode); -DataNode* DynOS_Rooms_Load(FILE *aFile, GfxData *aGfxData); +void DynOS_Rooms_Write(BinFile* aFile, GfxData* aGfxData, DataNode *aNode); +DataNode* DynOS_Rooms_Load(BinFile *aFile, GfxData *aGfxData); DataNode* DynOS_Tex_Parse(GfxData* aGfxData, DataNode* aNode); -void DynOS_Tex_Write(FILE* aFile, GfxData* aGfxData, DataNode *aNode); -DataNode* DynOS_Tex_Load(FILE *aFile, GfxData *aGfxData); +void DynOS_Tex_Write(BinFile* aFile, GfxData* aGfxData, DataNode *aNode); +DataNode* DynOS_Tex_Load(BinFile *aFile, GfxData *aGfxData); DataNode* DynOS_Tex_LoadFromBinary(const SysPath &aPackFolder, const SysPath &aFilename, const char *aTexName, bool aAddToPack); void DynOS_Tex_ConvertTextureDataToPng(GfxData *aGfxData, TexData* aTexture); void DynOS_Tex_GeneratePack(const SysPath &aPackFolder, SysPath &aOutputFolder, bool aAllowCustomTextures); DataNode* DynOS_TexList_Parse(GfxData* aGfxData, DataNode* aNode); -void DynOS_TexList_Write(FILE* aFile, GfxData* aGfxData, DataNode *aNode); -DataNode* DynOS_TexList_Load(FILE *aFile, GfxData *aGfxData); +void DynOS_TexList_Write(BinFile* aFile, GfxData* aGfxData, DataNode *aNode); +DataNode* DynOS_TexList_Load(BinFile *aFile, GfxData *aGfxData); DataNode* DynOS_Vtx_Parse(GfxData* aGfxData, DataNode* aNode); -void DynOS_Vtx_Write(FILE* aFile, GfxData* aGfxData, DataNode *aNode); -void DynOS_Vtx_Load(FILE *aFile, GfxData *aGfxData); +void DynOS_Vtx_Write(BinFile* aFile, GfxData* aGfxData, DataNode *aNode); +void DynOS_Vtx_Load(BinFile *aFile, GfxData *aGfxData); -void DynOS_Pointer_Lua_Write(FILE* aFile, u32 index, GfxData* aGfxData); -void DynOS_Pointer_Write(FILE* aFile, const void* aPtr, GfxData* aGfxData); -void *DynOS_Pointer_Load(FILE *aFile, GfxData *aGfxData, u32 aValue, u8* outFlags); +void DynOS_Pointer_Lua_Write(BinFile* aFile, u32 index, GfxData* aGfxData); +void DynOS_Pointer_Write(BinFile* aFile, const void* aPtr, GfxData* aGfxData); +void *DynOS_Pointer_Load(BinFile *aFile, GfxData *aGfxData, u32 aValue, u8* outFlags); -void DynOS_GfxDynCmd_Load(FILE *aFile, GfxData *aGfxData); +void DynOS_GfxDynCmd_Load(BinFile *aFile, GfxData *aGfxData); GfxData *DynOS_Actor_LoadFromBinary(const SysPath &aPackFolder, const char *aActorName, const SysPath &aFilename, bool aAddToPack); void DynOS_Actor_GeneratePack(const SysPath &aPackFolder); @@ -960,5 +1060,9 @@ s64 DynOS_Bhv_ParseBehaviorIntegerScriptConstants(const String &_Arg, bool *foun s64 DynOS_Common_ParseBhvConstants(const String &_Arg, bool *found); s64 DynOS_Common_ParseModelConstants(const String &_Arg, bool *found); +bool DynOS_Bin_IsCompressed(const SysPath &aFilename); +bool DynOS_Bin_Compress(const SysPath &aFilename); +BinFile *DynOS_Bin_Decompress(const SysPath &aFilename); + #endif #endif diff --git a/data/dynos_bin_actor.cpp b/data/dynos_bin_actor.cpp index f5d80a18..f380f413 100644 --- a/data/dynos_bin_actor.cpp +++ b/data/dynos_bin_actor.cpp @@ -14,7 +14,7 @@ void ClearGfxDataNodes(DataNodes &aDataNodes) { ///////////// static bool DynOS_Actor_WriteBinary(const SysPath &aOutputFilename, GfxData *aGfxData) { - FILE *_File = fopen(aOutputFilename.c_str(), "wb"); + BinFile *_File = BinFile::OpenW(aOutputFilename.c_str()); if (!_File) { PrintError(" ERROR: Unable to create file \"%s\"", aOutputFilename.c_str()); return false; @@ -64,8 +64,8 @@ static bool DynOS_Actor_WriteBinary(const SysPath &aOutputFilename, GfxData *aGf } DynOS_Anim_Write(_File, aGfxData); DynOS_Anim_Table_Write(_File, aGfxData); - fclose(_File); - return true; + BinFile::Close(_File); + return DynOS_Bin_Compress(aOutputFilename); } ///////////// @@ -86,11 +86,11 @@ GfxData *DynOS_Actor_LoadFromBinary(const SysPath &aPackFolder, const char *aAct // Load data from binary file GfxData *_GfxData = NULL; - FILE *_File = fopen(aFilename.c_str(), "rb"); + BinFile *_File = DynOS_Bin_Decompress(aFilename); if (_File) { _GfxData = New(); for (bool _Done = false; !_Done;) { - switch (ReadBytes(_File)) { + switch (_File->Read()) { case DATA_TYPE_LIGHT: DynOS_Lights_Load (_File, _GfxData); break; case DATA_TYPE_LIGHT_T: DynOS_LightT_Load (_File, _GfxData); break; case DATA_TYPE_AMBIENT_T: DynOS_AmbientT_Load (_File, _GfxData); break; @@ -105,7 +105,7 @@ GfxData *DynOS_Actor_LoadFromBinary(const SysPath &aPackFolder, const char *aAct default: _Done = true; break; } } - fclose(_File); + BinFile::Close(_File); } // Add data to cache, even if not loaded @@ -143,6 +143,12 @@ static void DynOS_Actor_Generate(const SysPath &aPackFolder, Arrayd_name) == ".") continue; if (SysPath(_PackEnt->d_name) == "..") continue; +#ifdef DEVELOPMENT + // Compress .bin files to gain some space + SysPath _Filename = fstring("%s/%s", aPackFolder.c_str(), _PackEnt->d_name); + if (SysPath(_PackEnt->d_name).find(".bin") != SysPath::npos && !DynOS_Bin_IsCompressed(_Filename)) { + DynOS_Bin_Compress(_Filename); + continue; + } +#endif + // For each subfolder, read tokens from model.inc.c and geo.inc.c SysPath _Folder = fstring("%s/%s", aPackFolder.c_str(), _PackEnt->d_name); if (fs_sys_dir_exists(_Folder.c_str())) { diff --git a/data/dynos_bin_ambient_t.cpp b/data/dynos_bin_ambient_t.cpp index 327ba3cd..9bd3a2a2 100644 --- a/data/dynos_bin_ambient_t.cpp +++ b/data/dynos_bin_ambient_t.cpp @@ -33,22 +33,22 @@ DataNode* DynOS_AmbientT_Parse(GfxData* aGfxData, DataNode // Writing // ///////////// -void DynOS_AmbientT_Write(FILE* aFile, GfxData* aGfxData, DataNode *aNode) { +void DynOS_AmbientT_Write(BinFile* aFile, GfxData* aGfxData, DataNode *aNode) { if (!aNode->mData) return; // Header - WriteBytes(aFile, DATA_TYPE_AMBIENT_T); + aFile->Write(DATA_TYPE_AMBIENT_T); aNode->mName.Write(aFile); // Data - WriteBytes(aFile, *aNode->mData); + aFile->Write(*aNode->mData); } ///////////// // Reading // ///////////// -void DynOS_AmbientT_Load(FILE *aFile, GfxData *aGfxData) { +void DynOS_AmbientT_Load(BinFile *aFile, GfxData *aGfxData) { DataNode *_Node = New>(); // Name @@ -56,7 +56,7 @@ void DynOS_AmbientT_Load(FILE *aFile, GfxData *aGfxData) { // Data _Node->mData = New(); - *_Node->mData = ReadBytes(aFile); + *_Node->mData = aFile->Read(); // Append aGfxData->mAmbientTs.Add(_Node); diff --git a/data/dynos_bin_animation.cpp b/data/dynos_bin_animation.cpp index 1efe30b3..b78258cc 100644 --- a/data/dynos_bin_animation.cpp +++ b/data/dynos_bin_animation.cpp @@ -160,7 +160,7 @@ void DynOS_Anim_ScanFolder(GfxData *aGfxData, const SysPath &aAnimsFolder) { // Writing // ///////////// -void DynOS_Anim_Write(FILE* aFile, GfxData* aGfxData) { +void DynOS_Anim_Write(BinFile* aFile, GfxData* aGfxData) { for (auto& _Node : aGfxData->mAnimations) { // Value buffer @@ -182,27 +182,27 @@ void DynOS_Anim_Write(FILE* aFile, GfxData* aGfxData) { } // Header - WriteBytes(aFile, DATA_TYPE_ANIMATION); + aFile->Write(DATA_TYPE_ANIMATION); _Node->mName.Write(aFile); // Data - WriteBytes(aFile, _Node->mData->mFlags); - WriteBytes(aFile, _Node->mData->mUnk02); - WriteBytes(aFile, _Node->mData->mUnk04); - WriteBytes(aFile, _Node->mData->mUnk06); - WriteBytes(aFile, _Node->mData->mUnk08); - WriteBytes(aFile, (aGfxData->mAnimIndices[_Unk0ABufferIdx]->second.Count() / 6) - 1); - WriteBytes(aFile, _Node->mData->mLength); + aFile->Write(_Node->mData->mFlags); + aFile->Write(_Node->mData->mUnk02); + aFile->Write(_Node->mData->mUnk04); + aFile->Write(_Node->mData->mUnk06); + aFile->Write(_Node->mData->mUnk08); + aFile->Write((aGfxData->mAnimIndices[_Unk0ABufferIdx]->second.Count() / 6) - 1); + aFile->Write(_Node->mData->mLength); aGfxData->mAnimValues[_ValueBufferIdx]->second.Write(aFile); aGfxData->mAnimIndices[_IndexBufferIdx]->second.Write(aFile); } } -void DynOS_Anim_Table_Write(FILE* aFile, GfxData* aGfxData) { +void DynOS_Anim_Table_Write(BinFile* aFile, GfxData* aGfxData) { for (auto& _AnimName : aGfxData->mAnimationTable) { // Header - WriteBytes(aFile, DATA_TYPE_ANIMATION_TABLE); + aFile->Write(DATA_TYPE_ANIMATION_TABLE); // Data _AnimName.first.Write(aFile); @@ -213,7 +213,7 @@ void DynOS_Anim_Table_Write(FILE* aFile, GfxData* aGfxData) { // Reading // ///////////// -void DynOS_Anim_Load(FILE *aFile, GfxData *aGfxData) { +void DynOS_Anim_Load(BinFile *aFile, GfxData *aGfxData) { DataNode *_Node = New>(); // Name @@ -221,13 +221,13 @@ void DynOS_Anim_Load(FILE *aFile, GfxData *aGfxData) { // Data _Node->mData = New(); - _Node->mData->mFlags = ReadBytes(aFile); - _Node->mData->mUnk02 = ReadBytes(aFile); - _Node->mData->mUnk04 = ReadBytes(aFile); - _Node->mData->mUnk06 = ReadBytes(aFile); - _Node->mData->mUnk08 = ReadBytes(aFile); - _Node->mData->mUnk0A.second = ReadBytes(aFile); - _Node->mData->mLength = ReadBytes(aFile); + _Node->mData->mFlags = aFile->Read(); + _Node->mData->mUnk02 = aFile->Read(); + _Node->mData->mUnk04 = aFile->Read(); + _Node->mData->mUnk06 = aFile->Read(); + _Node->mData->mUnk08 = aFile->Read(); + _Node->mData->mUnk0A.second = aFile->Read(); + _Node->mData->mLength = aFile->Read(); _Node->mData->mValues.second.Read(aFile); _Node->mData->mIndex.second.Read(aFile); @@ -235,7 +235,7 @@ void DynOS_Anim_Load(FILE *aFile, GfxData *aGfxData) { aGfxData->mAnimations.Add(_Node); } -void DynOS_Anim_Table_Load(FILE *aFile, GfxData *aGfxData) { +void DynOS_Anim_Table_Load(BinFile *aFile, GfxData *aGfxData) { void *_AnimationPtr = NULL; // Data diff --git a/data/dynos_bin_behavior.cpp b/data/dynos_bin_behavior.cpp index 88e89eed..d141e2fd 100644 --- a/data/dynos_bin_behavior.cpp +++ b/data/dynos_bin_behavior.cpp @@ -2432,20 +2432,20 @@ static DataNode *GetBehaviorScript(GfxData *aGfxData, const Stri // Writing // ///////////// -static void DynOS_Bhv_Write(FILE* aFile, GfxData* aGfxData, DataNode *aNode) { +static void DynOS_Bhv_Write(BinFile* aFile, GfxData* aGfxData, DataNode *aNode) { if (!aNode->mData) return; // Name - WriteBytes(aFile, DATA_TYPE_BEHAVIOR_SCRIPT); + aFile->Write(DATA_TYPE_BEHAVIOR_SCRIPT); aNode->mName.Write(aFile); // Version - WriteBytes(aFile, BEHAVIOR_MAJOR_VER); - WriteBytes(aFile, BEHAVIOR_MINOR_VER); - WriteBytes(aFile, BEHAVIOR_PATCH_VER); + aFile->Write(BEHAVIOR_MAJOR_VER); + aFile->Write(BEHAVIOR_MINOR_VER); + aFile->Write(BEHAVIOR_PATCH_VER); // Data - WriteBytes(aFile, aNode->mSize); + aFile->Write(aNode->mSize); for (u32 i = 0; i != aNode->mSize; ++i) { BehaviorScript *_Head = &aNode->mData[i]; if (aGfxData->mPointerList.Find((void *) _Head) != -1) { @@ -2453,14 +2453,14 @@ static void DynOS_Bhv_Write(FILE* aFile, GfxData* aGfxData, DataNodemLuaPointerList.Find((void *) _Head) != -1) { DynOS_Pointer_Lua_Write(aFile, *(u32 *)_Head, aGfxData); } else { - WriteBytes(aFile, *((u32 *) _Head)); + aFile->Write(*((u32 *) _Head)); } } } static bool DynOS_Bhv_WriteBinary(const SysPath &aOutputFilename, GfxData *aGfxData) { - FILE *_File = fopen(aOutputFilename.c_str(), "wb"); + BinFile *_File = BinFile::OpenW(aOutputFilename.c_str()); if (!_File) { PrintError(" ERROR: Unable to create file \"%s\"", aOutputFilename.c_str()); return false; @@ -2474,7 +2474,7 @@ static bool DynOS_Bhv_WriteBinary(const SysPath &aOutputFilename, GfxData *aGfxD } } - fclose(_File); + BinFile::Close(_File); return true; } @@ -2482,28 +2482,28 @@ static bool DynOS_Bhv_WriteBinary(const SysPath &aOutputFilename, GfxData *aGfxD // Reading // ///////////// -static DataNode *DynOS_Bhv_Load(FILE *aFile, GfxData *aGfxData) { +static DataNode *DynOS_Bhv_Load(BinFile *aFile, GfxData *aGfxData) { DataNode *_Node = New>(); // Name _Node->mName.Read(aFile); // Version - u8 majorVersion = ReadBytes(aFile); - u8 minorVersion = ReadBytes(aFile); - u8 patchVersion = ReadBytes(aFile); + u8 majorVersion = aFile->Read(); + u8 minorVersion = aFile->Read(); + u8 patchVersion = aFile->Read(); // Version Sanity Check // // If the major version doesn't match, then a drasitc change has happened and // we can't read it no matter what. If it's just minor or patch. We might have // code to support it. - u32 dataSize = ReadBytes(aFile); + u32 dataSize = aFile->Read(); if (majorVersion != BEHAVIOR_MIN_MAJOR_VER || (minorVersion < BEHAVIOR_MIN_MINOR_VER || patchVersion < BEHAVIOR_MIN_PATCH_VER)) { PrintError(" ERROR: Behavior version is %u.%u.%u, but reading behaviors under %u.%u.%u is not supported!", majorVersion, minorVersion, patchVersion, BEHAVIOR_MIN_MAJOR_VER, BEHAVIOR_MIN_MINOR_VER, BEHAVIOR_MIN_PATCH_VER); // Skip the rest of the bytes saved for this behavior. - SkipBytes(aFile, dataSize); + aFile->Skip(dataSize); // We don't return this since we failed to read the behavior. Delete(_Node); // We have nothing to return, So return NULL. @@ -2521,11 +2521,11 @@ static DataNode *DynOS_Bhv_Load(FILE *aFile, GfxData *aGfxData) // Read it for (u32 i = 0; i != _Node->mSize; ++i) { - if (feof(aFile)) { + if (aFile->EoF()) { PrintError(" ERROR: Reached EOF when reading file! Expected %llx bytes!", _Node->mSize * sizeof(u32)); break; } - u32 _Value = ReadBytes(aFile); + u32 _Value = aFile->Read(); void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _Value, &_Node->mFlags); if (_Ptr) { _Node->mData[i] = (uintptr_t) _Ptr; @@ -2541,16 +2541,16 @@ GfxData *DynOS_Bhv_LoadFromBinary(const SysPath &aFilename, const char *aBehavio // Load data from binary file GfxData *_GfxData = NULL; - FILE *_File = fopen(aFilename.c_str(), "rb"); + BinFile *_File = BinFile::OpenR(aFilename.c_str()); if (_File != NULL) { _GfxData = New(); for (bool _Done = false; !_Done;) { - switch (ReadBytes(_File)) { + switch (_File->Read()) { case DATA_TYPE_BEHAVIOR_SCRIPT: DynOS_Bhv_Load(_File, _GfxData); break; default: _Done = true; break; } } - fclose(_File); + BinFile::Close(_File); } return _GfxData; diff --git a/data/dynos_bin_col.cpp b/data/dynos_bin_col.cpp index f3d0d730..7a610c7b 100644 --- a/data/dynos_bin_col.cpp +++ b/data/dynos_bin_col.cpp @@ -612,22 +612,22 @@ DataNode* DynOS_Col_Parse(GfxData* aGfxData, DataNode* aNo // Writing // ///////////// -void DynOS_Col_Write(FILE* aFile, GfxData* aGfxData, DataNode *aNode) { +void DynOS_Col_Write(BinFile* aFile, GfxData* aGfxData, DataNode *aNode) { if (!aNode->mData) return; // Name - WriteBytes(aFile, DATA_TYPE_COLLISION); + aFile->Write(DATA_TYPE_COLLISION); aNode->mName.Write(aFile); // Data - WriteBytes(aFile, aNode->mSize); + aFile->Write(aNode->mSize); for (u32 i = 0; i != aNode->mSize; ++i) { - WriteBytes(aFile, aNode->mData[i]); + aFile->Write(aNode->mData[i]); } } static bool DynOS_Col_WriteBinary(const SysPath &aOutputFilename, GfxData *aGfxData, DataNode* _Node) { - FILE *_File = fopen(aOutputFilename.c_str(), "wb"); + BinFile *_File = BinFile::OpenW(aOutputFilename.c_str()); if (!_File) { PrintError(" ERROR: Unable to create file \"%s\"", aOutputFilename.c_str()); return false; @@ -635,25 +635,25 @@ static bool DynOS_Col_WriteBinary(const SysPath &aOutputFilename, GfxData *aGfxD DynOS_Col_Write(_File, aGfxData, _Node); - fclose(_File); - return true; + BinFile::Close(_File); + return DynOS_Bin_Compress(aOutputFilename); } ///////////// // Loading // ///////////// -DataNode* DynOS_Col_Load(FILE *aFile, GfxData *aGfxData) { +DataNode* DynOS_Col_Load(BinFile *aFile, GfxData *aGfxData) { DataNode *_Node = New>(); // Name _Node->mName.Read(aFile); // Data - _Node->mSize = ReadBytes(aFile); + _Node->mSize = aFile->Read(); _Node->mData = New(_Node->mSize); for (u32 i = 0; i != _Node->mSize; ++i) { - _Node->mData[i] = ReadBytes(aFile); + _Node->mData[i] = aFile->Read(); } // Add it @@ -667,13 +667,13 @@ DataNode* DynOS_Col_Load(FILE *aFile, GfxData *aGfxData) { DataNode* DynOS_Col_LoadFromBinary(const SysPath &aFilename, const char *aCollisionName) { // Load data from binary file DataNode* collisionNode = NULL; - FILE *_File = fopen(aFilename.c_str(), "rb"); + BinFile *_File = DynOS_Bin_Decompress(aFilename); if (_File) { - u8 type = ReadBytes(_File); + u8 type = _File->Read(); if (type == DATA_TYPE_COLLISION) { collisionNode = DynOS_Col_Load(_File, NULL); } - fclose(_File); + BinFile::Close(_File); } return collisionNode; @@ -690,6 +690,12 @@ void DynOS_Col_Generate(const SysPath &aPackFolder, Array> _Ac // If there is an existing binary file for this collision, skip and go to the next actor SysPath _ColFilename = fstring("%s/%s.col", aPackFolder.c_str(), _ColRootName.begin()); if (fs_sys_file_exists(_ColFilename.c_str())) { +#ifdef DEVELOPMENT + // Compress file to gain some space + if (!DynOS_Bin_IsCompressed(_ColFilename)) { + DynOS_Bin_Compress(_ColFilename); + } +#endif continue; } diff --git a/data/dynos_bin_compress.cpp b/data/dynos_bin_compress.cpp new file mode 100644 index 00000000..8b9a24e4 --- /dev/null +++ b/data/dynos_bin_compress.cpp @@ -0,0 +1,222 @@ +#include "dynos.cpp.h" +#include + +static const u64 DYNOS_BIN_COMPRESS_MAGIC = 0x4E4942534F4E5944llu; +static FILE *sFile = NULL; +static Bytef *sBufferUncompressed = NULL; +static Bytef *sBufferCompressed = NULL; +static uLongf sLengthUncompressed = 0; +static uLongf sLengthCompressed = 0; + +static inline void DynOS_Bin_Compress_Init() { + sFile = NULL; + sBufferUncompressed = NULL; + sBufferCompressed = NULL; + sLengthUncompressed = 0; + sLengthCompressed = 0; +} + +static inline void DynOS_Bin_Compress_Free() { + if (sBufferCompressed) free(sBufferCompressed); + if (sBufferUncompressed) free(sBufferUncompressed); + if (sFile) fclose(sFile); +} + +static inline bool DynOS_Bin_Compress_Check(bool condition, const char *function, const char *filename, const char *message) { + if (!condition) { + Print("ERROR: %s: File \"%s\": %s", function, filename, message); + DynOS_Bin_Compress_Free(); + return false; + } + return true; +} + +bool DynOS_Bin_IsCompressed(const SysPath &aFilename) { + DynOS_Bin_Compress_Init(); + + // Open input file + if (!DynOS_Bin_Compress_Check( + (sFile = fopen(aFilename.c_str(), "rb")) != NULL, + __FUNCTION__, aFilename.c_str(), "Cannot open file" + )) return false; + + // Read magic + u64 _Magic = 0; + if (!DynOS_Bin_Compress_Check( + fread(&_Magic, sizeof(u64), 1, sFile) == 1, + __FUNCTION__, aFilename.c_str(), "Cannot read magic" + )) return false; + + // Compare with magic constant + if (_Magic != DYNOS_BIN_COMPRESS_MAGIC) { + DynOS_Bin_Compress_Free(); + return false; + } + + // It is a compressed file + DynOS_Bin_Compress_Free(); + return true; +} + +bool DynOS_Bin_Compress(const SysPath &aFilename) { + DynOS_Bin_Compress_Init(); + PrintNoNewLine("Compressing file \"%s\"...", aFilename.c_str()); + + // Open input file + if (!DynOS_Bin_Compress_Check( + (sFile = fopen(aFilename.c_str(), "rb")) != NULL, + __FUNCTION__, aFilename.c_str(), "Cannot open file" + )) return false; + + // Retrieve file length + if (!DynOS_Bin_Compress_Check( + fseek(sFile, 0, SEEK_END) == 0, + __FUNCTION__, aFilename.c_str(), "Cannot retrieve file length" + )) return false; + + // Check file length + if (!DynOS_Bin_Compress_Check( + (sLengthUncompressed = (uLongf) ftell(sFile)) != 0, + __FUNCTION__, aFilename.c_str(), "Empty file" + )) return false; + + // Allocate memory for uncompressed buffer + if (!DynOS_Bin_Compress_Check( + (sBufferUncompressed = (Bytef *) calloc(sLengthUncompressed, sizeof(Bytef))) != NULL, + __FUNCTION__, aFilename.c_str(), "Cannot allocate memory for compression" + )) return false; else rewind(sFile); + + // Read input data + if (!DynOS_Bin_Compress_Check( + fread(sBufferUncompressed, sizeof(Bytef), sLengthUncompressed, sFile) == sLengthUncompressed, + __FUNCTION__, aFilename.c_str(), "Cannot read uncompressed data" + )) return false; else fclose(sFile); + + // Compute maximum output file size + if (!DynOS_Bin_Compress_Check( + (sLengthCompressed = compressBound(sLengthUncompressed)) != 0, + __FUNCTION__, aFilename.c_str(), "Cannot compute compressed size" + )) return false; + + // Allocate memory for compressed buffer + if (!DynOS_Bin_Compress_Check( + (sBufferCompressed = (Bytef *) calloc(sLengthCompressed, sizeof(Bytef))) != NULL, + __FUNCTION__, aFilename.c_str(), "Cannot allocate memory for compression" + )) return false; + + // Compress data + if (!DynOS_Bin_Compress_Check( + compress2(sBufferCompressed, &sLengthCompressed, sBufferUncompressed, sLengthUncompressed, Z_BEST_COMPRESSION) == Z_OK, + __FUNCTION__, aFilename.c_str(), "Cannot compress data" + )) return false; + + // Check output length + // If the compression generates a bigger file, skip the process, but don't return a failure + if (!DynOS_Bin_Compress_Check( + sLengthCompressed < sLengthUncompressed, + __FUNCTION__, aFilename.c_str(), "Compressed data is bigger than uncompressed; Skipping compression" + )) return true; + + // Open output file + if (!DynOS_Bin_Compress_Check( + (sFile = fopen(aFilename.c_str(), "wb")) != NULL, + __FUNCTION__, aFilename.c_str(), "Cannot open file" + )) return false; + + // Write magic + if (!DynOS_Bin_Compress_Check( + fwrite(&DYNOS_BIN_COMPRESS_MAGIC, sizeof(u64), 1, sFile) == 1, + __FUNCTION__, aFilename.c_str(), "Cannot write magic" + )) return false; + + // Write uncompressed file size + if (!DynOS_Bin_Compress_Check( + fwrite(&sLengthUncompressed, sizeof(uLongf), 1, sFile) == 1, + __FUNCTION__, aFilename.c_str(), "Cannot write uncompressed file size" + )) return false; + + // Write compressed data + if (!DynOS_Bin_Compress_Check( + fwrite(sBufferCompressed, sizeof(Bytef), sLengthCompressed, sFile) == sLengthCompressed, + __FUNCTION__, aFilename.c_str(), "Cannot write compressed data" + )) return false; + + // Done, free buffers and files + DynOS_Bin_Compress_Free(); + Print(" Done."); + return true; +} + +BinFile *DynOS_Bin_Decompress(const SysPath &aFilename) { + DynOS_Bin_Compress_Init(); + + // Open input file + if (!DynOS_Bin_Compress_Check( + (sFile = fopen(aFilename.c_str(), "rb")) != NULL, + __FUNCTION__, aFilename.c_str(), "Cannot open file" + )) return NULL; + + // Read magic + u64 _Magic = 0; + if (!DynOS_Bin_Compress_Check( + fread(&_Magic, sizeof(u64), 1, sFile) == 1, + __FUNCTION__, aFilename.c_str(), "Cannot read magic" + )) return NULL; + + // Compare with magic constant + // If not equal, it's not a compressed file + if (_Magic != DYNOS_BIN_COMPRESS_MAGIC) { + DynOS_Bin_Compress_Free(); + return BinFile::OpenR(aFilename.c_str()); + } + PrintNoNewLine("Decompressing file \"%s\"...", aFilename.c_str()); + + // Read expected uncompressed file size + if (!DynOS_Bin_Compress_Check( + fread(&sLengthUncompressed, sizeof(uLongf), 1, sFile) == 1, + __FUNCTION__, aFilename.c_str(), "Cannot read uncompressed file size" + )) return NULL; + + // Retrieve file length + if (!DynOS_Bin_Compress_Check( + fseek(sFile, 0, SEEK_END) == 0, + __FUNCTION__, aFilename.c_str(), "Cannot retrieve file length" + )) return NULL; + + // Check file length + uLongf _LengthHeader = (uLongf) (sizeof(u64) + sizeof(uLongf)); + if (!DynOS_Bin_Compress_Check( + (sLengthCompressed = (uLongf) ftell(sFile)) >= _LengthHeader, + __FUNCTION__, aFilename.c_str(), "Empty file" + )) return NULL; + + // Allocate memory for compressed buffer + if (!DynOS_Bin_Compress_Check( + (sBufferCompressed = (Bytef *) calloc(sLengthCompressed - _LengthHeader, sizeof(Bytef))) != NULL, + __FUNCTION__, aFilename.c_str(), "Cannot allocate memory for decompression" + )) return NULL; else fseek(sFile, _LengthHeader, SEEK_SET); + + // Read input data + if (!DynOS_Bin_Compress_Check( + fread(sBufferCompressed, sizeof(Bytef), sLengthCompressed - _LengthHeader, sFile) == sLengthCompressed - _LengthHeader, + __FUNCTION__, aFilename.c_str(), "Cannot read compressed data" + )) return NULL; else fclose(sFile); + + // Allocate memory for uncompressed buffer + if (!DynOS_Bin_Compress_Check( + (sBufferUncompressed = (Bytef *) calloc(sLengthUncompressed, sizeof(Bytef))) != NULL, + __FUNCTION__, aFilename.c_str(), "Cannot allocate memory for decompression" + )) return NULL; + + // Uncompress data + if (!DynOS_Bin_Compress_Check( + uncompress(sBufferUncompressed, &sLengthUncompressed, sBufferCompressed, sLengthCompressed) == Z_OK, + __FUNCTION__, aFilename.c_str(), "Cannot uncompress data" + )) return NULL; + + // Return uncompressed data as a BinFile + BinFile *_BinFile = BinFile::OpenB(sBufferUncompressed, sLengthUncompressed); + DynOS_Bin_Compress_Free(); + Print(" Done."); + return _BinFile; +} diff --git a/data/dynos_bin_geo.cpp b/data/dynos_bin_geo.cpp index a91835b0..ba37877a 100644 --- a/data/dynos_bin_geo.cpp +++ b/data/dynos_bin_geo.cpp @@ -431,21 +431,21 @@ DataNode* DynOS_Geo_Parse(GfxData* aGfxData, DataNode* aNo // Writing // ///////////// -void DynOS_Geo_Write(FILE *aFile, GfxData *aGfxData, DataNode *aNode) { +void DynOS_Geo_Write(BinFile *aFile, GfxData *aGfxData, DataNode *aNode) { if (!aNode->mData) return; // Header - WriteBytes(aFile, DATA_TYPE_GEO_LAYOUT); + aFile->Write(DATA_TYPE_GEO_LAYOUT); aNode->mName.Write(aFile); // Data - WriteBytes(aFile, aNode->mSize); + aFile->Write(aNode->mSize); for (u32 i = 0; i != aNode->mSize; ++i) { GeoLayout *_Head = &aNode->mData[i]; if (aGfxData->mPointerList.Find((void *) _Head) != -1) { DynOS_Pointer_Write(aFile, (const void *) (*_Head), aGfxData); } else { - WriteBytes(aFile, *((u32 *) _Head)); + aFile->Write(*((u32 *) _Head)); } } } @@ -454,17 +454,17 @@ void DynOS_Geo_Write(FILE *aFile, GfxData *aGfxData, DataNode *aNode) // Reading // ///////////// -void DynOS_Geo_Load(FILE *aFile, GfxData *aGfxData) { +void DynOS_Geo_Load(BinFile *aFile, GfxData *aGfxData) { DataNode *_Node = New>(); // Name _Node->mName.Read(aFile); // Data - _Node->mSize = ReadBytes(aFile); + _Node->mSize = aFile->Read(); _Node->mData = New(_Node->mSize); for (u32 i = 0; i != _Node->mSize; ++i) { - u32 _Value = ReadBytes(aFile); + u32 _Value = aFile->Read(); void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _Value, &_Node->mFlags); if (_Ptr) { _Node->mData[i] = (uintptr_t) _Ptr; diff --git a/data/dynos_bin_gfx.cpp b/data/dynos_bin_gfx.cpp index 939e6ba7..33a2e914 100644 --- a/data/dynos_bin_gfx.cpp +++ b/data/dynos_bin_gfx.cpp @@ -937,23 +937,23 @@ DataNode* DynOS_Gfx_Parse(GfxData* aGfxData, DataNode* aNode) { // Writing // ///////////// -void DynOS_Gfx_Write(FILE *aFile, GfxData *aGfxData, DataNode *aNode) { +void DynOS_Gfx_Write(BinFile *aFile, GfxData *aGfxData, DataNode *aNode) { if (!aNode->mData) return; // Header - WriteBytes(aFile, DATA_TYPE_DISPLAY_LIST); + aFile->Write(DATA_TYPE_DISPLAY_LIST); aNode->mName.Write(aFile); // Data - WriteBytes(aFile, aNode->mSize); + aFile->Write(aNode->mSize); for (u32 i = 0; i != aNode->mSize; ++i) { Gfx *_Head = &aNode->mData[i]; if (aGfxData->mPointerList.Find((void *) _Head) != -1) { - WriteBytes(aFile, _Head->words.w0); + aFile->Write(_Head->words.w0); DynOS_Pointer_Write(aFile, (const void *) _Head->words.w1, aGfxData); } else { - WriteBytes(aFile, _Head->words.w0); - WriteBytes(aFile, _Head->words.w1); + aFile->Write(_Head->words.w0); + aFile->Write(_Head->words.w1); } } } @@ -961,18 +961,18 @@ void DynOS_Gfx_Write(FILE *aFile, GfxData *aGfxData, DataNode *aNode) { // Reading // ///////////// -void DynOS_Gfx_Load(FILE *aFile, GfxData *aGfxData) { +void DynOS_Gfx_Load(BinFile *aFile, GfxData *aGfxData) { DataNode *_Node = New>(); // Name _Node->mName.Read(aFile); // Data - _Node->mSize = ReadBytes(aFile); + _Node->mSize = aFile->Read(); _Node->mData = New(_Node->mSize); for (u32 i = 0; i != _Node->mSize; ++i) { - u32 _WordsW0 = ReadBytes(aFile); - u32 _WordsW1 = ReadBytes(aFile); + u32 _WordsW0 = aFile->Read(); + u32 _WordsW1 = aFile->Read(); void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _WordsW1, &_Node->mFlags); if (_Ptr) { _Node->mData[i].words.w0 = (uintptr_t) _WordsW0; diff --git a/data/dynos_bin_legacy.cpp b/data/dynos_bin_legacy.cpp index ac8cddf9..8d43138a 100644 --- a/data/dynos_bin_legacy.cpp +++ b/data/dynos_bin_legacy.cpp @@ -13,7 +13,7 @@ ///////////// // For retro-compatibility -void DynOS_GfxDynCmd_Load(FILE *aFile, GfxData *aGfxData) { +void DynOS_GfxDynCmd_Load(BinFile *aFile, GfxData *aGfxData) { Gfx *_Data = NULL; String _DisplayListName; _DisplayListName.Read(aFile); for (auto& _DisplayList : aGfxData->mDisplayLists) { @@ -25,6 +25,6 @@ void DynOS_GfxDynCmd_Load(FILE *aFile, GfxData *aGfxData) { if (!_Data) { sys_fatal("Display list not found: %s", _DisplayListName.begin()); } - ReadBytes(aFile); - ReadBytes(aFile); + aFile->Read(); + aFile->Read(); } diff --git a/data/dynos_bin_light_t.cpp b/data/dynos_bin_light_t.cpp index a266ccf0..e950e1c1 100644 --- a/data/dynos_bin_light_t.cpp +++ b/data/dynos_bin_light_t.cpp @@ -37,22 +37,22 @@ DataNode* DynOS_LightT_Parse(GfxData* aGfxData, DataNode* aNod // Writing // ///////////// -void DynOS_LightT_Write(FILE* aFile, GfxData* aGfxData, DataNode *aNode) { +void DynOS_LightT_Write(BinFile* aFile, GfxData* aGfxData, DataNode *aNode) { if (!aNode->mData) return; // Header - WriteBytes(aFile, DATA_TYPE_LIGHT_T); + aFile->Write(DATA_TYPE_LIGHT_T); aNode->mName.Write(aFile); // Data - WriteBytes(aFile, *aNode->mData); + aFile->Write(*aNode->mData); } ///////////// // Reading // ///////////// -void DynOS_LightT_Load(FILE *aFile, GfxData *aGfxData) { +void DynOS_LightT_Load(BinFile *aFile, GfxData *aGfxData) { DataNode *_Node = New>(); // Name @@ -60,7 +60,7 @@ void DynOS_LightT_Load(FILE *aFile, GfxData *aGfxData) { // Data _Node->mData = New(); - *_Node->mData = ReadBytes(aFile); + *_Node->mData = aFile->Read(); // Append aGfxData->mLightTs.Add(_Node); diff --git a/data/dynos_bin_lights.cpp b/data/dynos_bin_lights.cpp index ef046a58..aef7cc01 100644 --- a/data/dynos_bin_lights.cpp +++ b/data/dynos_bin_lights.cpp @@ -39,22 +39,22 @@ DataNode* DynOS_Lights_Parse(GfxData* aGfxData, DataNode* aNod // Writing // ///////////// -void DynOS_Lights_Write(FILE* aFile, GfxData* aGfxData, DataNode *aNode) { +void DynOS_Lights_Write(BinFile* aFile, GfxData* aGfxData, DataNode *aNode) { if (!aNode->mData) return; // Header - WriteBytes(aFile, DATA_TYPE_LIGHT); + aFile->Write(DATA_TYPE_LIGHT); aNode->mName.Write(aFile); // Data - WriteBytes(aFile, *aNode->mData); + aFile->Write(*aNode->mData); } ///////////// // Reading // ///////////// -void DynOS_Lights_Load(FILE *aFile, GfxData *aGfxData) { +void DynOS_Lights_Load(BinFile *aFile, GfxData *aGfxData) { DataNode *_Node = New>(); // Name @@ -62,7 +62,7 @@ void DynOS_Lights_Load(FILE *aFile, GfxData *aGfxData) { // Data _Node->mData = New(); - *_Node->mData = ReadBytes(aFile); + *_Node->mData = aFile->Read(); // Append aGfxData->mLights.Add(_Node); diff --git a/data/dynos_bin_lvl.cpp b/data/dynos_bin_lvl.cpp index 19a9b237..cc959624 100644 --- a/data/dynos_bin_lvl.cpp +++ b/data/dynos_bin_lvl.cpp @@ -857,15 +857,15 @@ static DataNode *GetLevelScript(GfxData *aGfxData, const String& aG // Writing // ///////////// -static void DynOS_Lvl_Write(FILE* aFile, GfxData* aGfxData, DataNode *aNode) { +static void DynOS_Lvl_Write(BinFile* aFile, GfxData* aGfxData, DataNode *aNode) { if (!aNode->mData) return; // Name - WriteBytes(aFile, DATA_TYPE_LEVEL_SCRIPT); + aFile->Write(DATA_TYPE_LEVEL_SCRIPT); aNode->mName.Write(aFile); // Data - WriteBytes(aFile, aNode->mSize); + aFile->Write(aNode->mSize); for (u32 i = 0; i != aNode->mSize; ++i) { LevelScript *_Head = &aNode->mData[i]; if (aGfxData->mPointerList.Find((void *) _Head) != -1) { @@ -873,13 +873,13 @@ static void DynOS_Lvl_Write(FILE* aFile, GfxData* aGfxData, DataNodemLuaPointerList.Find((void *) _Head) != -1) { DynOS_Pointer_Lua_Write(aFile, *(u32 *)_Head, aGfxData); } else { - WriteBytes(aFile, *((u32 *) _Head)); + aFile->Write(*((u32 *) _Head)); } } } static bool DynOS_Lvl_WriteBinary(const SysPath &aOutputFilename, GfxData *aGfxData) { - FILE *_File = fopen(aOutputFilename.c_str(), "wb"); + BinFile *_File = BinFile::OpenW(aOutputFilename.c_str()); if (!_File) { PrintError(" ERROR: Unable to create file \"%s\"", aOutputFilename.c_str()); return false; @@ -962,22 +962,22 @@ static bool DynOS_Lvl_WriteBinary(const SysPath &aOutputFilename, GfxData *aGfxD } } } - fclose(_File); - return true; + BinFile::Close(_File); + return DynOS_Bin_Compress(aOutputFilename); } ///////////// // Reading // ///////////// -static DataNode* DynOS_Lvl_Load(FILE *aFile, GfxData *aGfxData) { +static DataNode* DynOS_Lvl_Load(BinFile *aFile, GfxData *aGfxData) { DataNode *_Node = New>(); // Name _Node->mName.Read(aFile); // Data - _Node->mSize = ReadBytes(aFile); + _Node->mSize = aFile->Read(); _Node->mData = New(_Node->mSize); // Add it @@ -987,7 +987,7 @@ static DataNode* DynOS_Lvl_Load(FILE *aFile, GfxData *aGfxData) { // Read it for (u32 i = 0; i != _Node->mSize; ++i) { - u32 _Value = ReadBytes(aFile); + u32 _Value = aFile->Read(); void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _Value, &_Node->mFlags); if (_Ptr) { _Node->mData[i] = (uintptr_t) _Ptr; @@ -1005,11 +1005,11 @@ GfxData *DynOS_Lvl_LoadFromBinary(const SysPath &aFilename, const char *aLevelNa // Load data from binary file GfxData *_GfxData = NULL; - FILE *_File = fopen(aFilename.c_str(), "rb"); + BinFile *_File = DynOS_Bin_Decompress(aFilename); if (_File) { _GfxData = New(); for (bool _Done = false; !_Done;) { - switch (ReadBytes(_File)) { + switch (_File->Read()) { case DATA_TYPE_LIGHT: DynOS_Lights_Load (_File, _GfxData); break; case DATA_TYPE_LIGHT_T: DynOS_LightT_Load (_File, _GfxData); break; case DATA_TYPE_AMBIENT_T: DynOS_AmbientT_Load (_File, _GfxData); break; @@ -1031,7 +1031,7 @@ GfxData *DynOS_Lvl_LoadFromBinary(const SysPath &aFilename, const char *aLevelNa default: _Done = true; break; } } - fclose(_File); + BinFile::Close(_File); } return _GfxData; @@ -1051,6 +1051,12 @@ static bool DynOS_Lvl_GeneratePack_Internal(const SysPath &aPackFolder, Arrayd_name) == ".") continue; if (SysPath(_PackEnt->d_name) == "..") continue; +#ifdef DEVELOPMENT + // Compress .lvl files to gain some space + SysPath _Filename = fstring("%s/%s", aPackFolder.c_str(), _PackEnt->d_name); + if (SysPath(_PackEnt->d_name).find(".lvl") != SysPath::npos && !DynOS_Bin_IsCompressed(_Filename)) { + DynOS_Bin_Compress(_Filename); + continue; + } +#endif + // For each subfolder, read tokens from script.c SysPath _Folder = fstring("%s/%s", aPackFolder.c_str(), _PackEnt->d_name); if (!fs_sys_dir_exists(_Folder.c_str())) continue; diff --git a/data/dynos_bin_macro_object.cpp b/data/dynos_bin_macro_object.cpp index 327e610a..013fffa0 100644 --- a/data/dynos_bin_macro_object.cpp +++ b/data/dynos_bin_macro_object.cpp @@ -477,17 +477,17 @@ DataNode* DynOS_MacroObject_Parse(GfxData* aGfxData, DataNode *aNode) { +void DynOS_MacroObject_Write(BinFile* aFile, GfxData* aGfxData, DataNode *aNode) { if (!aNode->mData) return; // Name - WriteBytes(aFile, DATA_TYPE_MACRO_OBJECT); + aFile->Write(DATA_TYPE_MACRO_OBJECT); aNode->mName.Write(aFile); // Data - WriteBytes(aFile, aNode->mSize); + aFile->Write(aNode->mSize); for (u32 i = 0; i != aNode->mSize; ++i) { - WriteBytes(aFile, aNode->mData[i]); + aFile->Write(aNode->mData[i]); } } @@ -495,17 +495,17 @@ void DynOS_MacroObject_Write(FILE* aFile, GfxData* aGfxData, DataNode* DynOS_MacroObject_Load(FILE *aFile, GfxData *aGfxData) { +DataNode* DynOS_MacroObject_Load(BinFile *aFile, GfxData *aGfxData) { DataNode *_Node = New>(); // Name _Node->mName.Read(aFile); // Data - _Node->mSize = ReadBytes(aFile); + _Node->mSize = aFile->Read(); _Node->mData = New(_Node->mSize); for (u32 i = 0; i != _Node->mSize; ++i) { - _Node->mData[i] = ReadBytes(aFile); + _Node->mData[i] = aFile->Read(); } // Add it diff --git a/data/dynos_bin_movtex.cpp b/data/dynos_bin_movtex.cpp index ded1021d..9edbc26c 100644 --- a/data/dynos_bin_movtex.cpp +++ b/data/dynos_bin_movtex.cpp @@ -169,17 +169,17 @@ DataNode* DynOS_Movtex_Parse(GfxData* aGfxData, DataNode* aNode, // Writing // ///////////// -void DynOS_Movtex_Write(FILE* aFile, GfxData* aGfxData, DataNode *aNode) { +void DynOS_Movtex_Write(BinFile* aFile, GfxData* aGfxData, DataNode *aNode) { if (!aNode->mData) return; // Name - WriteBytes(aFile, DATA_TYPE_MOVTEX); + aFile->Write(DATA_TYPE_MOVTEX); aNode->mName.Write(aFile); // Data - WriteBytes(aFile, aNode->mSize); + aFile->Write(aNode->mSize); for (u32 i = 0; i != aNode->mSize; ++i) { - WriteBytes(aFile, aNode->mData[i]); + aFile->Write(aNode->mData[i]); } } @@ -187,17 +187,17 @@ void DynOS_Movtex_Write(FILE* aFile, GfxData* aGfxData, DataNode *aNode) // Reading // ///////////// -DataNode* DynOS_Movtex_Load(FILE *aFile, GfxData *aGfxData) { +DataNode* DynOS_Movtex_Load(BinFile *aFile, GfxData *aGfxData) { DataNode *_Node = New>(); // Name _Node->mName.Read(aFile); // Data - _Node->mSize = ReadBytes(aFile); + _Node->mSize = aFile->Read(); _Node->mData = New(_Node->mSize); for (u32 i = 0; i != _Node->mSize; ++i) { - _Node->mData[i] = ReadBytes(aFile); + _Node->mData[i] = aFile->Read(); } // Add it diff --git a/data/dynos_bin_movtexqc.cpp b/data/dynos_bin_movtexqc.cpp index 5d8f6c76..1a8fdc85 100644 --- a/data/dynos_bin_movtexqc.cpp +++ b/data/dynos_bin_movtexqc.cpp @@ -53,17 +53,17 @@ DataNode* DynOS_MovtexQC_Parse(GfxData* aGfxData, DataNode* // Writing // ///////////// -void DynOS_MovtexQC_Write(FILE* aFile, GfxData* aGfxData, DataNode *aNode) { +void DynOS_MovtexQC_Write(BinFile* aFile, GfxData* aGfxData, DataNode *aNode) { if (!aNode->mData) return; // Name - WriteBytes(aFile, DATA_TYPE_MOVTEXQC); + aFile->Write(DATA_TYPE_MOVTEXQC); aNode->mName.Write(aFile); // Data - WriteBytes(aFile, aNode->mSize); + aFile->Write(aNode->mSize); for (u32 i = 0; i != aNode->mSize; ++i) { - WriteBytes(aFile, aNode->mData[i].id); + aFile->Write(aNode->mData[i].id); DynOS_Pointer_Write(aFile, (const void *) (aNode->mData[i].quadArraySegmented), aGfxData); } } @@ -72,18 +72,18 @@ void DynOS_MovtexQC_Write(FILE* aFile, GfxData* aGfxData, DataNode *aN // Reading // ///////////// -DataNode* DynOS_MovtexQC_Load(FILE *aFile, GfxData *aGfxData) { +DataNode* DynOS_MovtexQC_Load(BinFile *aFile, GfxData *aGfxData) { DataNode *_Node = New>(); // Name _Node->mName.Read(aFile); // Data - _Node->mSize = ReadBytes(aFile); + _Node->mSize = aFile->Read(); _Node->mData = New(_Node->mSize); for (u32 i = 0; i != _Node->mSize; ++i) { - _Node->mData[i].id = ReadBytes(aFile); - u32 _Value = ReadBytes(aFile); + _Node->mData[i].id = aFile->Read(); + u32 _Value = aFile->Read(); void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _Value, &_Node->mFlags); _Node->mData[i].quadArraySegmented = (Movtex*)_Ptr; } diff --git a/data/dynos_bin_pointer.cpp b/data/dynos_bin_pointer.cpp index 7b1980a1..e7a28fec 100644 --- a/data/dynos_bin_pointer.cpp +++ b/data/dynos_bin_pointer.cpp @@ -187,17 +187,17 @@ static PointerData GetDataFromPointer(const void* aPtr, GfxData* aGfxData) { return { "", 0 }; } -void DynOS_Pointer_Lua_Write(FILE* aFile, u32 index, GfxData* aGfxData) { +void DynOS_Pointer_Lua_Write(BinFile* aFile, u32 index, GfxData* aGfxData) { String& token = aGfxData->mLuaTokenList[index]; - WriteBytes(aFile, LUA_VAR_CODE); + aFile->Write(LUA_VAR_CODE); token.Write(aFile); } -void DynOS_Pointer_Write(FILE* aFile, const void* aPtr, GfxData* aGfxData) { +void DynOS_Pointer_Write(BinFile* aFile, const void* aPtr, GfxData* aGfxData) { // NULL if (!aPtr) { - WriteBytes(aFile, 0); + aFile->Write(0); return; } @@ -206,7 +206,7 @@ void DynOS_Pointer_Write(FILE* aFile, const void* aPtr, GfxData* aGfxData) { if (aPtr == aGfxData->mLuaPointerList[i]) { u32 index = *((u32*)aPtr); String& token = aGfxData->mLuaTokenList[index]; - WriteBytes(aFile, LUA_VAR_CODE); + aFile->Write(LUA_VAR_CODE); token.Write(aFile); return; } @@ -215,16 +215,16 @@ void DynOS_Pointer_Write(FILE* aFile, const void* aPtr, GfxData* aGfxData) { // Built-in functions s32 _GeoFunctionIndex = DynOS_Builtin_Func_GetIndexFromData(aPtr); if (_GeoFunctionIndex != -1) { - WriteBytes(aFile, FUNCTION_CODE); - WriteBytes(aFile, _GeoFunctionIndex); + aFile->Write(FUNCTION_CODE); + aFile->Write(_GeoFunctionIndex); return; } // Pointer PointerData _PtrData = GetDataFromPointer(aPtr, aGfxData); - WriteBytes(aFile, POINTER_CODE); + aFile->Write(POINTER_CODE); _PtrData.first.Write(aFile); - WriteBytes(aFile, _PtrData.second); + aFile->Write(_PtrData.second); } ///////////// @@ -416,7 +416,7 @@ static void *GetPointerFromData(GfxData *aGfxData, const String &aPtrName, u32 a return NULL; } -void *DynOS_Pointer_Load(FILE *aFile, GfxData *aGfxData, u32 aValue, u8* outFlags) { +void *DynOS_Pointer_Load(BinFile *aFile, GfxData *aGfxData, u32 aValue, u8* outFlags) { // LUAV if (aValue == LUA_VAR_CODE) { @@ -433,14 +433,14 @@ void *DynOS_Pointer_Load(FILE *aFile, GfxData *aGfxData, u32 aValue, u8* outFlag // FUNC if (aValue == FUNCTION_CODE) { - s32 _FunctionIndex = ReadBytes(aFile); + s32 _FunctionIndex = aFile->Read(); return (void*) DynOS_Builtin_Func_GetFromIndex(_FunctionIndex); } // PNTR if (aValue == POINTER_CODE) { String _PtrName; _PtrName.Read(aFile); - u32 _PtrData = ReadBytes(aFile); + u32 _PtrData = aFile->Read(); return GetPointerFromData(aGfxData, _PtrName, _PtrData, outFlags); } diff --git a/data/dynos_bin_rooms.cpp b/data/dynos_bin_rooms.cpp index e5bad55f..755613ce 100644 --- a/data/dynos_bin_rooms.cpp +++ b/data/dynos_bin_rooms.cpp @@ -24,17 +24,17 @@ DataNode* DynOS_Rooms_Parse(GfxData* aGfxData, DataNode* aNode) { // Writing // ///////////// -void DynOS_Rooms_Write(FILE* aFile, GfxData* aGfxData, DataNode *aNode) { +void DynOS_Rooms_Write(BinFile* aFile, GfxData* aGfxData, DataNode *aNode) { if (!aNode->mData) return; // Name - WriteBytes(aFile, DATA_TYPE_ROOMS); + aFile->Write(DATA_TYPE_ROOMS); aNode->mName.Write(aFile); // Data - WriteBytes(aFile, aNode->mSize); + aFile->Write(aNode->mSize); for (u32 i = 0; i != aNode->mSize; ++i) { - WriteBytes(aFile, aNode->mData[i]); + aFile->Write(aNode->mData[i]); } } @@ -42,17 +42,17 @@ void DynOS_Rooms_Write(FILE* aFile, GfxData* aGfxData, DataNode *aNode) { // Reading // ///////////// -DataNode* DynOS_Rooms_Load(FILE *aFile, GfxData *aGfxData) { +DataNode* DynOS_Rooms_Load(BinFile *aFile, GfxData *aGfxData) { DataNode *_Node = New>(); // Name _Node->mName.Read(aFile); // Data - _Node->mSize = ReadBytes(aFile); + _Node->mSize = aFile->Read(); _Node->mData = New(_Node->mSize); for (u32 i = 0; i != _Node->mSize; ++i) { - _Node->mData[i] = ReadBytes(aFile); + _Node->mData[i] = aFile->Read(); } // Add it diff --git a/data/dynos_bin_tex.cpp b/data/dynos_bin_tex.cpp index 6ea57c87..a7b7852a 100644 --- a/data/dynos_bin_tex.cpp +++ b/data/dynos_bin_tex.cpp @@ -151,11 +151,11 @@ DataNode* DynOS_Tex_Parse(GfxData* aGfxData, DataNode* aNode) // Writing // ///////////// -void DynOS_Tex_Write(FILE* aFile, GfxData* aGfxData, DataNode *aNode) { +void DynOS_Tex_Write(BinFile* aFile, GfxData* aGfxData, DataNode *aNode) { if (!aNode->mData) return; // Header - WriteBytes(aFile, DATA_TYPE_TEXTURE); + aFile->Write(DATA_TYPE_TEXTURE); aNode->mName.Write(aFile); // Data @@ -169,7 +169,7 @@ void DynOS_Tex_Write(FILE* aFile, GfxData* aGfxData, DataNode *aNode) { aNode->mData->mPngData.Count() == _Node->mData->mPngData.Count() && // Check PNG data lengths memcmp(aNode->mData->mPngData.begin(), _Node->mData->mPngData.begin(), aNode->mData->mPngData.Count()) == 0) // Check PNG data content { - WriteBytes(aFile, TEX_REF_CODE); + aFile->Write(TEX_REF_CODE); _Node->mName.Write(aFile); return; } @@ -179,7 +179,7 @@ void DynOS_Tex_Write(FILE* aFile, GfxData* aGfxData, DataNode *aNode) { } static bool DynOS_Tex_WriteBinary(GfxData* aGfxData, const SysPath &aOutputFilename, String& aName, TexData* aTexData, bool aRawTexture) { - FILE *_File = fopen(aOutputFilename.c_str(), "wb"); + BinFile *_File = BinFile::OpenW(aOutputFilename.c_str()); if (!_File) { PrintError(" ERROR: Unable to create file \"%s\"", aOutputFilename.c_str()); return false; @@ -189,20 +189,20 @@ static bool DynOS_Tex_WriteBinary(GfxData* aGfxData, const SysPath &aOutputFilen // Write png-texture // Header - WriteBytes(_File, DATA_TYPE_TEXTURE); + _File->Write(DATA_TYPE_TEXTURE); aName.Write(_File); // Data aTexData->mPngData.Write(_File); - fclose(_File); + BinFile::Close(_File); return true; } // Write raw-texture // Header - WriteBytes(_File, DATA_TYPE_TEXTURE_RAW); + _File->Write(DATA_TYPE_TEXTURE_RAW); aName.Write(_File); // load @@ -213,13 +213,13 @@ static bool DynOS_Tex_WriteBinary(GfxData* aGfxData, const SysPath &aOutputFilen free(_RawData); // Data - WriteBytes(_File, aTexData->mRawFormat); - WriteBytes(_File, aTexData->mRawSize); - WriteBytes(_File, aTexData->mRawWidth); - WriteBytes(_File, aTexData->mRawHeight); + _File->Write(aTexData->mRawFormat); + _File->Write(aTexData->mRawSize); + _File->Write(aTexData->mRawWidth); + _File->Write(aTexData->mRawHeight); aTexData->mRawData.Write(_File); - fclose(_File); + BinFile::Close(_File); return true; } @@ -227,7 +227,7 @@ static bool DynOS_Tex_WriteBinary(GfxData* aGfxData, const SysPath &aOutputFilen // Reading // ///////////// -DataNode* DynOS_Tex_Load(FILE *aFile, GfxData *aGfxData) { +DataNode* DynOS_Tex_Load(BinFile *aFile, GfxData *aGfxData) { DataNode *_Node = New>(); // Name @@ -238,8 +238,8 @@ DataNode* DynOS_Tex_Load(FILE *aFile, GfxData *aGfxData) { _Node->mData->mUploaded = false; // Check for the texture ref magic - s32 _FileOffset = (s32) ftell(aFile); - u32 _TexRefCode = ReadBytes(aFile); + s32 _FileOffset = aFile->Offset(); + u32 _TexRefCode = aFile->Read(); if (_TexRefCode == TEX_REF_CODE) { // That's a duplicate, find the original node and copy its content @@ -256,7 +256,7 @@ DataNode* DynOS_Tex_Load(FILE *aFile, GfxData *aGfxData) { } } } else { - fseek(aFile, _FileOffset, SEEK_SET); + aFile->SetOffset(_FileOffset); _Node->mData->mPngData.Read(aFile); if (!_Node->mData->mPngData.Empty()) { u8 *_RawData = stbi_load_from_memory(_Node->mData->mPngData.begin(), _Node->mData->mPngData.Count(), &_Node->mData->mRawWidth, &_Node->mData->mRawHeight, NULL, 4); @@ -295,10 +295,10 @@ DataNode* DynOS_Tex_LoadFromBinary(const SysPath &aPackFolder, const Sy // Load data from binary file DataNode* _TexNode = NULL; - FILE *_File = fopen(aFilename.c_str(), "rb"); + BinFile *_File = BinFile::OpenR(aFilename.c_str()); if (!_File) { return NULL; } - u8 type = ReadBytes(_File); + u8 type = _File->Read(); if (type == DATA_TYPE_TEXTURE) { // load png-texture _TexNode = New>(); @@ -306,7 +306,7 @@ DataNode* DynOS_Tex_LoadFromBinary(const SysPath &aPackFolder, const Sy _TexNode->mName.Read(_File); _TexNode->mData->mPngData.Read(_File); - fclose(_File); + BinFile::Close(_File); if (aAddToPack) { if (!_Pack) { _Pack = DynOS_Pack_Add(aPackFolder); } @@ -315,7 +315,7 @@ DataNode* DynOS_Tex_LoadFromBinary(const SysPath &aPackFolder, const Sy return _TexNode; } else if (type != DATA_TYPE_TEXTURE_RAW) { - fclose(_File); + BinFile::Close(_File); return NULL; } @@ -324,13 +324,13 @@ DataNode* DynOS_Tex_LoadFromBinary(const SysPath &aPackFolder, const Sy _TexNode->mData = New(); _TexNode->mName.Read(_File); - _TexNode->mData->mRawFormat = ReadBytes(_File); - _TexNode->mData->mRawSize = ReadBytes(_File); - _TexNode->mData->mRawWidth = ReadBytes(_File); - _TexNode->mData->mRawHeight = ReadBytes(_File); + _TexNode->mData->mRawFormat = _File->Read(); + _TexNode->mData->mRawSize = _File->Read(); + _TexNode->mData->mRawWidth = _File->Read(); + _TexNode->mData->mRawHeight = _File->Read(); _TexNode->mData->mRawData.Read(_File); - fclose(_File); + BinFile::Close(_File); if (aAddToPack) { if (!_Pack) { _Pack = DynOS_Pack_Add(aPackFolder); } diff --git a/data/dynos_bin_texlist.cpp b/data/dynos_bin_texlist.cpp index 4729dbe6..c0a6fe88 100644 --- a/data/dynos_bin_texlist.cpp +++ b/data/dynos_bin_texlist.cpp @@ -36,15 +36,15 @@ DataNode* DynOS_TexList_Parse(GfxData* aGfxData, DataNode* a // Writing // ///////////// -void DynOS_TexList_Write(FILE* aFile, GfxData* aGfxData, DataNode *aNode) { +void DynOS_TexList_Write(BinFile* aFile, GfxData* aGfxData, DataNode *aNode) { if (!aNode->mData) return; // Name - WriteBytes(aFile, DATA_TYPE_TEXTURE_LIST); + aFile->Write(DATA_TYPE_TEXTURE_LIST); aNode->mName.Write(aFile); // Data - WriteBytes(aFile, aNode->mSize); + aFile->Write(aNode->mSize); for (u32 i = 0; i != aNode->mSize; ++i) { // find node bool found = false; @@ -65,17 +65,17 @@ void DynOS_TexList_Write(FILE* aFile, GfxData* aGfxData, DataNode *aNo // Reading // ///////////// -DataNode* DynOS_TexList_Load(FILE *aFile, GfxData *aGfxData) { +DataNode* DynOS_TexList_Load(BinFile *aFile, GfxData *aGfxData) { DataNode *_Node = New>(); // Name _Node->mName.Read(aFile); // Data - _Node->mSize = ReadBytes(aFile); + _Node->mSize = aFile->Read(); _Node->mData = New(_Node->mSize); for (u32 i = 0; i != _Node->mSize; ++i) { - u32 _Value = ReadBytes(aFile); + u32 _Value = aFile->Read(); void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _Value, &_Node->mFlags); if (_Ptr == NULL) { PrintError("Could not read texture in texlist"); diff --git a/data/dynos_bin_trajectory.cpp b/data/dynos_bin_trajectory.cpp index 718f342b..ba4cff5f 100644 --- a/data/dynos_bin_trajectory.cpp +++ b/data/dynos_bin_trajectory.cpp @@ -85,17 +85,17 @@ DataNode* DynOS_Trajectory_Parse(GfxData* aGfxData, DataNode *aNode) { +void DynOS_Trajectory_Write(BinFile* aFile, GfxData* aGfxData, DataNode *aNode) { if (!aNode->mData) return; // Name - WriteBytes(aFile, DATA_TYPE_TRAJECTORY); + aFile->Write(DATA_TYPE_TRAJECTORY); aNode->mName.Write(aFile); // Data - WriteBytes(aFile, aNode->mSize); + aFile->Write(aNode->mSize); for (u32 i = 0; i != aNode->mSize; ++i) { - WriteBytes(aFile, aNode->mData[i]); + aFile->Write(aNode->mData[i]); } } @@ -103,17 +103,17 @@ void DynOS_Trajectory_Write(FILE* aFile, GfxData* aGfxData, DataNode // Reading // ///////////// -DataNode* DynOS_Trajectory_Load(FILE *aFile, GfxData *aGfxData) { +DataNode* DynOS_Trajectory_Load(BinFile *aFile, GfxData *aGfxData) { DataNode *_Node = New>(); // Name _Node->mName.Read(aFile); // Data - _Node->mSize = ReadBytes(aFile); + _Node->mSize = aFile->Read(); _Node->mData = New(_Node->mSize); for (u32 i = 0; i != _Node->mSize; ++i) { - _Node->mData[i] = ReadBytes(aFile); + _Node->mData[i] = aFile->Read(); } // Add it diff --git a/data/dynos_bin_vtx.cpp b/data/dynos_bin_vtx.cpp index 31d28c72..d1cdc406 100644 --- a/data/dynos_bin_vtx.cpp +++ b/data/dynos_bin_vtx.cpp @@ -56,49 +56,49 @@ DataNode* DynOS_Vtx_Parse(GfxData* aGfxData, DataNode* aNode) { // Writing // ///////////// -void DynOS_Vtx_Write(FILE* aFile, GfxData* aGfxData, DataNode *aNode) { +void DynOS_Vtx_Write(BinFile* aFile, GfxData* aGfxData, DataNode *aNode) { if (!aNode->mData) return; // Header - WriteBytes(aFile, DATA_TYPE_VERTEX); + aFile->Write(DATA_TYPE_VERTEX); aNode->mName.Write(aFile); // Data bool shouldUseF32Vtx = ShouldUseF32Vtx(aNode); if (shouldUseF32Vtx) { - WriteBytes(aFile, aNode->mSize + 1); + aFile->Write(aNode->mSize + 1); // Write sentinel - WriteBytes(aFile, F32VTX_SENTINEL_0); - WriteBytes(aFile, F32VTX_SENTINEL_1); - WriteBytes(aFile, F32VTX_SENTINEL_2); - WriteBytes(aFile, 0); - WriteBytes(aFile, 0); - WriteBytes(aFile, 0); - WriteBytes (aFile, 0); - WriteBytes (aFile, 0); - WriteBytes (aFile, 0); - WriteBytes (aFile, 0); + aFile->Write(F32VTX_SENTINEL_0); + aFile->Write(F32VTX_SENTINEL_1); + aFile->Write(F32VTX_SENTINEL_2); + aFile->Write(0); + aFile->Write(0); + aFile->Write(0); + aFile->Write (0); + aFile->Write (0); + aFile->Write (0); + aFile->Write (0); } else { - WriteBytes(aFile, aNode->mSize); + aFile->Write(aNode->mSize); } for (u32 i = 0; i != aNode->mSize; ++i) { if (shouldUseF32Vtx) { - WriteBytes(aFile, aNode->mData[i].n.ob[0]); - WriteBytes(aFile, aNode->mData[i].n.ob[1]); - WriteBytes(aFile, aNode->mData[i].n.ob[2]); + aFile->Write(aNode->mData[i].n.ob[0]); + aFile->Write(aNode->mData[i].n.ob[1]); + aFile->Write(aNode->mData[i].n.ob[2]); } else { - WriteBytes(aFile, aNode->mData[i].n.ob[0]); - WriteBytes(aFile, aNode->mData[i].n.ob[1]); - WriteBytes(aFile, aNode->mData[i].n.ob[2]); + aFile->Write(aNode->mData[i].n.ob[0]); + aFile->Write(aNode->mData[i].n.ob[1]); + aFile->Write(aNode->mData[i].n.ob[2]); } - WriteBytes(aFile, aNode->mData[i].n.flag); - WriteBytes(aFile, aNode->mData[i].n.tc[0]); - WriteBytes(aFile, aNode->mData[i].n.tc[1]); - WriteBytes (aFile, aNode->mData[i].n.n[0]); - WriteBytes (aFile, aNode->mData[i].n.n[1]); - WriteBytes (aFile, aNode->mData[i].n.n[2]); - WriteBytes (aFile, aNode->mData[i].n.a); + aFile->Write(aNode->mData[i].n.flag); + aFile->Write(aNode->mData[i].n.tc[0]); + aFile->Write(aNode->mData[i].n.tc[1]); + aFile->Write (aNode->mData[i].n.n[0]); + aFile->Write (aNode->mData[i].n.n[1]); + aFile->Write (aNode->mData[i].n.n[2]); + aFile->Write (aNode->mData[i].n.a); } } @@ -106,7 +106,7 @@ void DynOS_Vtx_Write(FILE* aFile, GfxData* aGfxData, DataNode *aNode) { // Reading // ///////////// -void DynOS_Vtx_Load(FILE *aFile, GfxData *aGfxData) { +void DynOS_Vtx_Load(BinFile *aFile, GfxData *aGfxData) { DataNode *_Node = New>(); // Name @@ -114,25 +114,25 @@ void DynOS_Vtx_Load(FILE *aFile, GfxData *aGfxData) { // Data bool isUsingF32Vtx = false; - _Node->mSize = ReadBytes(aFile); + _Node->mSize = aFile->Read(); _Node->mData = New(_Node->mSize); for (u32 i = 0; i != _Node->mSize; ++i) { if (isUsingF32Vtx) { - _Node->mData[i].n.ob[0] = ReadBytes(aFile); - _Node->mData[i].n.ob[1] = ReadBytes(aFile); - _Node->mData[i].n.ob[2] = ReadBytes(aFile); + _Node->mData[i].n.ob[0] = aFile->Read(); + _Node->mData[i].n.ob[1] = aFile->Read(); + _Node->mData[i].n.ob[2] = aFile->Read(); } else { - _Node->mData[i].n.ob[0] = ReadBytes(aFile); - _Node->mData[i].n.ob[1] = ReadBytes(aFile); - _Node->mData[i].n.ob[2] = ReadBytes(aFile); + _Node->mData[i].n.ob[0] = aFile->Read(); + _Node->mData[i].n.ob[1] = aFile->Read(); + _Node->mData[i].n.ob[2] = aFile->Read(); } - _Node->mData[i].n.flag = ReadBytes(aFile); - _Node->mData[i].n.tc[0] = ReadBytes(aFile); - _Node->mData[i].n.tc[1] = ReadBytes(aFile); - _Node->mData[i].n.n[0] = ReadBytes (aFile); - _Node->mData[i].n.n[1] = ReadBytes (aFile); - _Node->mData[i].n.n[2] = ReadBytes (aFile); - _Node->mData[i].n.a = ReadBytes (aFile); + _Node->mData[i].n.flag = aFile->Read(); + _Node->mData[i].n.tc[0] = aFile->Read(); + _Node->mData[i].n.tc[1] = aFile->Read(); + _Node->mData[i].n.n[0] = aFile->Read (); + _Node->mData[i].n.n[1] = aFile->Read (); + _Node->mData[i].n.n[2] = aFile->Read (); + _Node->mData[i].n.a = aFile->Read (); // Check sentinel on first vertex if (!isUsingF32Vtx && i == 0 && IsUsingF32Vtx(_Node->mData[i].n.ob)) { diff --git a/data/dynos_file.cpp b/data/dynos_file.cpp deleted file mode 100644 index 2b995627..00000000 --- a/data/dynos_file.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include "dynos.cpp.h" - -void SkipBytes(FILE *aFile, size_t amount) { - // If we're at end of file. There is no more to skip. - if (feof(aFile)) { return; } - - int failure = fseek(aFile, amount, SEEK_CUR); - // If we failed to skip bytes. Print the error. - if (failure) { perror("The following error occured when skipping bytes"); } -} \ No newline at end of file