DynOS Bin Compression (#131)

This commit is contained in:
PeachyPeach 2022-06-25 09:52:53 +02:00 committed by GitHub
parent 4da9812d9b
commit f0c6668423
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 665 additions and 310 deletions

View file

@ -938,6 +938,9 @@ endif
# Coop specific libraries
# Zlib
LDFLAGS += -lz
# Lua
ifeq ($(WINDOWS_BUILD),1)
ifeq ($(TARGET_BITS), 32)

View file

@ -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 <typename T>
T Read() const {
T _Item = { 0 };
if (mOffset + sizeof(T) <= mSize) {
memcpy(&_Item, mData + mOffset, sizeof(T));
mOffset += sizeof(T);
}
return _Item;
}
template <typename T>
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 <typename T>
void Write(const T& aItem) {
if (!mReadOnly) {
Grow(mOffset + sizeof(T));
memcpy(mData + mOffset, &aItem, sizeof(T));
mOffset += sizeof(T);
}
}
template <typename T>
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<s32>();
Resize(_Length);
fread(mBuffer, sizeof(T), _Length, aFile);
aFile->Read<T>(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<s32>(mCount);
aFile->Write<T>(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<u8>();
aFile->Read<char>(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<u8>(mCount);
aFile->Write<char>(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 <typename T>
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 <typename T>
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 <typename... Args>
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<Collision>* DynOS_Col_Parse(GfxData* aGfxData, DataNode<Collision>* aNode, bool aDisplayPercent);
void DynOS_Col_Write(FILE* aFile, GfxData* aGfxData, DataNode<Collision> *aNode);
DataNode<Collision>* DynOS_Col_Load(FILE *aFile, GfxData *aGfxData);
void DynOS_Col_Write(BinFile* aFile, GfxData* aGfxData, DataNode<Collision> *aNode);
DataNode<Collision>* DynOS_Col_Load(BinFile *aFile, GfxData *aGfxData);
DataNode<Collision>* DynOS_Col_LoadFromBinary(const SysPath &aFilename, const char *aCollisionName);
void DynOS_Col_Generate(const SysPath &aPackFolder, Array<Pair<u64, String>> _ActorsFolders, GfxData *_GfxData);
DataNode<GeoLayout>* DynOS_Geo_Parse(GfxData* aGfxData, DataNode<GeoLayout>* aNode, bool aDisplayPercent);
void DynOS_Geo_Write(FILE *aFile, GfxData *aGfxData, DataNode<GeoLayout> *aNode);
void DynOS_Geo_Write(BinFile *aFile, GfxData *aGfxData, DataNode<GeoLayout> *aNode);
DataNode<GeoLayout>** DynOS_Geo_GetLoading(void);
void DynOS_Geo_Load(FILE *aFile, GfxData *aGfxData);
void DynOS_Geo_Load(BinFile *aFile, GfxData *aGfxData);
DataNode<Gfx>* DynOS_Gfx_Parse(GfxData* aGfxData, DataNode<Gfx>* aNode);
void DynOS_Gfx_Write(FILE *aFile, GfxData *aGfxData, DataNode<Gfx> *aNode);
void DynOS_Gfx_Load(FILE *aFile, GfxData *aGfxData);
void DynOS_Gfx_Write(BinFile *aFile, GfxData *aGfxData, DataNode<Gfx> *aNode);
void DynOS_Gfx_Load(BinFile *aFile, GfxData *aGfxData);
s64 DynOS_Gfx_ParseGfxConstants(const String& _Arg, bool* found);
DataNode<Lights1>* DynOS_Lights_Parse(GfxData* aGfxData, DataNode<Lights1>* aNode);
void DynOS_Lights_Write(FILE* aFile, GfxData* aGfxData, DataNode<Lights1> *aNode);
void DynOS_Lights_Load(FILE *aFile, GfxData *aGfxData);
void DynOS_Lights_Write(BinFile* aFile, GfxData* aGfxData, DataNode<Lights1> *aNode);
void DynOS_Lights_Load(BinFile *aFile, GfxData *aGfxData);
DataNode<Light_t>* DynOS_LightT_Parse(GfxData* aGfxData, DataNode<Light_t>* aNode);
void DynOS_LightT_Write(FILE* aFile, GfxData* aGfxData, DataNode<Light_t> *aNode);
void DynOS_LightT_Load(FILE *aFile, GfxData *aGfxData);
void DynOS_LightT_Write(BinFile* aFile, GfxData* aGfxData, DataNode<Light_t> *aNode);
void DynOS_LightT_Load(BinFile *aFile, GfxData *aGfxData);
DataNode<Ambient_t>* DynOS_AmbientT_Parse(GfxData* aGfxData, DataNode<Ambient_t>* aNode);
void DynOS_AmbientT_Write(FILE* aFile, GfxData* aGfxData, DataNode<Ambient_t> *aNode);
void DynOS_AmbientT_Load(FILE *aFile, GfxData *aGfxData);
void DynOS_AmbientT_Write(BinFile* aFile, GfxData* aGfxData, DataNode<Ambient_t> *aNode);
void DynOS_AmbientT_Load(BinFile *aFile, GfxData *aGfxData);
DataNode<MacroObject>* DynOS_MacroObject_Parse(GfxData* aGfxData, DataNode<MacroObject>* aNode, bool aDisplayPercent);
void DynOS_MacroObject_Write(FILE* aFile, GfxData* aGfxData, DataNode<MacroObject> *aNode);
DataNode<MacroObject>* DynOS_MacroObject_Load(FILE *aFile, GfxData *aGfxData);
void DynOS_MacroObject_Write(BinFile* aFile, GfxData* aGfxData, DataNode<MacroObject> *aNode);
DataNode<MacroObject>* DynOS_MacroObject_Load(BinFile *aFile, GfxData *aGfxData);
DataNode<Trajectory>* DynOS_Trajectory_Parse(GfxData* aGfxData, DataNode<Trajectory>* aNode, bool aDisplayPercent);
void DynOS_Trajectory_Write(FILE* aFile, GfxData* aGfxData, DataNode<Trajectory> *aNode);
DataNode<Trajectory>* DynOS_Trajectory_Load(FILE *aFile, GfxData *aGfxData);
void DynOS_Trajectory_Write(BinFile* aFile, GfxData* aGfxData, DataNode<Trajectory> *aNode);
DataNode<Trajectory>* DynOS_Trajectory_Load(BinFile *aFile, GfxData *aGfxData);
DataNode<Movtex>* DynOS_Movtex_Parse(GfxData* aGfxData, DataNode<Movtex>* aNode, bool aDisplayPercent);
void DynOS_Movtex_Write(FILE* aFile, GfxData* aGfxData, DataNode<Movtex> *aNode);
DataNode<Movtex>* DynOS_Movtex_Load(FILE *aFile, GfxData *aGfxData);
void DynOS_Movtex_Write(BinFile* aFile, GfxData* aGfxData, DataNode<Movtex> *aNode);
DataNode<Movtex>* DynOS_Movtex_Load(BinFile *aFile, GfxData *aGfxData);
DataNode<MovtexQC>* DynOS_MovtexQC_Parse(GfxData* aGfxData, DataNode<MovtexQC>* aNode);
void DynOS_MovtexQC_Write(FILE* aFile, GfxData* aGfxData, DataNode<MovtexQC> *aNode);
DataNode<MovtexQC>* DynOS_MovtexQC_Load(FILE *aFile, GfxData *aGfxData);
void DynOS_MovtexQC_Write(BinFile* aFile, GfxData* aGfxData, DataNode<MovtexQC> *aNode);
DataNode<MovtexQC>* DynOS_MovtexQC_Load(BinFile *aFile, GfxData *aGfxData);
DataNode<u8>* DynOS_Rooms_Parse(GfxData* aGfxData, DataNode<u8>* aNode);
void DynOS_Rooms_Write(FILE* aFile, GfxData* aGfxData, DataNode<u8> *aNode);
DataNode<u8>* DynOS_Rooms_Load(FILE *aFile, GfxData *aGfxData);
void DynOS_Rooms_Write(BinFile* aFile, GfxData* aGfxData, DataNode<u8> *aNode);
DataNode<u8>* DynOS_Rooms_Load(BinFile *aFile, GfxData *aGfxData);
DataNode<TexData>* DynOS_Tex_Parse(GfxData* aGfxData, DataNode<TexData>* aNode);
void DynOS_Tex_Write(FILE* aFile, GfxData* aGfxData, DataNode<TexData> *aNode);
DataNode<TexData>* DynOS_Tex_Load(FILE *aFile, GfxData *aGfxData);
void DynOS_Tex_Write(BinFile* aFile, GfxData* aGfxData, DataNode<TexData> *aNode);
DataNode<TexData>* DynOS_Tex_Load(BinFile *aFile, GfxData *aGfxData);
DataNode<TexData>* 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<TexData*>* DynOS_TexList_Parse(GfxData* aGfxData, DataNode<TexData*>* aNode);
void DynOS_TexList_Write(FILE* aFile, GfxData* aGfxData, DataNode<TexData*> *aNode);
DataNode<TexData*>* DynOS_TexList_Load(FILE *aFile, GfxData *aGfxData);
void DynOS_TexList_Write(BinFile* aFile, GfxData* aGfxData, DataNode<TexData*> *aNode);
DataNode<TexData*>* DynOS_TexList_Load(BinFile *aFile, GfxData *aGfxData);
DataNode<Vtx>* DynOS_Vtx_Parse(GfxData* aGfxData, DataNode<Vtx>* aNode);
void DynOS_Vtx_Write(FILE* aFile, GfxData* aGfxData, DataNode<Vtx> *aNode);
void DynOS_Vtx_Load(FILE *aFile, GfxData *aGfxData);
void DynOS_Vtx_Write(BinFile* aFile, GfxData* aGfxData, DataNode<Vtx> *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

View file

@ -14,7 +14,7 @@ void ClearGfxDataNodes(DataNodes<T> &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<GfxData>();
for (bool _Done = false; !_Done;) {
switch (ReadBytes<u8>(_File)) {
switch (_File->Read<u8>()) {
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, Array<Pair<u64, Str
// If there is an existing binary file for this layout, skip and go to the next actor
SysPath _BinFilename = fstring("%s/%s.bin", aPackFolder.c_str(), _GeoRootName.begin());
if (fs_sys_file_exists(_BinFilename.c_str())) {
#ifdef DEVELOPMENT
// Compress file to gain some space
if (!DynOS_Bin_IsCompressed(_BinFilename)) {
DynOS_Bin_Compress(_BinFilename);
}
#endif
return;
}
}
@ -246,6 +252,15 @@ void DynOS_Actor_GeneratePack(const SysPath &aPackFolder) {
if (SysPath(_PackEnt->d_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())) {

View file

@ -33,22 +33,22 @@ DataNode<Ambient_t>* DynOS_AmbientT_Parse(GfxData* aGfxData, DataNode<Ambient_t>
// Writing //
/////////////
void DynOS_AmbientT_Write(FILE* aFile, GfxData* aGfxData, DataNode<Ambient_t> *aNode) {
void DynOS_AmbientT_Write(BinFile* aFile, GfxData* aGfxData, DataNode<Ambient_t> *aNode) {
if (!aNode->mData) return;
// Header
WriteBytes<u8>(aFile, DATA_TYPE_AMBIENT_T);
aFile->Write<u8>(DATA_TYPE_AMBIENT_T);
aNode->mName.Write(aFile);
// Data
WriteBytes<Ambient_t>(aFile, *aNode->mData);
aFile->Write<Ambient_t>(*aNode->mData);
}
/////////////
// Reading //
/////////////
void DynOS_AmbientT_Load(FILE *aFile, GfxData *aGfxData) {
void DynOS_AmbientT_Load(BinFile *aFile, GfxData *aGfxData) {
DataNode<Ambient_t> *_Node = New<DataNode<Ambient_t>>();
// Name
@ -56,7 +56,7 @@ void DynOS_AmbientT_Load(FILE *aFile, GfxData *aGfxData) {
// Data
_Node->mData = New<Ambient_t>();
*_Node->mData = ReadBytes<Ambient_t>(aFile);
*_Node->mData = aFile->Read<Ambient_t>();
// Append
aGfxData->mAmbientTs.Add(_Node);

View file

@ -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<u8>(aFile, DATA_TYPE_ANIMATION);
aFile->Write<u8>(DATA_TYPE_ANIMATION);
_Node->mName.Write(aFile);
// Data
WriteBytes<s16>(aFile, _Node->mData->mFlags);
WriteBytes<s16>(aFile, _Node->mData->mUnk02);
WriteBytes<s16>(aFile, _Node->mData->mUnk04);
WriteBytes<s16>(aFile, _Node->mData->mUnk06);
WriteBytes<s16>(aFile, _Node->mData->mUnk08);
WriteBytes<s16>(aFile, (aGfxData->mAnimIndices[_Unk0ABufferIdx]->second.Count() / 6) - 1);
WriteBytes<u32>(aFile, _Node->mData->mLength);
aFile->Write<s16>(_Node->mData->mFlags);
aFile->Write<s16>(_Node->mData->mUnk02);
aFile->Write<s16>(_Node->mData->mUnk04);
aFile->Write<s16>(_Node->mData->mUnk06);
aFile->Write<s16>(_Node->mData->mUnk08);
aFile->Write<s16>((aGfxData->mAnimIndices[_Unk0ABufferIdx]->second.Count() / 6) - 1);
aFile->Write<u32>(_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<u8>(aFile, DATA_TYPE_ANIMATION_TABLE);
aFile->Write<u8>(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<AnimData> *_Node = New<DataNode<AnimData>>();
// Name
@ -221,13 +221,13 @@ void DynOS_Anim_Load(FILE *aFile, GfxData *aGfxData) {
// Data
_Node->mData = New<AnimData>();
_Node->mData->mFlags = ReadBytes<s16>(aFile);
_Node->mData->mUnk02 = ReadBytes<s16>(aFile);
_Node->mData->mUnk04 = ReadBytes<s16>(aFile);
_Node->mData->mUnk06 = ReadBytes<s16>(aFile);
_Node->mData->mUnk08 = ReadBytes<s16>(aFile);
_Node->mData->mUnk0A.second = ReadBytes<s16>(aFile);
_Node->mData->mLength = ReadBytes<u32>(aFile);
_Node->mData->mFlags = aFile->Read<s16>();
_Node->mData->mUnk02 = aFile->Read<s16>();
_Node->mData->mUnk04 = aFile->Read<s16>();
_Node->mData->mUnk06 = aFile->Read<s16>();
_Node->mData->mUnk08 = aFile->Read<s16>();
_Node->mData->mUnk0A.second = aFile->Read<s16>();
_Node->mData->mLength = aFile->Read<u32>();
_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

View file

@ -2432,20 +2432,20 @@ static DataNode<BehaviorScript> *GetBehaviorScript(GfxData *aGfxData, const Stri
// Writing //
/////////////
static void DynOS_Bhv_Write(FILE* aFile, GfxData* aGfxData, DataNode<BehaviorScript> *aNode) {
static void DynOS_Bhv_Write(BinFile* aFile, GfxData* aGfxData, DataNode<BehaviorScript> *aNode) {
if (!aNode->mData) return;
// Name
WriteBytes<u8>(aFile, DATA_TYPE_BEHAVIOR_SCRIPT);
aFile->Write<u8>(DATA_TYPE_BEHAVIOR_SCRIPT);
aNode->mName.Write(aFile);
// Version
WriteBytes<u8>(aFile, BEHAVIOR_MAJOR_VER);
WriteBytes<u8>(aFile, BEHAVIOR_MINOR_VER);
WriteBytes<u8>(aFile, BEHAVIOR_PATCH_VER);
aFile->Write<u8>(BEHAVIOR_MAJOR_VER);
aFile->Write<u8>(BEHAVIOR_MINOR_VER);
aFile->Write<u8>(BEHAVIOR_PATCH_VER);
// Data
WriteBytes<u32>(aFile, aNode->mSize);
aFile->Write<u32>(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, DataNode<BehaviorScr
} else if (aGfxData->mLuaPointerList.Find((void *) _Head) != -1) {
DynOS_Pointer_Lua_Write(aFile, *(u32 *)_Head, aGfxData);
} else {
WriteBytes<u32>(aFile, *((u32 *) _Head));
aFile->Write<u32>(*((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<BehaviorScript> *DynOS_Bhv_Load(FILE *aFile, GfxData *aGfxData) {
static DataNode<BehaviorScript> *DynOS_Bhv_Load(BinFile *aFile, GfxData *aGfxData) {
DataNode<BehaviorScript> *_Node = New<DataNode<BehaviorScript>>();
// Name
_Node->mName.Read(aFile);
// Version
u8 majorVersion = ReadBytes<u8>(aFile);
u8 minorVersion = ReadBytes<u8>(aFile);
u8 patchVersion = ReadBytes<u8>(aFile);
u8 majorVersion = aFile->Read<u8>();
u8 minorVersion = aFile->Read<u8>();
u8 patchVersion = aFile->Read<u8>();
// 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<u32>(aFile);
u32 dataSize = aFile->Read<u32>();
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<BehaviorScript> *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<u32>(aFile);
u32 _Value = aFile->Read<u32>();
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<GfxData>();
for (bool _Done = false; !_Done;) {
switch (ReadBytes<u8>(_File)) {
switch (_File->Read<u8>()) {
case DATA_TYPE_BEHAVIOR_SCRIPT: DynOS_Bhv_Load(_File, _GfxData); break;
default: _Done = true; break;
}
}
fclose(_File);
BinFile::Close(_File);
}
return _GfxData;

View file

@ -612,22 +612,22 @@ DataNode<Collision>* DynOS_Col_Parse(GfxData* aGfxData, DataNode<Collision>* aNo
// Writing //
/////////////
void DynOS_Col_Write(FILE* aFile, GfxData* aGfxData, DataNode<Collision> *aNode) {
void DynOS_Col_Write(BinFile* aFile, GfxData* aGfxData, DataNode<Collision> *aNode) {
if (!aNode->mData) return;
// Name
WriteBytes<u8>(aFile, DATA_TYPE_COLLISION);
aFile->Write<u8>(DATA_TYPE_COLLISION);
aNode->mName.Write(aFile);
// Data
WriteBytes<u32>(aFile, aNode->mSize);
aFile->Write<u32>(aNode->mSize);
for (u32 i = 0; i != aNode->mSize; ++i) {
WriteBytes<Collision>(aFile, aNode->mData[i]);
aFile->Write<Collision>(aNode->mData[i]);
}
}
static bool DynOS_Col_WriteBinary(const SysPath &aOutputFilename, GfxData *aGfxData, DataNode<Collision>* _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<Collision>* DynOS_Col_Load(FILE *aFile, GfxData *aGfxData) {
DataNode<Collision>* DynOS_Col_Load(BinFile *aFile, GfxData *aGfxData) {
DataNode<Collision> *_Node = New<DataNode<Collision>>();
// Name
_Node->mName.Read(aFile);
// Data
_Node->mSize = ReadBytes<u32>(aFile);
_Node->mSize = aFile->Read<u32>();
_Node->mData = New<Collision>(_Node->mSize);
for (u32 i = 0; i != _Node->mSize; ++i) {
_Node->mData[i] = ReadBytes<Collision>(aFile);
_Node->mData[i] = aFile->Read<Collision>();
}
// Add it
@ -667,13 +667,13 @@ DataNode<Collision>* DynOS_Col_Load(FILE *aFile, GfxData *aGfxData) {
DataNode<Collision>* DynOS_Col_LoadFromBinary(const SysPath &aFilename, const char *aCollisionName) {
// Load data from binary file
DataNode<Collision>* collisionNode = NULL;
FILE *_File = fopen(aFilename.c_str(), "rb");
BinFile *_File = DynOS_Bin_Decompress(aFilename);
if (_File) {
u8 type = ReadBytes<u8>(_File);
u8 type = _File->Read<u8>();
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<Pair<u64, String>> _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;
}

222
data/dynos_bin_compress.cpp Normal file
View file

@ -0,0 +1,222 @@
#include "dynos.cpp.h"
#include <zlib.h>
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;
}

View file

@ -431,21 +431,21 @@ DataNode<GeoLayout>* DynOS_Geo_Parse(GfxData* aGfxData, DataNode<GeoLayout>* aNo
// Writing //
/////////////
void DynOS_Geo_Write(FILE *aFile, GfxData *aGfxData, DataNode<GeoLayout> *aNode) {
void DynOS_Geo_Write(BinFile *aFile, GfxData *aGfxData, DataNode<GeoLayout> *aNode) {
if (!aNode->mData) return;
// Header
WriteBytes<u8>(aFile, DATA_TYPE_GEO_LAYOUT);
aFile->Write<u8>(DATA_TYPE_GEO_LAYOUT);
aNode->mName.Write(aFile);
// Data
WriteBytes<u32>(aFile, aNode->mSize);
aFile->Write<u32>(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<u32>(aFile, *((u32 *) _Head));
aFile->Write<u32>(*((u32 *) _Head));
}
}
}
@ -454,17 +454,17 @@ void DynOS_Geo_Write(FILE *aFile, GfxData *aGfxData, DataNode<GeoLayout> *aNode)
// Reading //
/////////////
void DynOS_Geo_Load(FILE *aFile, GfxData *aGfxData) {
void DynOS_Geo_Load(BinFile *aFile, GfxData *aGfxData) {
DataNode<GeoLayout> *_Node = New<DataNode<GeoLayout>>();
// Name
_Node->mName.Read(aFile);
// Data
_Node->mSize = ReadBytes<u32>(aFile);
_Node->mSize = aFile->Read<u32>();
_Node->mData = New<GeoLayout>(_Node->mSize);
for (u32 i = 0; i != _Node->mSize; ++i) {
u32 _Value = ReadBytes<u32>(aFile);
u32 _Value = aFile->Read<u32>();
void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _Value, &_Node->mFlags);
if (_Ptr) {
_Node->mData[i] = (uintptr_t) _Ptr;

View file

@ -937,23 +937,23 @@ DataNode<Gfx>* DynOS_Gfx_Parse(GfxData* aGfxData, DataNode<Gfx>* aNode) {
// Writing //
/////////////
void DynOS_Gfx_Write(FILE *aFile, GfxData *aGfxData, DataNode<Gfx> *aNode) {
void DynOS_Gfx_Write(BinFile *aFile, GfxData *aGfxData, DataNode<Gfx> *aNode) {
if (!aNode->mData) return;
// Header
WriteBytes<u8>(aFile, DATA_TYPE_DISPLAY_LIST);
aFile->Write<u8>(DATA_TYPE_DISPLAY_LIST);
aNode->mName.Write(aFile);
// Data
WriteBytes<u32>(aFile, aNode->mSize);
aFile->Write<u32>(aNode->mSize);
for (u32 i = 0; i != aNode->mSize; ++i) {
Gfx *_Head = &aNode->mData[i];
if (aGfxData->mPointerList.Find((void *) _Head) != -1) {
WriteBytes<u32>(aFile, _Head->words.w0);
aFile->Write<u32>(_Head->words.w0);
DynOS_Pointer_Write(aFile, (const void *) _Head->words.w1, aGfxData);
} else {
WriteBytes<u32>(aFile, _Head->words.w0);
WriteBytes<u32>(aFile, _Head->words.w1);
aFile->Write<u32>(_Head->words.w0);
aFile->Write<u32>(_Head->words.w1);
}
}
}
@ -961,18 +961,18 @@ void DynOS_Gfx_Write(FILE *aFile, GfxData *aGfxData, DataNode<Gfx> *aNode) {
// Reading //
/////////////
void DynOS_Gfx_Load(FILE *aFile, GfxData *aGfxData) {
void DynOS_Gfx_Load(BinFile *aFile, GfxData *aGfxData) {
DataNode<Gfx> *_Node = New<DataNode<Gfx>>();
// Name
_Node->mName.Read(aFile);
// Data
_Node->mSize = ReadBytes<u32>(aFile);
_Node->mSize = aFile->Read<u32>();
_Node->mData = New<Gfx>(_Node->mSize);
for (u32 i = 0; i != _Node->mSize; ++i) {
u32 _WordsW0 = ReadBytes<u32>(aFile);
u32 _WordsW1 = ReadBytes<u32>(aFile);
u32 _WordsW0 = aFile->Read<u32>();
u32 _WordsW1 = aFile->Read<u32>();
void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _WordsW1, &_Node->mFlags);
if (_Ptr) {
_Node->mData[i].words.w0 = (uintptr_t) _WordsW0;

View file

@ -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<u32>(aFile);
ReadBytes<u8>(aFile);
aFile->Read<u32>();
aFile->Read<u8>();
}

View file

@ -37,22 +37,22 @@ DataNode<Light_t>* DynOS_LightT_Parse(GfxData* aGfxData, DataNode<Light_t>* aNod
// Writing //
/////////////
void DynOS_LightT_Write(FILE* aFile, GfxData* aGfxData, DataNode<Light_t> *aNode) {
void DynOS_LightT_Write(BinFile* aFile, GfxData* aGfxData, DataNode<Light_t> *aNode) {
if (!aNode->mData) return;
// Header
WriteBytes<u8>(aFile, DATA_TYPE_LIGHT_T);
aFile->Write<u8>(DATA_TYPE_LIGHT_T);
aNode->mName.Write(aFile);
// Data
WriteBytes<Light_t>(aFile, *aNode->mData);
aFile->Write<Light_t>(*aNode->mData);
}
/////////////
// Reading //
/////////////
void DynOS_LightT_Load(FILE *aFile, GfxData *aGfxData) {
void DynOS_LightT_Load(BinFile *aFile, GfxData *aGfxData) {
DataNode<Light_t> *_Node = New<DataNode<Light_t>>();
// Name
@ -60,7 +60,7 @@ void DynOS_LightT_Load(FILE *aFile, GfxData *aGfxData) {
// Data
_Node->mData = New<Light_t>();
*_Node->mData = ReadBytes<Light_t>(aFile);
*_Node->mData = aFile->Read<Light_t>();
// Append
aGfxData->mLightTs.Add(_Node);

View file

@ -39,22 +39,22 @@ DataNode<Lights1>* DynOS_Lights_Parse(GfxData* aGfxData, DataNode<Lights1>* aNod
// Writing //
/////////////
void DynOS_Lights_Write(FILE* aFile, GfxData* aGfxData, DataNode<Lights1> *aNode) {
void DynOS_Lights_Write(BinFile* aFile, GfxData* aGfxData, DataNode<Lights1> *aNode) {
if (!aNode->mData) return;
// Header
WriteBytes<u8>(aFile, DATA_TYPE_LIGHT);
aFile->Write<u8>(DATA_TYPE_LIGHT);
aNode->mName.Write(aFile);
// Data
WriteBytes<Lights1>(aFile, *aNode->mData);
aFile->Write<Lights1>(*aNode->mData);
}
/////////////
// Reading //
/////////////
void DynOS_Lights_Load(FILE *aFile, GfxData *aGfxData) {
void DynOS_Lights_Load(BinFile *aFile, GfxData *aGfxData) {
DataNode<Lights1> *_Node = New<DataNode<Lights1>>();
// Name
@ -62,7 +62,7 @@ void DynOS_Lights_Load(FILE *aFile, GfxData *aGfxData) {
// Data
_Node->mData = New<Lights1>();
*_Node->mData = ReadBytes<Lights1>(aFile);
*_Node->mData = aFile->Read<Lights1>();
// Append
aGfxData->mLights.Add(_Node);

View file

@ -857,15 +857,15 @@ static DataNode<LevelScript> *GetLevelScript(GfxData *aGfxData, const String& aG
// Writing //
/////////////
static void DynOS_Lvl_Write(FILE* aFile, GfxData* aGfxData, DataNode<LevelScript> *aNode) {
static void DynOS_Lvl_Write(BinFile* aFile, GfxData* aGfxData, DataNode<LevelScript> *aNode) {
if (!aNode->mData) return;
// Name
WriteBytes<u8>(aFile, DATA_TYPE_LEVEL_SCRIPT);
aFile->Write<u8>(DATA_TYPE_LEVEL_SCRIPT);
aNode->mName.Write(aFile);
// Data
WriteBytes<u32>(aFile, aNode->mSize);
aFile->Write<u32>(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, DataNode<LevelScript
} else if (aGfxData->mLuaPointerList.Find((void *) _Head) != -1) {
DynOS_Pointer_Lua_Write(aFile, *(u32 *)_Head, aGfxData);
} else {
WriteBytes<u32>(aFile, *((u32 *) _Head));
aFile->Write<u32>(*((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<LevelScript>* DynOS_Lvl_Load(FILE *aFile, GfxData *aGfxData) {
static DataNode<LevelScript>* DynOS_Lvl_Load(BinFile *aFile, GfxData *aGfxData) {
DataNode<LevelScript> *_Node = New<DataNode<LevelScript>>();
// Name
_Node->mName.Read(aFile);
// Data
_Node->mSize = ReadBytes<u32>(aFile);
_Node->mSize = aFile->Read<u32>();
_Node->mData = New<LevelScript>(_Node->mSize);
// Add it
@ -987,7 +987,7 @@ static DataNode<LevelScript>* DynOS_Lvl_Load(FILE *aFile, GfxData *aGfxData) {
// Read it
for (u32 i = 0; i != _Node->mSize; ++i) {
u32 _Value = ReadBytes<u32>(aFile);
u32 _Value = aFile->Read<u32>();
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<GfxData>();
for (bool _Done = false; !_Done;) {
switch (ReadBytes<u8>(_File)) {
switch (_File->Read<u8>()) {
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, Array<Pa
// If there is an existing binary file for this level, skip and go to the next level
SysPath _LvlFilename = fstring("%s/%s.lvl", aPackFolder.c_str(), _LvlRootName.begin());
if (fs_sys_file_exists(_LvlFilename.c_str())) {
#ifdef DEVELOPMENT
// Compress file to gain some space
if (!DynOS_Bin_IsCompressed(_LvlFilename)) {
DynOS_Bin_Compress(_LvlFilename);
}
#endif
continue;
}
@ -1171,6 +1177,15 @@ void DynOS_Lvl_GeneratePack(const SysPath &aPackFolder) {
if (SysPath(_PackEnt->d_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;

View file

@ -477,17 +477,17 @@ DataNode<MacroObject>* DynOS_MacroObject_Parse(GfxData* aGfxData, DataNode<Macro
// Writing //
/////////////
void DynOS_MacroObject_Write(FILE* aFile, GfxData* aGfxData, DataNode<MacroObject> *aNode) {
void DynOS_MacroObject_Write(BinFile* aFile, GfxData* aGfxData, DataNode<MacroObject> *aNode) {
if (!aNode->mData) return;
// Name
WriteBytes<u8>(aFile, DATA_TYPE_MACRO_OBJECT);
aFile->Write<u8>(DATA_TYPE_MACRO_OBJECT);
aNode->mName.Write(aFile);
// Data
WriteBytes<u32>(aFile, aNode->mSize);
aFile->Write<u32>(aNode->mSize);
for (u32 i = 0; i != aNode->mSize; ++i) {
WriteBytes<MacroObject>(aFile, aNode->mData[i]);
aFile->Write<MacroObject>(aNode->mData[i]);
}
}
@ -495,17 +495,17 @@ void DynOS_MacroObject_Write(FILE* aFile, GfxData* aGfxData, DataNode<MacroObjec
// Reading //
/////////////
DataNode<MacroObject>* DynOS_MacroObject_Load(FILE *aFile, GfxData *aGfxData) {
DataNode<MacroObject>* DynOS_MacroObject_Load(BinFile *aFile, GfxData *aGfxData) {
DataNode<MacroObject> *_Node = New<DataNode<MacroObject>>();
// Name
_Node->mName.Read(aFile);
// Data
_Node->mSize = ReadBytes<u32>(aFile);
_Node->mSize = aFile->Read<u32>();
_Node->mData = New<MacroObject>(_Node->mSize);
for (u32 i = 0; i != _Node->mSize; ++i) {
_Node->mData[i] = ReadBytes<MacroObject>(aFile);
_Node->mData[i] = aFile->Read<MacroObject>();
}
// Add it

View file

@ -169,17 +169,17 @@ DataNode<Movtex>* DynOS_Movtex_Parse(GfxData* aGfxData, DataNode<Movtex>* aNode,
// Writing //
/////////////
void DynOS_Movtex_Write(FILE* aFile, GfxData* aGfxData, DataNode<Movtex> *aNode) {
void DynOS_Movtex_Write(BinFile* aFile, GfxData* aGfxData, DataNode<Movtex> *aNode) {
if (!aNode->mData) return;
// Name
WriteBytes<u8>(aFile, DATA_TYPE_MOVTEX);
aFile->Write<u8>(DATA_TYPE_MOVTEX);
aNode->mName.Write(aFile);
// Data
WriteBytes<u32>(aFile, aNode->mSize);
aFile->Write<u32>(aNode->mSize);
for (u32 i = 0; i != aNode->mSize; ++i) {
WriteBytes<Movtex>(aFile, aNode->mData[i]);
aFile->Write<Movtex>(aNode->mData[i]);
}
}
@ -187,17 +187,17 @@ void DynOS_Movtex_Write(FILE* aFile, GfxData* aGfxData, DataNode<Movtex> *aNode)
// Reading //
/////////////
DataNode<Movtex>* DynOS_Movtex_Load(FILE *aFile, GfxData *aGfxData) {
DataNode<Movtex>* DynOS_Movtex_Load(BinFile *aFile, GfxData *aGfxData) {
DataNode<Movtex> *_Node = New<DataNode<Movtex>>();
// Name
_Node->mName.Read(aFile);
// Data
_Node->mSize = ReadBytes<u32>(aFile);
_Node->mSize = aFile->Read<u32>();
_Node->mData = New<Movtex>(_Node->mSize);
for (u32 i = 0; i != _Node->mSize; ++i) {
_Node->mData[i] = ReadBytes<Movtex>(aFile);
_Node->mData[i] = aFile->Read<Movtex>();
}
// Add it

View file

@ -53,17 +53,17 @@ DataNode<MovtexQC>* DynOS_MovtexQC_Parse(GfxData* aGfxData, DataNode<MovtexQC>*
// Writing //
/////////////
void DynOS_MovtexQC_Write(FILE* aFile, GfxData* aGfxData, DataNode<MovtexQC> *aNode) {
void DynOS_MovtexQC_Write(BinFile* aFile, GfxData* aGfxData, DataNode<MovtexQC> *aNode) {
if (!aNode->mData) return;
// Name
WriteBytes<u8>(aFile, DATA_TYPE_MOVTEXQC);
aFile->Write<u8>(DATA_TYPE_MOVTEXQC);
aNode->mName.Write(aFile);
// Data
WriteBytes<u32>(aFile, aNode->mSize);
aFile->Write<u32>(aNode->mSize);
for (u32 i = 0; i != aNode->mSize; ++i) {
WriteBytes<s16>(aFile, aNode->mData[i].id);
aFile->Write<s16>(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<MovtexQC> *aN
// Reading //
/////////////
DataNode<MovtexQC>* DynOS_MovtexQC_Load(FILE *aFile, GfxData *aGfxData) {
DataNode<MovtexQC>* DynOS_MovtexQC_Load(BinFile *aFile, GfxData *aGfxData) {
DataNode<MovtexQC> *_Node = New<DataNode<MovtexQC>>();
// Name
_Node->mName.Read(aFile);
// Data
_Node->mSize = ReadBytes<u32>(aFile);
_Node->mSize = aFile->Read<u32>();
_Node->mData = New<MovtexQC>(_Node->mSize);
for (u32 i = 0; i != _Node->mSize; ++i) {
_Node->mData[i].id = ReadBytes<s16>(aFile);
u32 _Value = ReadBytes<u32>(aFile);
_Node->mData[i].id = aFile->Read<s16>();
u32 _Value = aFile->Read<u32>();
void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _Value, &_Node->mFlags);
_Node->mData[i].quadArraySegmented = (Movtex*)_Ptr;
}

View file

@ -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<u32>(aFile, LUA_VAR_CODE);
aFile->Write<u32>(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<u32>(aFile, 0);
aFile->Write<u32>(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<u32>(aFile, LUA_VAR_CODE);
aFile->Write<u32>(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<u32>(aFile, FUNCTION_CODE);
WriteBytes<s32>(aFile, _GeoFunctionIndex);
aFile->Write<u32>(FUNCTION_CODE);
aFile->Write<s32>(_GeoFunctionIndex);
return;
}
// Pointer
PointerData _PtrData = GetDataFromPointer(aPtr, aGfxData);
WriteBytes<u32>(aFile, POINTER_CODE);
aFile->Write<u32>(POINTER_CODE);
_PtrData.first.Write(aFile);
WriteBytes<u32>(aFile, _PtrData.second);
aFile->Write<u32>(_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<s32>(aFile);
s32 _FunctionIndex = aFile->Read<s32>();
return (void*) DynOS_Builtin_Func_GetFromIndex(_FunctionIndex);
}
// PNTR
if (aValue == POINTER_CODE) {
String _PtrName; _PtrName.Read(aFile);
u32 _PtrData = ReadBytes<u32>(aFile);
u32 _PtrData = aFile->Read<u32>();
return GetPointerFromData(aGfxData, _PtrName, _PtrData, outFlags);
}

View file

@ -24,17 +24,17 @@ DataNode<u8>* DynOS_Rooms_Parse(GfxData* aGfxData, DataNode<u8>* aNode) {
// Writing //
/////////////
void DynOS_Rooms_Write(FILE* aFile, GfxData* aGfxData, DataNode<u8> *aNode) {
void DynOS_Rooms_Write(BinFile* aFile, GfxData* aGfxData, DataNode<u8> *aNode) {
if (!aNode->mData) return;
// Name
WriteBytes<u8>(aFile, DATA_TYPE_ROOMS);
aFile->Write<u8>(DATA_TYPE_ROOMS);
aNode->mName.Write(aFile);
// Data
WriteBytes<u32>(aFile, aNode->mSize);
aFile->Write<u32>(aNode->mSize);
for (u32 i = 0; i != aNode->mSize; ++i) {
WriteBytes<u8>(aFile, aNode->mData[i]);
aFile->Write<u8>(aNode->mData[i]);
}
}
@ -42,17 +42,17 @@ void DynOS_Rooms_Write(FILE* aFile, GfxData* aGfxData, DataNode<u8> *aNode) {
// Reading //
/////////////
DataNode<u8>* DynOS_Rooms_Load(FILE *aFile, GfxData *aGfxData) {
DataNode<u8>* DynOS_Rooms_Load(BinFile *aFile, GfxData *aGfxData) {
DataNode<u8> *_Node = New<DataNode<u8>>();
// Name
_Node->mName.Read(aFile);
// Data
_Node->mSize = ReadBytes<u32>(aFile);
_Node->mSize = aFile->Read<u32>();
_Node->mData = New<u8>(_Node->mSize);
for (u32 i = 0; i != _Node->mSize; ++i) {
_Node->mData[i] = ReadBytes<u8>(aFile);
_Node->mData[i] = aFile->Read<u8>();
}
// Add it

View file

@ -151,11 +151,11 @@ DataNode<TexData>* DynOS_Tex_Parse(GfxData* aGfxData, DataNode<TexData>* aNode)
// Writing //
/////////////
void DynOS_Tex_Write(FILE* aFile, GfxData* aGfxData, DataNode<TexData> *aNode) {
void DynOS_Tex_Write(BinFile* aFile, GfxData* aGfxData, DataNode<TexData> *aNode) {
if (!aNode->mData) return;
// Header
WriteBytes<u8>(aFile, DATA_TYPE_TEXTURE);
aFile->Write<u8>(DATA_TYPE_TEXTURE);
aNode->mName.Write(aFile);
// Data
@ -169,7 +169,7 @@ void DynOS_Tex_Write(FILE* aFile, GfxData* aGfxData, DataNode<TexData> *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<u32>(aFile, TEX_REF_CODE);
aFile->Write<u32>(TEX_REF_CODE);
_Node->mName.Write(aFile);
return;
}
@ -179,7 +179,7 @@ void DynOS_Tex_Write(FILE* aFile, GfxData* aGfxData, DataNode<TexData> *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<u8>(_File, DATA_TYPE_TEXTURE);
_File->Write<u8>(DATA_TYPE_TEXTURE);
aName.Write(_File);
// Data
aTexData->mPngData.Write(_File);
fclose(_File);
BinFile::Close(_File);
return true;
}
// Write raw-texture
// Header
WriteBytes<u8>(_File, DATA_TYPE_TEXTURE_RAW);
_File->Write<u8>(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<s32>(_File, aTexData->mRawFormat);
WriteBytes<s32>(_File, aTexData->mRawSize);
WriteBytes<s32>(_File, aTexData->mRawWidth);
WriteBytes<s32>(_File, aTexData->mRawHeight);
_File->Write<s32>(aTexData->mRawFormat);
_File->Write<s32>(aTexData->mRawSize);
_File->Write<s32>(aTexData->mRawWidth);
_File->Write<s32>(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<TexData>* DynOS_Tex_Load(FILE *aFile, GfxData *aGfxData) {
DataNode<TexData>* DynOS_Tex_Load(BinFile *aFile, GfxData *aGfxData) {
DataNode<TexData> *_Node = New<DataNode<TexData>>();
// Name
@ -238,8 +238,8 @@ DataNode<TexData>* 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<u32>(aFile);
s32 _FileOffset = aFile->Offset();
u32 _TexRefCode = aFile->Read<u32>();
if (_TexRefCode == TEX_REF_CODE) {
// That's a duplicate, find the original node and copy its content
@ -256,7 +256,7 @@ DataNode<TexData>* 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<TexData>* DynOS_Tex_LoadFromBinary(const SysPath &aPackFolder, const Sy
// Load data from binary file
DataNode<TexData>* _TexNode = NULL;
FILE *_File = fopen(aFilename.c_str(), "rb");
BinFile *_File = BinFile::OpenR(aFilename.c_str());
if (!_File) { return NULL; }
u8 type = ReadBytes<u8>(_File);
u8 type = _File->Read<u8>();
if (type == DATA_TYPE_TEXTURE) {
// load png-texture
_TexNode = New<DataNode<TexData>>();
@ -306,7 +306,7 @@ DataNode<TexData>* 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<TexData>* 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<TexData>* DynOS_Tex_LoadFromBinary(const SysPath &aPackFolder, const Sy
_TexNode->mData = New<TexData>();
_TexNode->mName.Read(_File);
_TexNode->mData->mRawFormat = ReadBytes<s32>(_File);
_TexNode->mData->mRawSize = ReadBytes<s32>(_File);
_TexNode->mData->mRawWidth = ReadBytes<s32>(_File);
_TexNode->mData->mRawHeight = ReadBytes<s32>(_File);
_TexNode->mData->mRawFormat = _File->Read<s32>();
_TexNode->mData->mRawSize = _File->Read<s32>();
_TexNode->mData->mRawWidth = _File->Read<s32>();
_TexNode->mData->mRawHeight = _File->Read<s32>();
_TexNode->mData->mRawData.Read(_File);
fclose(_File);
BinFile::Close(_File);
if (aAddToPack) {
if (!_Pack) { _Pack = DynOS_Pack_Add(aPackFolder); }

View file

@ -36,15 +36,15 @@ DataNode<TexData*>* DynOS_TexList_Parse(GfxData* aGfxData, DataNode<TexData*>* a
// Writing //
/////////////
void DynOS_TexList_Write(FILE* aFile, GfxData* aGfxData, DataNode<TexData*> *aNode) {
void DynOS_TexList_Write(BinFile* aFile, GfxData* aGfxData, DataNode<TexData*> *aNode) {
if (!aNode->mData) return;
// Name
WriteBytes<u8>(aFile, DATA_TYPE_TEXTURE_LIST);
aFile->Write<u8>(DATA_TYPE_TEXTURE_LIST);
aNode->mName.Write(aFile);
// Data
WriteBytes<u32>(aFile, aNode->mSize);
aFile->Write<u32>(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<TexData*> *aNo
// Reading //
/////////////
DataNode<TexData*>* DynOS_TexList_Load(FILE *aFile, GfxData *aGfxData) {
DataNode<TexData*>* DynOS_TexList_Load(BinFile *aFile, GfxData *aGfxData) {
DataNode<TexData*> *_Node = New<DataNode<TexData*>>();
// Name
_Node->mName.Read(aFile);
// Data
_Node->mSize = ReadBytes<u32>(aFile);
_Node->mSize = aFile->Read<u32>();
_Node->mData = New<TexData*>(_Node->mSize);
for (u32 i = 0; i != _Node->mSize; ++i) {
u32 _Value = ReadBytes<u32>(aFile);
u32 _Value = aFile->Read<u32>();
void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _Value, &_Node->mFlags);
if (_Ptr == NULL) {
PrintError("Could not read texture in texlist");

View file

@ -85,17 +85,17 @@ DataNode<Trajectory>* DynOS_Trajectory_Parse(GfxData* aGfxData, DataNode<Traject
// Writing //
/////////////
void DynOS_Trajectory_Write(FILE* aFile, GfxData* aGfxData, DataNode<Trajectory> *aNode) {
void DynOS_Trajectory_Write(BinFile* aFile, GfxData* aGfxData, DataNode<Trajectory> *aNode) {
if (!aNode->mData) return;
// Name
WriteBytes<u8>(aFile, DATA_TYPE_TRAJECTORY);
aFile->Write<u8>(DATA_TYPE_TRAJECTORY);
aNode->mName.Write(aFile);
// Data
WriteBytes<u32>(aFile, aNode->mSize);
aFile->Write<u32>(aNode->mSize);
for (u32 i = 0; i != aNode->mSize; ++i) {
WriteBytes<Trajectory>(aFile, aNode->mData[i]);
aFile->Write<Trajectory>(aNode->mData[i]);
}
}
@ -103,17 +103,17 @@ void DynOS_Trajectory_Write(FILE* aFile, GfxData* aGfxData, DataNode<Trajectory>
// Reading //
/////////////
DataNode<Trajectory>* DynOS_Trajectory_Load(FILE *aFile, GfxData *aGfxData) {
DataNode<Trajectory>* DynOS_Trajectory_Load(BinFile *aFile, GfxData *aGfxData) {
DataNode<Trajectory> *_Node = New<DataNode<Trajectory>>();
// Name
_Node->mName.Read(aFile);
// Data
_Node->mSize = ReadBytes<u32>(aFile);
_Node->mSize = aFile->Read<u32>();
_Node->mData = New<Trajectory>(_Node->mSize);
for (u32 i = 0; i != _Node->mSize; ++i) {
_Node->mData[i] = ReadBytes<Trajectory>(aFile);
_Node->mData[i] = aFile->Read<Trajectory>();
}
// Add it

View file

@ -56,49 +56,49 @@ DataNode<Vtx>* DynOS_Vtx_Parse(GfxData* aGfxData, DataNode<Vtx>* aNode) {
// Writing //
/////////////
void DynOS_Vtx_Write(FILE* aFile, GfxData* aGfxData, DataNode<Vtx> *aNode) {
void DynOS_Vtx_Write(BinFile* aFile, GfxData* aGfxData, DataNode<Vtx> *aNode) {
if (!aNode->mData) return;
// Header
WriteBytes<u8>(aFile, DATA_TYPE_VERTEX);
aFile->Write<u8>(DATA_TYPE_VERTEX);
aNode->mName.Write(aFile);
// Data
bool shouldUseF32Vtx = ShouldUseF32Vtx(aNode);
if (shouldUseF32Vtx) {
WriteBytes<u32>(aFile, aNode->mSize + 1);
aFile->Write<u32>(aNode->mSize + 1);
// Write sentinel
WriteBytes<s16>(aFile, F32VTX_SENTINEL_0);
WriteBytes<s16>(aFile, F32VTX_SENTINEL_1);
WriteBytes<s16>(aFile, F32VTX_SENTINEL_2);
WriteBytes<s16>(aFile, 0);
WriteBytes<s16>(aFile, 0);
WriteBytes<s16>(aFile, 0);
WriteBytes<s8> (aFile, 0);
WriteBytes<s8> (aFile, 0);
WriteBytes<s8> (aFile, 0);
WriteBytes<u8> (aFile, 0);
aFile->Write<s16>(F32VTX_SENTINEL_0);
aFile->Write<s16>(F32VTX_SENTINEL_1);
aFile->Write<s16>(F32VTX_SENTINEL_2);
aFile->Write<s16>(0);
aFile->Write<s16>(0);
aFile->Write<s16>(0);
aFile->Write<s8> (0);
aFile->Write<s8> (0);
aFile->Write<s8> (0);
aFile->Write<u8> (0);
} else {
WriteBytes<u32>(aFile, aNode->mSize);
aFile->Write<u32>(aNode->mSize);
}
for (u32 i = 0; i != aNode->mSize; ++i) {
if (shouldUseF32Vtx) {
WriteBytes<f32>(aFile, aNode->mData[i].n.ob[0]);
WriteBytes<f32>(aFile, aNode->mData[i].n.ob[1]);
WriteBytes<f32>(aFile, aNode->mData[i].n.ob[2]);
aFile->Write<f32>(aNode->mData[i].n.ob[0]);
aFile->Write<f32>(aNode->mData[i].n.ob[1]);
aFile->Write<f32>(aNode->mData[i].n.ob[2]);
} else {
WriteBytes<s16>(aFile, aNode->mData[i].n.ob[0]);
WriteBytes<s16>(aFile, aNode->mData[i].n.ob[1]);
WriteBytes<s16>(aFile, aNode->mData[i].n.ob[2]);
aFile->Write<s16>(aNode->mData[i].n.ob[0]);
aFile->Write<s16>(aNode->mData[i].n.ob[1]);
aFile->Write<s16>(aNode->mData[i].n.ob[2]);
}
WriteBytes<s16>(aFile, aNode->mData[i].n.flag);
WriteBytes<s16>(aFile, aNode->mData[i].n.tc[0]);
WriteBytes<s16>(aFile, aNode->mData[i].n.tc[1]);
WriteBytes<s8> (aFile, aNode->mData[i].n.n[0]);
WriteBytes<s8> (aFile, aNode->mData[i].n.n[1]);
WriteBytes<s8> (aFile, aNode->mData[i].n.n[2]);
WriteBytes<u8> (aFile, aNode->mData[i].n.a);
aFile->Write<s16>(aNode->mData[i].n.flag);
aFile->Write<s16>(aNode->mData[i].n.tc[0]);
aFile->Write<s16>(aNode->mData[i].n.tc[1]);
aFile->Write<s8> (aNode->mData[i].n.n[0]);
aFile->Write<s8> (aNode->mData[i].n.n[1]);
aFile->Write<s8> (aNode->mData[i].n.n[2]);
aFile->Write<u8> (aNode->mData[i].n.a);
}
}
@ -106,7 +106,7 @@ void DynOS_Vtx_Write(FILE* aFile, GfxData* aGfxData, DataNode<Vtx> *aNode) {
// Reading //
/////////////
void DynOS_Vtx_Load(FILE *aFile, GfxData *aGfxData) {
void DynOS_Vtx_Load(BinFile *aFile, GfxData *aGfxData) {
DataNode<Vtx> *_Node = New<DataNode<Vtx>>();
// Name
@ -114,25 +114,25 @@ void DynOS_Vtx_Load(FILE *aFile, GfxData *aGfxData) {
// Data
bool isUsingF32Vtx = false;
_Node->mSize = ReadBytes<u32>(aFile);
_Node->mSize = aFile->Read<u32>();
_Node->mData = New<Vtx>(_Node->mSize);
for (u32 i = 0; i != _Node->mSize; ++i) {
if (isUsingF32Vtx) {
_Node->mData[i].n.ob[0] = ReadBytes<f32>(aFile);
_Node->mData[i].n.ob[1] = ReadBytes<f32>(aFile);
_Node->mData[i].n.ob[2] = ReadBytes<f32>(aFile);
_Node->mData[i].n.ob[0] = aFile->Read<f32>();
_Node->mData[i].n.ob[1] = aFile->Read<f32>();
_Node->mData[i].n.ob[2] = aFile->Read<f32>();
} else {
_Node->mData[i].n.ob[0] = ReadBytes<s16>(aFile);
_Node->mData[i].n.ob[1] = ReadBytes<s16>(aFile);
_Node->mData[i].n.ob[2] = ReadBytes<s16>(aFile);
_Node->mData[i].n.ob[0] = aFile->Read<s16>();
_Node->mData[i].n.ob[1] = aFile->Read<s16>();
_Node->mData[i].n.ob[2] = aFile->Read<s16>();
}
_Node->mData[i].n.flag = ReadBytes<s16>(aFile);
_Node->mData[i].n.tc[0] = ReadBytes<s16>(aFile);
_Node->mData[i].n.tc[1] = ReadBytes<s16>(aFile);
_Node->mData[i].n.n[0] = ReadBytes<s8> (aFile);
_Node->mData[i].n.n[1] = ReadBytes<s8> (aFile);
_Node->mData[i].n.n[2] = ReadBytes<s8> (aFile);
_Node->mData[i].n.a = ReadBytes<u8> (aFile);
_Node->mData[i].n.flag = aFile->Read<s16>();
_Node->mData[i].n.tc[0] = aFile->Read<s16>();
_Node->mData[i].n.tc[1] = aFile->Read<s16>();
_Node->mData[i].n.n[0] = aFile->Read<s8> ();
_Node->mData[i].n.n[1] = aFile->Read<s8> ();
_Node->mData[i].n.n[2] = aFile->Read<s8> ();
_Node->mData[i].n.a = aFile->Read<u8> ();
// Check sentinel on first vertex
if (!isUsingF32Vtx && i == 0 && IsUsingF32Vtx(_Node->mData[i].n.ob)) {

View file

@ -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"); }
}