Add Lights0 support to DynOS

This commit is contained in:
MysterD 2023-06-12 02:08:20 -07:00
parent f04be96225
commit 3331b5c98b
9 changed files with 137 additions and 1 deletions

View file

@ -47,6 +47,7 @@ enum {
DATA_TYPE_TEXTURE_RAW, DATA_TYPE_TEXTURE_RAW,
DATA_TYPE_BEHAVIOR_SCRIPT, DATA_TYPE_BEHAVIOR_SCRIPT,
DATA_TYPE_UNUSED, DATA_TYPE_UNUSED,
DATA_TYPE_LIGHT_0,
}; };
enum { enum {
@ -538,6 +539,7 @@ struct GfxData : NoCopy {
// Model data // Model data
DataNodes<Lights1> mLights; DataNodes<Lights1> mLights;
DataNodes<Lights0> mLight0s;
DataNodes<Light_t> mLightTs; DataNodes<Light_t> mLightTs;
DataNodes<Ambient_t> mAmbientTs; DataNodes<Ambient_t> mAmbientTs;
DataNodes<TexData> mTextures; DataNodes<TexData> mTextures;
@ -1028,6 +1030,10 @@ DataNode<Lights1>* DynOS_Lights_Parse(GfxData* aGfxData, DataNode<Lights1>* aNod
void DynOS_Lights_Write(BinFile* aFile, GfxData* aGfxData, DataNode<Lights1> *aNode); void DynOS_Lights_Write(BinFile* aFile, GfxData* aGfxData, DataNode<Lights1> *aNode);
void DynOS_Lights_Load(BinFile *aFile, GfxData *aGfxData); void DynOS_Lights_Load(BinFile *aFile, GfxData *aGfxData);
DataNode<Lights0>* DynOS_Light0_Parse(GfxData* aGfxData, DataNode<Lights0>* aNode);
void DynOS_Light0_Write(BinFile* aFile, GfxData* aGfxData, DataNode<Lights0> *aNode);
void DynOS_Light0_Load(BinFile *aFile, GfxData *aGfxData);
DataNode<Light_t>* DynOS_LightT_Parse(GfxData* aGfxData, DataNode<Light_t>* aNode); DataNode<Light_t>* DynOS_LightT_Parse(GfxData* aGfxData, DataNode<Light_t>* aNode);
void DynOS_LightT_Write(BinFile* aFile, GfxData* aGfxData, DataNode<Light_t> *aNode); void DynOS_LightT_Write(BinFile* aFile, GfxData* aGfxData, DataNode<Light_t> *aNode);
void DynOS_LightT_Load(BinFile *aFile, GfxData *aGfxData); void DynOS_LightT_Load(BinFile *aFile, GfxData *aGfxData);

View file

@ -26,6 +26,11 @@ static bool DynOS_Actor_WriteBinary(const SysPath &aOutputFilename, GfxData *aGf
DynOS_Lights_Write(_File, aGfxData, _Node); 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) { for (auto &_Node : aGfxData->mLightTs) {
if (_Node->mLoadIndex == i) { if (_Node->mLoadIndex == i) {
DynOS_LightT_Write(_File, aGfxData, _Node); 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;) { for (bool _Done = false; !_Done;) {
switch (_File->Read<u8>()) { switch (_File->Read<u8>()) {
case DATA_TYPE_LIGHT: DynOS_Lights_Load (_File, _GfxData); break; 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_LIGHT_T: DynOS_LightT_Load (_File, _GfxData); break;
case DATA_TYPE_AMBIENT_T: DynOS_AmbientT_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; case DATA_TYPE_TEXTURE: DynOS_Tex_Load (_File, _GfxData); break;
@ -220,6 +226,7 @@ static void DynOS_Actor_Generate(const SysPath &aPackFolder, Array<Pair<u64, Str
} }
// Clear data pointers // Clear data pointers
ClearGfxDataNodes(_GfxData->mLights); ClearGfxDataNodes(_GfxData->mLights);
ClearGfxDataNodes(_GfxData->mLight0s);
ClearGfxDataNodes(_GfxData->mLightTs); ClearGfxDataNodes(_GfxData->mLightTs);
ClearGfxDataNodes(_GfxData->mAmbientTs); ClearGfxDataNodes(_GfxData->mAmbientTs);
ClearGfxDataNodes(_GfxData->mTextures); ClearGfxDataNodes(_GfxData->mTextures);

View file

@ -422,6 +422,13 @@ static s64 ParseGfxSymbolArg(GfxData* aGfxData, DataNode<Gfx>* 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) { for (auto& _Node : aGfxData->mLightTs) {
// Light pointer // Light pointer
if (_Arg == _Node->mName) { if (_Arg == _Node->mName) {
@ -811,6 +818,15 @@ static void ParseGfxSymbol(GfxData* aGfxData, DataNode<Gfx>* aNode, Gfx*& aHead,
} }
// Complex symbols // 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") { if (_Symbol == "gsSPSetLights1") {
Lights1 *_Light = (Lights1 *) ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); Lights1 *_Light = (Lights1 *) ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, "");
gSPNumLights(aHead++, NUMLIGHTS_1); gSPNumLights(aHead++, NUMLIGHTS_1);

63
data/dynos_bin_light0.cpp Normal file
View file

@ -0,0 +1,63 @@
#include "dynos.cpp.h"
/////////////
// Parsing //
/////////////
DataNode<Lights0>* DynOS_Light0_Parse(GfxData* aGfxData, DataNode<Lights0>* 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<Lights0>();
*aNode->mData = gdSPDefLights0(ar, ag, ab);
aNode->mLoadIndex = aGfxData->mLoadIndex++;
return aNode;
}
/////////////
// Writing //
/////////////
void DynOS_Light0_Write(BinFile* aFile, GfxData* aGfxData, DataNode<Lights0> *aNode) {
if (!aNode->mData) return;
// Header
aFile->Write<u8>(DATA_TYPE_LIGHT_0);
aNode->mName.Write(aFile);
// Data
aFile->Write<Lights0>(*aNode->mData);
}
/////////////
// Reading //
/////////////
void DynOS_Light0_Load(BinFile *aFile, GfxData *aGfxData) {
DataNode<Lights0> *_Node = New<DataNode<Lights0>>();
// Name
_Node->mName.Read(aFile);
// Data
_Node->mData = New<Lights0>();
*_Node->mData = aFile->Read<Lights0>();
// Append
aGfxData->mLight0s.Add(_Node);
}

View file

@ -894,6 +894,11 @@ static bool DynOS_Lvl_WriteBinary(const SysPath &aOutputFilename, GfxData *aGfxD
DynOS_Lights_Write(_File, aGfxData, _Node); 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) { for (auto &_Node : aGfxData->mLightTs) {
if (_Node->mLoadIndex == i) { if (_Node->mLoadIndex == i) {
DynOS_LightT_Write(_File, aGfxData, _Node); 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;) { for (bool _Done = false; !_Done;) {
switch (_File->Read<u8>()) { switch (_File->Read<u8>()) {
case DATA_TYPE_LIGHT: DynOS_Lights_Load (_File, _GfxData); break; 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_LIGHT_T: DynOS_LightT_Load (_File, _GfxData); break;
case DATA_TYPE_AMBIENT_T: DynOS_AmbientT_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; case DATA_TYPE_TEXTURE: DynOS_Tex_Load (_File, _GfxData); break;
@ -1108,6 +1114,7 @@ static bool DynOS_Lvl_GeneratePack_Internal(const SysPath &aPackFolder, Array<Pa
// Clear data pointers // Clear data pointers
ClearLvlDataNodes(_GfxData->mLights); ClearLvlDataNodes(_GfxData->mLights);
ClearLvlDataNodes(_GfxData->mLight0s);
ClearLvlDataNodes(_GfxData->mLightTs); ClearLvlDataNodes(_GfxData->mLightTs);
ClearLvlDataNodes(_GfxData->mAmbientTs); ClearLvlDataNodes(_GfxData->mAmbientTs);
ClearLvlDataNodes(_GfxData->mTextures); ClearLvlDataNodes(_GfxData->mTextures);

View file

@ -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 // Light_ts
for (auto& _Node : aGfxData->mLightTs) { for (auto& _Node : aGfxData->mLightTs) {
if (&_Node->mData->col[0] == aPtr) { 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 // Light_ts
for (auto& _Node : aGfxData->mLightTs) { for (auto& _Node : aGfxData->mLightTs) {
if (_Node->mName == aPtrName) { if (_Node->mName == aPtrName) {

View file

@ -179,6 +179,8 @@ void DynOS_Read_Source(GfxData *aGfxData, const SysPath &aFilename) {
// Ignore struct keyword // Ignore struct keyword
} else if (_Buffer == "u64") { } else if (_Buffer == "u64") {
_DataType = DATA_TYPE_UNUSED; _DataType = DATA_TYPE_UNUSED;
} else if (_Buffer == "Lights0") {
_DataType = DATA_TYPE_LIGHT_0;
} else if (_Buffer == "Lights1") { } else if (_Buffer == "Lights1") {
_DataType = DATA_TYPE_LIGHT; _DataType = DATA_TYPE_LIGHT;
} else if (_Buffer == "Light_t") { } else if (_Buffer == "Light_t") {
@ -240,6 +242,7 @@ void DynOS_Read_Source(GfxData *aGfxData, const SysPath &aFilename) {
else if (_Buffer.Length() != 0) { else if (_Buffer.Length() != 0) {
switch (_DataType) { switch (_DataType) {
case DATA_TYPE_LIGHT: AppendNewNode(aGfxData, aGfxData->mLights, _Buffer, pDataName, pDataTokens); break; 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_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_AMBIENT_T: AppendNewNode(aGfxData, aGfxData->mAmbientTs, _Buffer, pDataName, pDataTokens); break;
case DATA_TYPE_TEXTURE: AppendNewNode(aGfxData, aGfxData->mTextures, _Buffer, pDataName, pDataTokens); break; case DATA_TYPE_TEXTURE: AppendNewNode(aGfxData, aGfxData->mTextures, _Buffer, pDataName, pDataTokens); break;

View file

@ -106,7 +106,14 @@ DataNode<TexData>* DynOS_Tex_Parse(GfxData* aGfxData, DataNode<TexData>* aNode)
if (i0 != -1) { if (i0 != -1) {
s32 i1 = aNode->mTokens[0].Find(".inc.c"); s32 i1 = aNode->mTokens[0].Find(".inc.c");
if (i1 == -1) { 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<TexData>();
aNode->mData = _Texture;
aNode->mLoadIndex = aGfxData->mLoadIndex++;
}
return aNode; return aNode;
} }

View file

@ -53,6 +53,10 @@ void DynOS_Gfx_Free(GfxData* aGfxData) {
Delete(_Node->mData); Delete(_Node->mData);
Delete(_Node); Delete(_Node);
} }
for (auto& _Node : aGfxData->mLight0s) {
Delete(_Node->mData);
Delete(_Node);
}
for (auto& _Node : aGfxData->mLightTs) { for (auto& _Node : aGfxData->mLightTs) {
Delete(_Node->mData); Delete(_Node->mData);
Delete(_Node); Delete(_Node);