diff --git a/data/dynos_bin_vtx.cpp b/data/dynos_bin_vtx.cpp index 86c19ae42..d5ba5e9b7 100644 --- a/data/dynos_bin_vtx.cpp +++ b/data/dynos_bin_vtx.cpp @@ -1,5 +1,27 @@ #include "dynos.cpp.h" +#define F32VTX_SENTINEL_0 0x3346 +#define F32VTX_SENTINEL_1 0x5632 +#define F32VTX_SENTINEL_2 0x5854 + +static inline bool ShouldUseF32Vtx(DataNode* aNode) { + for (u32 i = 0; i != aNode->mSize; ++i) { + for (u32 j = 0; j != 3; ++j) { + if (aNode->mData[i].n.ob[j] < -0x7FFF || + aNode->mData[i].n.ob[j] > +0x7FFF) { + return true; + } + } + } + return false; +} + +static inline bool IsUsingF32Vtx(Vec3f ob) { + return ob[0] == F32VTX_SENTINEL_0 && + ob[1] == F32VTX_SENTINEL_1 && + ob[2] == F32VTX_SENTINEL_2; +} + ///////////// // Parsing // ///////////// @@ -39,11 +61,34 @@ void DynOS_Vtx_Write(FILE* aFile, GfxData* aGfxData, DataNode *aNode) { aNode->mName.Write(aFile); // Data - WriteBytes(aFile, aNode->mSize); + bool shouldUseF32Vtx = ShouldUseF32Vtx(aNode); + if (shouldUseF32Vtx) { + WriteBytes(aFile, 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); + } else { + WriteBytes(aFile, aNode->mSize); + } for (u32 i = 0; i != aNode->mSize; ++i) { - WriteBytes(aFile, aNode->mData[i].n.ob[0]); - WriteBytes(aFile, aNode->mData[i].n.ob[1]); - WriteBytes(aFile, aNode->mData[i].n.ob[2]); + 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]); + } 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]); + } WriteBytes(aFile, aNode->mData[i].n.flag); WriteBytes(aFile, aNode->mData[i].n.tc[0]); WriteBytes(aFile, aNode->mData[i].n.tc[1]); @@ -65,19 +110,32 @@ void DynOS_Vtx_Load(FILE *aFile, GfxData *aGfxData) { _Node->mName.Read(aFile); // Data + bool isUsingF32Vtx = false; _Node->mSize = ReadBytes(aFile); _Node->mData = New(_Node->mSize); for (u32 i = 0; i != _Node->mSize; ++i) { - _Node->mData[i].n.ob[0] = ReadBytes(aFile); - _Node->mData[i].n.ob[1] = ReadBytes(aFile); - _Node->mData[i].n.ob[2] = ReadBytes(aFile); + 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); + } 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.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.a = ReadBytes (aFile); + + // Check sentinel on first vertex + if (!isUsingF32Vtx && i == 0 && IsUsingF32Vtx(_Node->mData[i].n.ob)) { + _Node->mSize--; i--; + isUsingF32Vtx = true; + } } // Append