From 483c32259db1da47bae23f6a9dae38e44cfe3084 Mon Sep 17 00:00:00 2001 From: MysterD Date: Mon, 12 Jun 2023 02:08:20 -0700 Subject: [PATCH] Add Lights0 support to DynOS --- data/dynos.cpp.h | 6 ++++ data/dynos_bin_actor.cpp | 7 +++++ data/dynos_bin_gfx.cpp | 16 ++++++++++ data/dynos_bin_light0.cpp | 63 ++++++++++++++++++++++++++++++++++++++ data/dynos_bin_lvl.cpp | 7 +++++ data/dynos_bin_pointer.cpp | 23 ++++++++++++++ data/dynos_bin_read.cpp | 3 ++ data/dynos_bin_tex.cpp | 9 +++++- data/dynos_bin_utils.cpp | 4 +++ 9 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 data/dynos_bin_light0.cpp diff --git a/data/dynos.cpp.h b/data/dynos.cpp.h index 33753d68..bc131a28 100644 --- a/data/dynos.cpp.h +++ b/data/dynos.cpp.h @@ -47,6 +47,7 @@ enum { DATA_TYPE_TEXTURE_RAW, DATA_TYPE_BEHAVIOR_SCRIPT, DATA_TYPE_UNUSED, + DATA_TYPE_LIGHT_0, }; enum { @@ -538,6 +539,7 @@ struct GfxData : NoCopy { // Model data DataNodes mLights; + DataNodes mLight0s; DataNodes mLightTs; DataNodes mAmbientTs; DataNodes mTextures; @@ -1028,6 +1030,10 @@ DataNode* DynOS_Lights_Parse(GfxData* aGfxData, DataNode* aNod void DynOS_Lights_Write(BinFile* aFile, GfxData* aGfxData, DataNode *aNode); void DynOS_Lights_Load(BinFile *aFile, GfxData *aGfxData); +DataNode* DynOS_Light0_Parse(GfxData* aGfxData, DataNode* aNode); +void DynOS_Light0_Write(BinFile* aFile, GfxData* aGfxData, DataNode *aNode); +void DynOS_Light0_Load(BinFile *aFile, GfxData *aGfxData); + DataNode* DynOS_LightT_Parse(GfxData* aGfxData, DataNode* aNode); void DynOS_LightT_Write(BinFile* aFile, GfxData* aGfxData, DataNode *aNode); void DynOS_LightT_Load(BinFile *aFile, GfxData *aGfxData); diff --git a/data/dynos_bin_actor.cpp b/data/dynos_bin_actor.cpp index 4bcb004b..9c224ecf 100644 --- a/data/dynos_bin_actor.cpp +++ b/data/dynos_bin_actor.cpp @@ -26,6 +26,11 @@ static bool DynOS_Actor_WriteBinary(const SysPath &aOutputFilename, GfxData *aGf DynOS_Lights_Write(_File, aGfxData, _Node); } } + for (auto &_Node : aGfxData->mLight0s) { + if (_Node->mLoadIndex == i) { + DynOS_Light0_Write(_File, aGfxData, _Node); + } + } for (auto &_Node : aGfxData->mLightTs) { if (_Node->mLoadIndex == i) { DynOS_LightT_Write(_File, aGfxData, _Node); @@ -92,6 +97,7 @@ GfxData *DynOS_Actor_LoadFromBinary(const SysPath &aPackFolder, const char *aAct for (bool _Done = false; !_Done;) { switch (_File->Read()) { case DATA_TYPE_LIGHT: DynOS_Lights_Load (_File, _GfxData); break; + case DATA_TYPE_LIGHT_0: DynOS_Light0_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; case DATA_TYPE_TEXTURE: DynOS_Tex_Load (_File, _GfxData); break; @@ -220,6 +226,7 @@ static void DynOS_Actor_Generate(const SysPath &aPackFolder, ArraymLights); + ClearGfxDataNodes(_GfxData->mLight0s); ClearGfxDataNodes(_GfxData->mLightTs); ClearGfxDataNodes(_GfxData->mAmbientTs); ClearGfxDataNodes(_GfxData->mTextures); diff --git a/data/dynos_bin_gfx.cpp b/data/dynos_bin_gfx.cpp index 2d5b164f..99cc0394 100644 --- a/data/dynos_bin_gfx.cpp +++ b/data/dynos_bin_gfx.cpp @@ -422,6 +422,13 @@ static s64 ParseGfxSymbolArg(GfxData* aGfxData, DataNode* aNode, u64* pToke } } + for (auto& _Node : aGfxData->mLight0s) { + // Light pointer + if (_Arg == _Node->mName) { + return (s64) DynOS_Light0_Parse(aGfxData, _Node)->mData; + } + } + for (auto& _Node : aGfxData->mLightTs) { // Light pointer if (_Arg == _Node->mName) { @@ -811,6 +818,15 @@ static void ParseGfxSymbol(GfxData* aGfxData, DataNode* aNode, Gfx*& aHead, } // Complex symbols + if (_Symbol == "gsSPSetLights0") { + Lights0 *_Light = (Lights0 *) ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + gSPNumLights(aHead++, NUMLIGHTS_0); + aGfxData->mPointerList.Add(aHead); + gSPLight(aHead++, &_Light->l[0], 1); + aGfxData->mPointerList.Add(aHead); + gSPLight(aHead++, &_Light->a, 2); + return; + } if (_Symbol == "gsSPSetLights1") { Lights1 *_Light = (Lights1 *) ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); gSPNumLights(aHead++, NUMLIGHTS_1); diff --git a/data/dynos_bin_light0.cpp b/data/dynos_bin_light0.cpp new file mode 100644 index 00000000..d26548ae --- /dev/null +++ b/data/dynos_bin_light0.cpp @@ -0,0 +1,63 @@ +#include "dynos.cpp.h" + + ///////////// + // Parsing // +///////////// + +DataNode* DynOS_Light0_Parse(GfxData* aGfxData, DataNode* aNode) { + if (aNode->mData) return aNode; + + // Check tokens count + if (aNode->mTokens.Count() < 4) { + PrintDataError(" ERROR: %s: not enough data", aNode->mName.begin()); + return aNode; + } + + // Parse def token + if (aNode->mTokens[0] != "gdSPDefLights0") { + PrintDataError(" ERROR: Invalid def token: should be gdSPDefLights0, is %s", aNode->mTokens[0].begin()); + return aNode; + } + + // Parse data tokens + u8 ar = (u8) aNode->mTokens[1].ParseInt(); + u8 ag = (u8) aNode->mTokens[2].ParseInt(); + u8 ab = (u8) aNode->mTokens[3].ParseInt(); + aNode->mData = New(); + *aNode->mData = gdSPDefLights0(ar, ag, ab); + aNode->mLoadIndex = aGfxData->mLoadIndex++; + return aNode; +} + + ///////////// + // Writing // +///////////// + +void DynOS_Light0_Write(BinFile* aFile, GfxData* aGfxData, DataNode *aNode) { + if (!aNode->mData) return; + + // Header + aFile->Write(DATA_TYPE_LIGHT_0); + aNode->mName.Write(aFile); + + // Data + aFile->Write(*aNode->mData); +} + + ///////////// + // Reading // +///////////// + +void DynOS_Light0_Load(BinFile *aFile, GfxData *aGfxData) { + DataNode *_Node = New>(); + + // Name + _Node->mName.Read(aFile); + + // Data + _Node->mData = New(); + *_Node->mData = aFile->Read(); + + // Append + aGfxData->mLight0s.Add(_Node); +} diff --git a/data/dynos_bin_lvl.cpp b/data/dynos_bin_lvl.cpp index 8e02fe2c..05a12a03 100644 --- a/data/dynos_bin_lvl.cpp +++ b/data/dynos_bin_lvl.cpp @@ -894,6 +894,11 @@ static bool DynOS_Lvl_WriteBinary(const SysPath &aOutputFilename, GfxData *aGfxD DynOS_Lights_Write(_File, aGfxData, _Node); } } + for (auto &_Node : aGfxData->mLight0s) { + if (_Node->mLoadIndex == i) { + DynOS_Light0_Write(_File, aGfxData, _Node); + } + } for (auto &_Node : aGfxData->mLightTs) { if (_Node->mLoadIndex == i) { DynOS_LightT_Write(_File, aGfxData, _Node); @@ -1014,6 +1019,7 @@ GfxData *DynOS_Lvl_LoadFromBinary(const SysPath &aFilename, const char *aLevelNa for (bool _Done = false; !_Done;) { switch (_File->Read()) { case DATA_TYPE_LIGHT: DynOS_Lights_Load (_File, _GfxData); break; + case DATA_TYPE_LIGHT_0: DynOS_Light0_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; case DATA_TYPE_TEXTURE: DynOS_Tex_Load (_File, _GfxData); break; @@ -1108,6 +1114,7 @@ static bool DynOS_Lvl_GeneratePack_Internal(const SysPath &aPackFolder, ArraymLights); + ClearLvlDataNodes(_GfxData->mLight0s); ClearLvlDataNodes(_GfxData->mLightTs); ClearLvlDataNodes(_GfxData->mAmbientTs); ClearLvlDataNodes(_GfxData->mTextures); diff --git a/data/dynos_bin_pointer.cpp b/data/dynos_bin_pointer.cpp index de3a94ca..fae27bdb 100644 --- a/data/dynos_bin_pointer.cpp +++ b/data/dynos_bin_pointer.cpp @@ -21,6 +21,16 @@ static PointerData GetDataFromPointer(const void* aPtr, GfxData* aGfxData) { } } + // Light0s + for (auto& _Node : aGfxData->mLight0s) { + if (&_Node->mData->l[0] == aPtr) { // Light *, not Lights1 * + return { _Node->mName, 1 }; + } + if (&_Node->mData->a == aPtr) { // Ambient *, not Lights1 * + return { _Node->mName, 2 }; + } + } + // Light_ts for (auto& _Node : aGfxData->mLightTs) { if (&_Node->mData->col[0] == aPtr) { @@ -246,6 +256,19 @@ static void *GetPointerFromData(GfxData *aGfxData, const String &aPtrName, u32 a } } + // Light0s + for (auto& _Node : aGfxData->mLight0s) { + if (_Node->mName == aPtrName) { + if (aPtrData == 1) { + return (void *) &_Node->mData->l[0]; + } + if (aPtrData == 2) { + return (void *) &_Node->mData->a; + } + sys_fatal("Unknown Light type: %u", aPtrData); + } + } + // Light_ts for (auto& _Node : aGfxData->mLightTs) { if (_Node->mName == aPtrName) { diff --git a/data/dynos_bin_read.cpp b/data/dynos_bin_read.cpp index 4cb85f45..0a0ef53c 100644 --- a/data/dynos_bin_read.cpp +++ b/data/dynos_bin_read.cpp @@ -179,6 +179,8 @@ void DynOS_Read_Source(GfxData *aGfxData, const SysPath &aFilename) { // Ignore struct keyword } else if (_Buffer == "u64") { _DataType = DATA_TYPE_UNUSED; + } else if (_Buffer == "Lights0") { + _DataType = DATA_TYPE_LIGHT_0; } else if (_Buffer == "Lights1") { _DataType = DATA_TYPE_LIGHT; } else if (_Buffer == "Light_t") { @@ -240,6 +242,7 @@ void DynOS_Read_Source(GfxData *aGfxData, const SysPath &aFilename) { else if (_Buffer.Length() != 0) { switch (_DataType) { case DATA_TYPE_LIGHT: AppendNewNode(aGfxData, aGfxData->mLights, _Buffer, pDataName, pDataTokens); break; + case DATA_TYPE_LIGHT_0: AppendNewNode(aGfxData, aGfxData->mLight0s, _Buffer, pDataName, pDataTokens); break; case DATA_TYPE_LIGHT_T: AppendNewNode(aGfxData, aGfxData->mLightTs, _Buffer, pDataName, pDataTokens); break; case DATA_TYPE_AMBIENT_T: AppendNewNode(aGfxData, aGfxData->mAmbientTs, _Buffer, pDataName, pDataTokens); break; case DATA_TYPE_TEXTURE: AppendNewNode(aGfxData, aGfxData->mTextures, _Buffer, pDataName, pDataTokens); break; diff --git a/data/dynos_bin_tex.cpp b/data/dynos_bin_tex.cpp index bb023a03..e10fbe7c 100644 --- a/data/dynos_bin_tex.cpp +++ b/data/dynos_bin_tex.cpp @@ -106,7 +106,14 @@ DataNode* DynOS_Tex_Parse(GfxData* aGfxData, DataNode* aNode) if (i0 != -1) { s32 i1 = aNode->mTokens[0].Find(".inc.c"); if (i1 == -1) { - PrintDataError(" ERROR: %s: missing .inc.c in String %s", aNode->mName.begin(), aNode->mTokens[0].begin()); + if (strstr(aNode->mName.begin(), "_pal_") == NULL) { + PrintDataError(" ERROR: %s: missing .inc.c in String %s", aNode->mName.begin(), aNode->mTokens[0].begin()); + } else { + // hack for pal textures to be "found" + TexData* _Texture = New(); + aNode->mData = _Texture; + aNode->mLoadIndex = aGfxData->mLoadIndex++; + } return aNode; } diff --git a/data/dynos_bin_utils.cpp b/data/dynos_bin_utils.cpp index e46fc49f..c0be6817 100644 --- a/data/dynos_bin_utils.cpp +++ b/data/dynos_bin_utils.cpp @@ -53,6 +53,10 @@ void DynOS_Gfx_Free(GfxData* aGfxData) { Delete(_Node->mData); Delete(_Node); } + for (auto& _Node : aGfxData->mLight0s) { + Delete(_Node->mData); + Delete(_Node); + } for (auto& _Node : aGfxData->mLightTs) { Delete(_Node->mData); Delete(_Node);