From 2f56594e45b9546af1dcc9817de80a74e5387bd5 Mon Sep 17 00:00:00 2001 From: MysterD Date: Fri, 1 Apr 2022 17:19:26 -0700 Subject: [PATCH] DynOS level parsing - phase 1 --- data/dynos.cpp.h | 16 +- .../{dynos_col_read.cpp => dynos_bin_col.cpp} | 52 +- data/dynos_bin_geo.cpp | 361 ++++ data/dynos_bin_gfx.cpp | 855 ++++++++++ data/dynos_bin_lights.cpp | 36 + .../{dynos_lvl_read.cpp => dynos_bin_lvl.cpp} | 720 +++++++- data/dynos_bin_macro_object.cpp | 466 +++++ data/dynos_bin_tex.cpp | 110 ++ data/dynos_bin_utils.cpp | 157 ++ data/dynos_bin_vtx.cpp | 28 + data/dynos_gfx_read.cpp | 1507 +---------------- include/behavior_data.h | 7 +- 12 files changed, 2802 insertions(+), 1513 deletions(-) rename data/{dynos_col_read.cpp => dynos_bin_col.cpp} (90%) create mode 100644 data/dynos_bin_geo.cpp create mode 100644 data/dynos_bin_gfx.cpp create mode 100644 data/dynos_bin_lights.cpp rename data/{dynos_lvl_read.cpp => dynos_bin_lvl.cpp} (59%) create mode 100644 data/dynos_bin_macro_object.cpp create mode 100644 data/dynos_bin_tex.cpp create mode 100644 data/dynos_bin_utils.cpp create mode 100644 data/dynos_bin_vtx.cpp diff --git a/data/dynos.cpp.h b/data/dynos.cpp.h index f47e3b79a..5dd95d61e 100644 --- a/data/dynos.cpp.h +++ b/data/dynos.cpp.h @@ -28,6 +28,7 @@ enum { DATA_TYPE_GFXDYNCMD, DATA_TYPE_COLLISION, DATA_TYPE_LEVEL_SCRIPT, + DATA_TYPE_MACRO_OBJECT, DATA_TYPE_UNUSED, }; @@ -424,6 +425,7 @@ struct GfxData : NoCopy { DataNodes mGeoLayouts; DataNodes mCollisions; DataNodes mLevelScripts; + DataNodes mMacroObjects; // Animation data Array *> mAnimValues; @@ -712,7 +714,6 @@ const char *DynOS_Warp_GetParamName(s32 aLevel, s32 aIndex); // Collisions // -bool DynOS_Col_GeneratePack(const SysPath &aPackFolder, Array> _ActorsFolders, GfxData *_GfxData); bool DynOS_Col_WriteBinary(const SysPath &aOutputFilename, GfxData *aGfxData, DataNode* _Node); DataNode* DynOS_Col_LoadFromBinary(const SysPath &aPackFolder, const char *aCollisionName); @@ -729,5 +730,18 @@ bool DynOS_Lvl_GeneratePack_Internal(const SysPath &aPackFolder, Array* DynOS_Geo_Parse(GfxData* aGfxData, DataNode* aNode, bool aDisplayPercent); +DataNode* DynOS_Gfx_Parse(GfxData* aGfxData, DataNode* aNode); +DataNode* DynOS_Vtx_Parse(GfxData* aGfxData, DataNode* aNode); +DataNode* DynOS_Tex_Parse(GfxData* aGfxData, DataNode* aNode); +DataNode* DynOS_Lights_Parse(GfxData* aGfxData, DataNode* aNode); +DataNode* DynOS_Col_Parse(GfxData* aGfxData, DataNode* aNode, bool aDisplayPercent); +DataNode* DynOS_Lvl_Parse(GfxData* aGfxData, DataNode* aNode, bool aDisplayPercent); +DataNode* DynOS_MacroObject_Parse(GfxData* aGfxData, DataNode* aNode, bool aDisplayPercent); + +void DynOS_Tex_ConvertTextureDataToPng(GfxData *aGfxData, TexData* aTexture); +s64 DynOS_RecursiveDescent_Parse(const char* expr, bool* success); + #endif #endif diff --git a/data/dynos_col_read.cpp b/data/dynos_bin_col.cpp similarity index 90% rename from data/dynos_col_read.cpp rename to data/dynos_bin_col.cpp index ac2e3654e..427172563 100644 --- a/data/dynos_col_read.cpp +++ b/data/dynos_bin_col.cpp @@ -15,9 +15,9 @@ static void ClearColDataNodes(DataNodes &aDataNodes) { } } -// -// Parse collision file -// + ///////////// + // Parsing // +///////////// #define COLLISION_SIZE_PER_TOKEN 4 @@ -384,7 +384,7 @@ static void ParseCollisionSymbol(GfxData* aGfxData, DataNode* aNode, PrintError(" ERROR: Unknown col symbol: %s", _Symbol.begin()); } -static DataNode* ParseCollisionData(GfxData* aGfxData, DataNode* aNode, bool aDisplayPercent) { +DataNode* DynOS_Col_Parse(GfxData* aGfxData, DataNode* aNode, bool aDisplayPercent) { if (aNode->mData) return aNode; // Collision data @@ -400,47 +400,3 @@ static DataNode* ParseCollisionData(GfxData* aGfxData, DataNodemLoadIndex = aGfxData->mLoadIndex++; return aNode; } - -static DataNode *GetCollision(GfxData *aGfxData, const String& aGeoRoot) { - for (DataNode *_Node : aGfxData->mCollisions) { - if (_Node->mName == aGeoRoot) { - return _Node; - } - } - return NULL; -} - -bool DynOS_Col_GeneratePack(const SysPath &aPackFolder, Array> _ActorsFolders, GfxData *_GfxData) { - bool generated = false; - for (auto &_ColNode : _GfxData->mCollisions) { - String _ColRootName = _ColNode->mName; - DataNode *_ColRoot = GetCollision(_GfxData, _ColRootName); - if (_ColRoot != NULL) { - - // 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())) { - continue; - } - - // Init - _GfxData->mErrorCount = 0; - _GfxData->mLoadIndex = 0; - - // Parse data - PrintNoNewLine("%s.col: Model identifier: %X - Processing... ", _ColRootName.begin(), _GfxData->mModelIdentifier); - ParseCollisionData(_GfxData, _ColRoot, true); - - // Write if no error - if (_GfxData->mErrorCount == 0) { - DynOS_Col_WriteBinary(_ColFilename, _GfxData, _ColRoot); - } else { - Print(" %u error(s): Unable to parse data", _GfxData->mErrorCount); - } - // Clear data pointers - ClearColDataNodes(_GfxData->mCollisions); - generated = true; - } - } - return generated; -} diff --git a/data/dynos_bin_geo.cpp b/data/dynos_bin_geo.cpp new file mode 100644 index 000000000..dbbc12f2a --- /dev/null +++ b/data/dynos_bin_geo.cpp @@ -0,0 +1,361 @@ +#include "dynos.cpp.h" +extern "C" { +#include "sm64.h" +#include "geo_commands.h" +#include "src/game/camera.h" +#include "src/game/envfx_snow.h" +} + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnarrowing" + + ///////////// + // Parsing // +///////////// + +#define GEO_LAYOUT_SIZE_PER_TOKEN 4 + +#define geo_constant(x) if (_Arg == #x) { return (s64) (x); } +static s64 ParseGeoSymbolArg(GfxData* aGfxData, DataNode* aNode, u64& aTokenIndex) { + const String& _Arg = aNode->mTokens[aTokenIndex++]; + + // Geo functions + void *_GeoFunctionPtr = DynOS_Geo_GetFunctionPointerFromName(_Arg); + if (_GeoFunctionPtr != NULL) { + return (s64) _GeoFunctionPtr; + } + + // Layer constants + geo_constant(LAYER_FORCE); + geo_constant(LAYER_OPAQUE); + geo_constant(LAYER_OPAQUE_DECAL); + geo_constant(LAYER_OPAQUE_INTER); + geo_constant(LAYER_ALPHA); + geo_constant(LAYER_TRANSPARENT); + geo_constant(LAYER_TRANSPARENT_DECAL); + geo_constant(LAYER_TRANSPARENT_INTER); + + // Background constants + geo_constant(BACKGROUND_OCEAN_SKY); + geo_constant(BACKGROUND_FLAMING_SKY); + geo_constant(BACKGROUND_UNDERWATER_CITY); + geo_constant(BACKGROUND_BELOW_CLOUDS); + geo_constant(BACKGROUND_SNOW_MOUNTAINS); + geo_constant(BACKGROUND_DESERT); + geo_constant(BACKGROUND_HAUNTED); + geo_constant(BACKGROUND_GREEN_SKY); + geo_constant(BACKGROUND_ABOVE_CLOUDS); + geo_constant(BACKGROUND_PURPLE_SKY); + + // Shadow constants + geo_constant(SHADOW_CIRCLE_9_VERTS); + geo_constant(SHADOW_CIRCLE_4_VERTS); + geo_constant(SHADOW_CIRCLE_4_VERTS_FLAT_UNUSED); + geo_constant(SHADOW_SQUARE_PERMANENT); + geo_constant(SHADOW_SQUARE_SCALABLE); + geo_constant(SHADOW_SQUARE_TOGGLABLE); + geo_constant(SHADOW_RECTANGLE_HARDCODED_OFFSET); + geo_constant(SHADOW_CIRCLE_PLAYER); + + // Envfx constants + geo_constant(ENVFX_MODE_NONE); + geo_constant(ENVFX_SNOW_NORMAL); + geo_constant(ENVFX_SNOW_WATER); + geo_constant(ENVFX_SNOW_BLIZZARD); + geo_constant(ENVFX_BUBBLE_START); + geo_constant(ENVFX_FLOWERS); + geo_constant(ENVFX_LAVA_BUBBLES); + geo_constant(ENVFX_WHIRLPOOL_BUBBLES); + geo_constant(ENVFX_JETSTREAM_BUBBLES); + + + // Camera constants + geo_constant(CAMERA_MODE_NONE); + geo_constant(CAMERA_MODE_RADIAL); + geo_constant(CAMERA_MODE_OUTWARD_RADIAL); + geo_constant(CAMERA_MODE_BEHIND_MARIO); + geo_constant(CAMERA_MODE_CLOSE); + geo_constant(CAMERA_MODE_C_UP); + geo_constant(CAMERA_MODE_WATER_SURFACE); + geo_constant(CAMERA_MODE_SLIDE_HOOT); + geo_constant(CAMERA_MODE_INSIDE_CANNON); + geo_constant(CAMERA_MODE_BOSS_FIGHT); + geo_constant(CAMERA_MODE_PARALLEL_TRACKING); + geo_constant(CAMERA_MODE_FIXED); + geo_constant(CAMERA_MODE_8_DIRECTIONS); + geo_constant(CAMERA_MODE_FREE_ROAM); + geo_constant(CAMERA_MODE_SPIRAL_STAIRS); + + // Other constants + geo_constant(NULL); + geo_constant(SCREEN_WIDTH); + geo_constant(SCREEN_HEIGHT); + geo_constant(SCREEN_WIDTH/2); + geo_constant(SCREEN_HEIGHT/2); + + // Display lists + for (auto& _Node : aGfxData->mDisplayLists) { + if (_Arg == _Node->mName) { + return (s64) DynOS_Gfx_Parse(aGfxData, _Node); + } + } + + // Geo layouts + for (auto& _Node : aGfxData->mGeoLayouts) { + if (_Arg == _Node->mName) { + return (s64) DynOS_Geo_Parse(aGfxData, _Node, false)->mData; + } + } + + // Integers + s32 x; + if ((_Arg[1] == 'x' && sscanf(_Arg.begin(), "%x", &x) == 1) || (sscanf(_Arg.begin(), "%d", &x) == 1)) { + return (s64) x; + } + + // Unknown + PrintError(" ERROR: Unknown geo arg: %s", _Arg.begin()); + return 0; +} + +#define geo_symbol_0(symb) \ + if (_Symbol == #symb) { \ + GeoLayout _Gl[] = { symb() }; \ + memcpy(aHead, _Gl, sizeof(_Gl)); \ + aHead += (sizeof(_Gl) / sizeof(_Gl[0])); \ + return; \ + } + +#define geo_symbol_1(symb, n) \ + if (_Symbol == #symb) { \ + s64 _Arg0 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + if (n != 0) { aGfxData->mPointerList.Add(aHead + n); } \ + GeoLayout _Gl[] = { symb(_Arg0) }; \ + memcpy(aHead, _Gl, sizeof(_Gl)); \ + aHead += (sizeof(_Gl) / sizeof(_Gl[0])); \ + return; \ + } + +#define geo_symbol_2(symb, n) \ + if (_Symbol == #symb) { \ + s64 _Arg0 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg1 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + if (n != 0) { aGfxData->mPointerList.Add(aHead + n); } \ + GeoLayout _Gl[] = { symb(_Arg0, _Arg1) }; \ + memcpy(aHead, _Gl, sizeof(_Gl)); \ + aHead += (sizeof(_Gl) / sizeof(_Gl[0])); \ + return; \ + } + +#define geo_symbol_3(symb, n) \ + if (_Symbol == #symb) { \ + s64 _Arg0 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg1 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg2 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + if (n != 0) { aGfxData->mPointerList.Add(aHead + n); } \ + GeoLayout _Gl[] = { symb(_Arg0, _Arg1, _Arg2) }; \ + memcpy(aHead, _Gl, sizeof(_Gl)); \ + aHead += (sizeof(_Gl) / sizeof(_Gl[0])); \ + return; \ + } + +#define geo_symbol_4(symb, n) \ + if (_Symbol == #symb) { \ + s64 _Arg0 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg1 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg2 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg3 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + if (n != 0) { aGfxData->mPointerList.Add(aHead + n); } \ + GeoLayout _Gl[] = { symb(_Arg0, _Arg1, _Arg2, _Arg3) }; \ + memcpy(aHead, _Gl, sizeof(_Gl)); \ + aHead += (sizeof(_Gl) / sizeof(_Gl[0])); \ + return; \ + } + +#define geo_symbol_5(symb, n) \ + if (_Symbol == #symb) { \ + s64 _Arg0 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg1 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg2 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg3 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg4 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + if (n != 0) { aGfxData->mPointerList.Add(aHead + n); } \ + GeoLayout _Gl[] = { symb(_Arg0, _Arg1, _Arg2, _Arg3, _Arg4) }; \ + memcpy(aHead, _Gl, sizeof(_Gl)); \ + aHead += (sizeof(_Gl) / sizeof(_Gl[0])); \ + return; \ + } + +#define geo_symbol_6(symb, n) \ + if (_Symbol == #symb) { \ + s64 _Arg0 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg1 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg2 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg3 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg4 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg5 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + if (n != 0) { aGfxData->mPointerList.Add(aHead + n); } \ + GeoLayout _Gl[] = { symb(_Arg0, _Arg1, _Arg2, _Arg3, _Arg4, _Arg5) }; \ + memcpy(aHead, _Gl, sizeof(_Gl)); \ + aHead += (sizeof(_Gl) / sizeof(_Gl[0])); \ + return; \ + } + +#define geo_symbol_7(symb, n) \ + if (_Symbol == #symb) { \ + s64 _Arg0 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg1 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg2 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg3 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg4 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg5 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg6 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + if (n != 0) { aGfxData->mPointerList.Add(aHead + n); } \ + GeoLayout _Gl[] = { symb(_Arg0, _Arg1, _Arg2, _Arg3, _Arg4, _Arg5, _Arg6) }; \ + memcpy(aHead, _Gl, sizeof(_Gl)); \ + aHead += (sizeof(_Gl) / sizeof(_Gl[0])); \ + return; \ + } + +#define geo_symbol_8(symb, n) \ + if (_Symbol == #symb) { \ + s64 _Arg0 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg1 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg2 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg3 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg4 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg5 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg6 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg7 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ + if (n != 0) { aGfxData->mPointerList.Add(aHead + n); } \ + GeoLayout _Gl[] = { symb(_Arg0, _Arg1, _Arg2, _Arg3, _Arg4, _Arg5, _Arg6, _Arg7) }; \ + memcpy(aHead, _Gl, sizeof(_Gl)); \ + aHead += (sizeof(_Gl) / sizeof(_Gl[0])); \ + return; \ + } + +static void ParseGeoSymbol(GfxData* aGfxData, DataNode* aNode, GeoLayout*& aHead, u64& aTokenIndex, Array& aSwitchNodes) { + const String& _Symbol = aNode->mTokens[aTokenIndex++]; + + // Restore context after each command if inside a switch + if (!aSwitchNodes.Empty() && !aGfxData->mGeoNodeStack.Empty()) { + aGfxData->mGfxContext = aGfxData->mGeoNodeStack[aGfxData->mGeoNodeStack.Count() - 1]; + } + + geo_symbol_1(GEO_BRANCH_AND_LINK, 1); + geo_symbol_0(GEO_END); + geo_symbol_2(GEO_BRANCH, 1); + geo_symbol_0(GEO_RETURN); + geo_symbol_5(GEO_NODE_SCREEN_AREA, 0); + geo_symbol_1(GEO_NODE_ORTHO, 0); + geo_symbol_3(GEO_CAMERA_FRUSTUM, 0); + geo_symbol_4(GEO_CAMERA_FRUSTUM_WITH_FUNC, 2); + geo_symbol_0(GEO_NODE_START); + geo_symbol_1(GEO_ZBUFFER, 0); + geo_symbol_2(GEO_RENDER_RANGE, 0); + geo_symbol_8(GEO_CAMERA, 4); + geo_symbol_7(GEO_TRANSLATE_ROTATE, 0); + geo_symbol_8(GEO_TRANSLATE_ROTATE_WITH_DL, 4); + geo_symbol_4(GEO_TRANSLATE, 0); + geo_symbol_5(GEO_TRANSLATE_WITH_DL, 2); + geo_symbol_4(GEO_ROTATE, 0); + geo_symbol_5(GEO_ROTATE_WITH_DL, 2); + geo_symbol_2(GEO_ROTATE_Y, 0); + geo_symbol_3(GEO_ROTATE_Y_WITH_DL, 1); + geo_symbol_4(GEO_TRANSLATE_NODE, 0); + geo_symbol_5(GEO_TRANSLATE_NODE_WITH_DL, 2); + geo_symbol_4(GEO_ROTATION_NODE, 0); + geo_symbol_5(GEO_ROTATION_NODE_WITH_DL, 2); + geo_symbol_5(GEO_ANIMATED_PART, 2); + geo_symbol_4(GEO_BILLBOARD_WITH_PARAMS, 0); + geo_symbol_5(GEO_BILLBOARD_WITH_PARAMS_AND_DL, 2); + geo_symbol_0(GEO_BILLBOARD); + geo_symbol_2(GEO_DISPLAY_LIST, 1); + geo_symbol_3(GEO_SHADOW, 0); + geo_symbol_0(GEO_RENDER_OBJ); + geo_symbol_2(GEO_ASM, 1); + geo_symbol_2(GEO_BACKGROUND, 1); + geo_symbol_1(GEO_BACKGROUND_COLOR, 0); + geo_symbol_0(GEO_NOP_1A); + geo_symbol_5(GEO_HELD_OBJECT, 2); + geo_symbol_2(GEO_SCALE, 0); + geo_symbol_3(GEO_SCALE_WITH_DL, 2); + geo_symbol_0(GEO_NOP_1E); + geo_symbol_0(GEO_NOP_1F); + geo_symbol_1(GEO_CULLING_RADIUS, 0); + + // Switch node + if (_Symbol == "GEO_SWITCH_CASE") { + + // Start a switch + aSwitchNodes.Add(0); + + s64 _Arg0 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); + s64 _Arg1 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); + aGfxData->mPointerList.Add(aHead + 1); + GeoLayout _Gl[] = { GEO_SWITCH_CASE(_Arg0, _Arg1) }; + memcpy(aHead, _Gl, sizeof(_Gl)); + aHead += (sizeof(_Gl) / sizeof(_Gl[0])); + return; + } + + // Open node + if (_Symbol == "GEO_OPEN_NODE") { + + // We're inside a switch + if (!aSwitchNodes.Empty()) { + aSwitchNodes[aSwitchNodes.Count() - 1]++; + } + + // Push context + aGfxData->mGeoNodeStack.Add(aGfxData->mGfxContext); + + *(aHead++) = GEO_OPEN_NODE(); + return; + } + + // Close node + if (_Symbol == "GEO_CLOSE_NODE") { + + // Are we still inside a switch? + if (!aSwitchNodes.Empty()) { + aSwitchNodes[aSwitchNodes.Count() - 1]--; + + // We're not anymore + if (aSwitchNodes[aSwitchNodes.Count() - 1] == 0) { + aSwitchNodes.Pop(); + } + } + + // Pop context + if (!aGfxData->mGeoNodeStack.Empty()) { + aGfxData->mGfxContext = aGfxData->mGeoNodeStack[aGfxData->mGeoNodeStack.Count() - 1]; + aGfxData->mGeoNodeStack.Pop(); + } + + *(aHead++) = GEO_CLOSE_NODE(); + return; + } + + // Unknown + PrintError(" ERROR: Unknown geo symbol: %s", _Symbol.begin()); +} + +DataNode* DynOS_Geo_Parse(GfxData* aGfxData, DataNode* aNode, bool aDisplayPercent) { + if (aNode->mData) return aNode; + + // Geo layout data + aNode->mData = New(aNode->mTokens.Count() * GEO_LAYOUT_SIZE_PER_TOKEN); + GeoLayout* _Head = aNode->mData; + Array _SwitchNodes; + for (u64 _TokenIndex = 0; _TokenIndex < aNode->mTokens.Count();) { // Don't increment _TokenIndex here! + ParseGeoSymbol(aGfxData, aNode, _Head, _TokenIndex, _SwitchNodes); + if (aDisplayPercent && aGfxData->mErrorCount == 0) { PrintNoNewLine("%3d%%\b\b\b\b", (s32) (_TokenIndex * 100) / aNode->mTokens.Count()); } + } + if (aDisplayPercent && aGfxData->mErrorCount == 0) { Print("100%%"); } + aNode->mSize = (u32)(_Head - aNode->mData); + aNode->mLoadIndex = aGfxData->mLoadIndex++; + return aNode; +} + +#pragma GCC diagnostic pop diff --git a/data/dynos_bin_gfx.cpp b/data/dynos_bin_gfx.cpp new file mode 100644 index 000000000..c0c845357 --- /dev/null +++ b/data/dynos_bin_gfx.cpp @@ -0,0 +1,855 @@ +#include "dynos.cpp.h" +extern "C" { +#include +#include "sm64.h" +} + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnarrowing" + +#define DISPLAY_LIST_SIZE_PER_TOKEN 4 + + ///////////// + // Parsing // +///////////// + +#define gfx_constant(x) if (_Arg == #x) { return (s64) (x); } +static s64 ParseGfxSymbolArg(GfxData* aGfxData, DataNode* aNode, u64* pTokenIndex, const char *aPrefix) { + assert(aPrefix != NULL); + String _Token = (pTokenIndex != NULL ? aNode->mTokens[(*pTokenIndex)++] : ""); + String _Arg("%s%s", aPrefix, _Token.begin()); + + // Offset + s32 _Offset = 0; + s32 _Plus = _Arg.Find('+'); + if (_Plus != -1) { + _Offset = _Arg.SubString(_Plus + 1).ParseInt(); + _Arg = _Arg.SubString(0, _Plus); + } + + // Constants + gfx_constant(NULL); + gfx_constant(G_ON); + gfx_constant(G_OFF); + + // Combine modes + gfx_constant(G_CCMUX_COMBINED); + gfx_constant(G_CCMUX_TEXEL0); + gfx_constant(G_CCMUX_TEXEL1); + gfx_constant(G_CCMUX_PRIMITIVE); + gfx_constant(G_CCMUX_SHADE); + gfx_constant(G_CCMUX_ENVIRONMENT); + gfx_constant(G_CCMUX_CENTER); + gfx_constant(G_CCMUX_SCALE); + gfx_constant(G_CCMUX_COMBINED_ALPHA); + gfx_constant(G_CCMUX_TEXEL0_ALPHA); + gfx_constant(G_CCMUX_TEXEL1_ALPHA); + gfx_constant(G_CCMUX_PRIMITIVE_ALPHA); + gfx_constant(G_CCMUX_SHADE_ALPHA); + gfx_constant(G_CCMUX_ENV_ALPHA); + gfx_constant(G_CCMUX_LOD_FRACTION); + gfx_constant(G_CCMUX_PRIM_LOD_FRAC); + gfx_constant(G_CCMUX_NOISE); + gfx_constant(G_CCMUX_K4); + gfx_constant(G_CCMUX_K5); + gfx_constant(G_CCMUX_1); + gfx_constant(G_CCMUX_0); + gfx_constant(G_ACMUX_COMBINED); + gfx_constant(G_ACMUX_TEXEL0); + gfx_constant(G_ACMUX_TEXEL1); + gfx_constant(G_ACMUX_PRIMITIVE); + gfx_constant(G_ACMUX_SHADE); + gfx_constant(G_ACMUX_ENVIRONMENT); + gfx_constant(G_ACMUX_LOD_FRACTION); + gfx_constant(G_ACMUX_PRIM_LOD_FRAC); + gfx_constant(G_ACMUX_1); + gfx_constant(G_ACMUX_0); + + // Light constants + gfx_constant(NUMLIGHTS_0); + gfx_constant(NUMLIGHTS_1); + gfx_constant(NUMLIGHTS_2); + gfx_constant(NUMLIGHTS_3); + gfx_constant(NUMLIGHTS_4); + gfx_constant(NUMLIGHTS_5); + gfx_constant(NUMLIGHTS_6); + gfx_constant(NUMLIGHTS_7); + + // Image formats + gfx_constant(G_IM_FMT_RGBA); + gfx_constant(G_IM_FMT_YUV); + gfx_constant(G_IM_FMT_CI); + gfx_constant(G_IM_FMT_IA); + gfx_constant(G_IM_FMT_I); + gfx_constant(G_IM_SIZ_4b); + gfx_constant(G_IM_SIZ_8b); + gfx_constant(G_IM_SIZ_16b); + gfx_constant(G_IM_SIZ_32b); + gfx_constant(G_IM_SIZ_DD); + + // Image constants + gfx_constant(G_IM_SIZ_4b_BYTES); + gfx_constant(G_IM_SIZ_4b_TILE_BYTES); + gfx_constant(G_IM_SIZ_4b_LINE_BYTES); + gfx_constant(G_IM_SIZ_8b_BYTES); + gfx_constant(G_IM_SIZ_8b_TILE_BYTES); + gfx_constant(G_IM_SIZ_8b_LINE_BYTES); + gfx_constant(G_IM_SIZ_16b_BYTES); + gfx_constant(G_IM_SIZ_16b_TILE_BYTES); + gfx_constant(G_IM_SIZ_16b_LINE_BYTES); + gfx_constant(G_IM_SIZ_32b_BYTES); + gfx_constant(G_IM_SIZ_32b_TILE_BYTES); + gfx_constant(G_IM_SIZ_32b_LINE_BYTES); + gfx_constant(G_IM_SIZ_4b_LOAD_BLOCK); + gfx_constant(G_IM_SIZ_8b_LOAD_BLOCK); + gfx_constant(G_IM_SIZ_16b_LOAD_BLOCK); + gfx_constant(G_IM_SIZ_32b_LOAD_BLOCK); + gfx_constant(G_IM_SIZ_4b_SHIFT); + gfx_constant(G_IM_SIZ_8b_SHIFT); + gfx_constant(G_IM_SIZ_16b_SHIFT); + gfx_constant(G_IM_SIZ_32b_SHIFT); + gfx_constant(G_IM_SIZ_4b_INCR); + gfx_constant(G_IM_SIZ_8b_INCR); + gfx_constant(G_IM_SIZ_16b_INCR); + gfx_constant(G_IM_SIZ_32b_INCR); + + // Tile formats + gfx_constant(G_TX_RENDERTILE); + gfx_constant(G_TX_LOADTILE); + gfx_constant(G_TX_NOMIRROR); + gfx_constant(G_TX_WRAP); + gfx_constant(G_TX_MIRROR); + gfx_constant(G_TX_CLAMP); + gfx_constant(G_TX_NOMASK); + gfx_constant(G_TX_NOLOD); + gfx_constant(G_TX_WRAP|G_TX_NOMIRROR); + gfx_constant(G_TX_WRAP|G_TX_MIRROR); + gfx_constant(G_TX_CLAMP|G_TX_NOMIRROR); + gfx_constant(G_TX_CLAMP|G_TX_MIRROR); + + // Render modes + gfx_constant(G_RM_AA_ZB_OPA_SURF); + gfx_constant(G_RM_AA_ZB_OPA_SURF2); + gfx_constant(G_RM_AA_ZB_XLU_SURF); + gfx_constant(G_RM_AA_ZB_XLU_SURF2); + gfx_constant(G_RM_AA_ZB_OPA_DECAL); + gfx_constant(G_RM_AA_ZB_OPA_DECAL2); + gfx_constant(G_RM_AA_ZB_XLU_DECAL); + gfx_constant(G_RM_AA_ZB_XLU_DECAL2); + gfx_constant(G_RM_AA_ZB_OPA_INTER); + gfx_constant(G_RM_AA_ZB_OPA_INTER2); + gfx_constant(G_RM_AA_ZB_XLU_INTER); + gfx_constant(G_RM_AA_ZB_XLU_INTER2); + gfx_constant(G_RM_AA_ZB_XLU_LINE); + gfx_constant(G_RM_AA_ZB_XLU_LINE2); + gfx_constant(G_RM_AA_ZB_DEC_LINE); + gfx_constant(G_RM_AA_ZB_DEC_LINE2); + gfx_constant(G_RM_AA_ZB_TEX_EDGE); + gfx_constant(G_RM_AA_ZB_TEX_EDGE2); + gfx_constant(G_RM_AA_ZB_TEX_INTER); + gfx_constant(G_RM_AA_ZB_TEX_INTER2); + gfx_constant(G_RM_AA_ZB_SUB_SURF); + gfx_constant(G_RM_AA_ZB_SUB_SURF2); + gfx_constant(G_RM_AA_ZB_PCL_SURF); + gfx_constant(G_RM_AA_ZB_PCL_SURF2); + gfx_constant(G_RM_AA_ZB_OPA_TERR); + gfx_constant(G_RM_AA_ZB_OPA_TERR2); + gfx_constant(G_RM_AA_ZB_TEX_TERR); + gfx_constant(G_RM_AA_ZB_TEX_TERR2); + gfx_constant(G_RM_AA_ZB_SUB_TERR); + gfx_constant(G_RM_AA_ZB_SUB_TERR2); + gfx_constant(G_RM_RA_ZB_OPA_SURF); + gfx_constant(G_RM_RA_ZB_OPA_SURF2); + gfx_constant(G_RM_RA_ZB_OPA_DECAL); + gfx_constant(G_RM_RA_ZB_OPA_DECAL2); + gfx_constant(G_RM_RA_ZB_OPA_INTER); + gfx_constant(G_RM_RA_ZB_OPA_INTER2); + gfx_constant(G_RM_AA_OPA_SURF); + gfx_constant(G_RM_AA_OPA_SURF2); + gfx_constant(G_RM_AA_XLU_SURF); + gfx_constant(G_RM_AA_XLU_SURF2); + gfx_constant(G_RM_AA_XLU_LINE); + gfx_constant(G_RM_AA_XLU_LINE2); + gfx_constant(G_RM_AA_DEC_LINE); + gfx_constant(G_RM_AA_DEC_LINE2); + gfx_constant(G_RM_AA_TEX_EDGE); + gfx_constant(G_RM_AA_TEX_EDGE2); + gfx_constant(G_RM_AA_SUB_SURF); + gfx_constant(G_RM_AA_SUB_SURF2); + gfx_constant(G_RM_AA_PCL_SURF); + gfx_constant(G_RM_AA_PCL_SURF2); + gfx_constant(G_RM_AA_OPA_TERR); + gfx_constant(G_RM_AA_OPA_TERR2); + gfx_constant(G_RM_AA_TEX_TERR); + gfx_constant(G_RM_AA_TEX_TERR2); + gfx_constant(G_RM_AA_SUB_TERR); + gfx_constant(G_RM_AA_SUB_TERR2); + gfx_constant(G_RM_RA_OPA_SURF); + gfx_constant(G_RM_RA_OPA_SURF2); + gfx_constant(G_RM_ZB_OPA_SURF); + gfx_constant(G_RM_ZB_OPA_SURF2); + gfx_constant(G_RM_ZB_XLU_SURF); + gfx_constant(G_RM_ZB_XLU_SURF2); + gfx_constant(G_RM_ZB_OPA_DECAL); + gfx_constant(G_RM_ZB_OPA_DECAL2); + gfx_constant(G_RM_ZB_XLU_DECAL); + gfx_constant(G_RM_ZB_XLU_DECAL2); + gfx_constant(G_RM_ZB_CLD_SURF); + gfx_constant(G_RM_ZB_CLD_SURF2); + gfx_constant(G_RM_ZB_OVL_SURF); + gfx_constant(G_RM_ZB_OVL_SURF2); + gfx_constant(G_RM_ZB_PCL_SURF); + gfx_constant(G_RM_ZB_PCL_SURF2); + gfx_constant(G_RM_OPA_SURF); + gfx_constant(G_RM_OPA_SURF2); + gfx_constant(G_RM_XLU_SURF); + gfx_constant(G_RM_XLU_SURF2); + gfx_constant(G_RM_CLD_SURF); + gfx_constant(G_RM_CLD_SURF2); + gfx_constant(G_RM_TEX_EDGE); + gfx_constant(G_RM_TEX_EDGE2); + gfx_constant(G_RM_PCL_SURF); + gfx_constant(G_RM_PCL_SURF2); + gfx_constant(G_RM_ADD); + gfx_constant(G_RM_ADD2); + gfx_constant(G_RM_NOOP); + gfx_constant(G_RM_NOOP2); + gfx_constant(G_RM_VISCVG); + gfx_constant(G_RM_VISCVG2); + gfx_constant(G_RM_OPA_CI); + gfx_constant(G_RM_OPA_CI2); + gfx_constant(G_RM_CUSTOM_AA_ZB_XLU_SURF); + gfx_constant(G_RM_CUSTOM_AA_ZB_XLU_SURF2); + gfx_constant(G_RM_FOG_SHADE_A); + gfx_constant(G_RM_FOG_PRIM_A); + gfx_constant(G_RM_PASS); + + // Geometry modes + gfx_constant(G_ZBUFFER); + gfx_constant(G_SHADE); + gfx_constant(G_TEXTURE_ENABLE); + gfx_constant(G_SHADING_SMOOTH); + gfx_constant(G_CULL_FRONT); + gfx_constant(G_CULL_BACK); + gfx_constant(G_CULL_BOTH); + gfx_constant(G_FOG); + gfx_constant(G_LIGHTING); + gfx_constant(G_TEXTURE_GEN); + gfx_constant(G_TEXTURE_GEN_LINEAR); + gfx_constant(G_LOD); + gfx_constant(G_CLIPPING); + gfx_constant(G_FOG|G_TEXTURE_GEN); + gfx_constant(G_LIGHTING|G_CULL_BACK); + gfx_constant(G_LIGHTING|G_SHADING_SMOOTH); + gfx_constant(G_CULL_BACK|G_SHADING_SMOOTH); + gfx_constant(G_LIGHTING|G_CULL_BACK|G_SHADING_SMOOTH); + gfx_constant(G_TEXTURE_GEN|G_SHADING_SMOOTH); + gfx_constant(G_TEXTURE_GEN|G_LIGHTING|G_CULL_BACK); + gfx_constant(G_TEXTURE_GEN|G_CULL_BACK|G_SHADING_SMOOTH); + + // Alpha modes + gfx_constant(G_AC_NONE); + gfx_constant(G_AC_THRESHOLD); + gfx_constant(G_AC_DITHER); + + // Other modes + gfx_constant(G_MDSFT_ALPHACOMPARE); + gfx_constant(G_MDSFT_ZSRCSEL); + gfx_constant(G_MDSFT_RENDERMODE); + gfx_constant(G_MDSFT_BLENDER); + gfx_constant(G_MDSFT_BLENDMASK); + gfx_constant(G_MDSFT_ALPHADITHER); + gfx_constant(G_MDSFT_RGBDITHER); + gfx_constant(G_MDSFT_COMBKEY); + gfx_constant(G_MDSFT_TEXTCONV); + gfx_constant(G_MDSFT_TEXTFILT); + gfx_constant(G_MDSFT_TEXTLUT); + gfx_constant(G_MDSFT_TEXTLOD); + gfx_constant(G_MDSFT_TEXTDETAIL); + gfx_constant(G_MDSFT_TEXTPERSP); + gfx_constant(G_MDSFT_CYCLETYPE); + gfx_constant(G_MDSFT_COLORDITHER); + gfx_constant(G_MDSFT_PIPELINE); + gfx_constant(G_PM_1PRIMITIVE); + gfx_constant(G_PM_NPRIMITIVE); + gfx_constant(G_CYC_1CYCLE); + gfx_constant(G_CYC_2CYCLE); + gfx_constant(G_CYC_COPY); + gfx_constant(G_CYC_FILL); + gfx_constant(G_TP_NONE); + gfx_constant(G_TP_PERSP); + gfx_constant(G_TD_CLAMP); + gfx_constant(G_TD_SHARPEN); + gfx_constant(G_TD_DETAIL); + gfx_constant(G_TL_TILE); + gfx_constant(G_TL_LOD); + gfx_constant(G_TT_NONE); + gfx_constant(G_TT_RGBA16); + gfx_constant(G_TT_IA16); + gfx_constant(G_TF_POINT); + gfx_constant(G_TF_AVERAGE); + gfx_constant(G_TF_BILERP); + gfx_constant(G_TC_CONV); + gfx_constant(G_TC_FILTCONV); + gfx_constant(G_TC_FILT); + gfx_constant(G_CK_NONE); + gfx_constant(G_CK_KEY); + gfx_constant(G_CD_MAGICSQ); + gfx_constant(G_CD_BAYER); + gfx_constant(G_CD_NOISE); + gfx_constant(G_CD_DISABLE); + gfx_constant(G_CD_ENABLE); + gfx_constant(G_AD_PATTERN); + gfx_constant(G_AD_NOTPATTERN); + gfx_constant(G_AD_NOISE); + gfx_constant(G_AD_DISABLE); + gfx_constant(G_AC_NONE); + gfx_constant(G_AC_THRESHOLD); + gfx_constant(G_AC_DITHER); + gfx_constant(G_ZS_PIXEL); + gfx_constant(G_ZS_PRIM); + + // Common values + gfx_constant((4-1)<mLights) { + + // Light pointer + if (_Arg == _Node->mName) { + return (s64) DynOS_Lights_Parse(aGfxData, _Node)->mData; + } + + // Ambient pointer + String _Ambient("&%s.a", _Node->mName.begin()); + if (_Arg == _Ambient) { + return (s64) &(DynOS_Lights_Parse(aGfxData, _Node)->mData->a); + } + + // Diffuse pointer + String _Diffuse("&%s.l", _Node->mName.begin()); + if (_Arg == _Diffuse) { + return (s64) &(DynOS_Lights_Parse(aGfxData, _Node)->mData->l[0]); + } + } + + // Textures + for (auto& _Node : aGfxData->mTextures) { + if (_Arg == _Node->mName) { + return (s64) DynOS_Tex_Parse(aGfxData, _Node); + } + } + + // Vertex arrays + for (auto& _Node : aGfxData->mVertices) { + if (_Arg == _Node->mName) { + return (s64) (DynOS_Vtx_Parse(aGfxData, _Node)->mData + _Offset); + } + } + + // Display lists + for (auto& _Node : aGfxData->mDisplayLists) { + if (_Arg == _Node->mName) { + return (s64) DynOS_Gfx_Parse(aGfxData, _Node); + } + } + + // Integers + s32 x; + if ((_Arg[1] == 'x' && sscanf(_Arg.begin(), "%x", &x) == 1) || (sscanf(_Arg.begin(), "%d", &x) == 1)) { + return (s64) x; + } + + // Unknown + PrintError(" ERROR: Unknown gfx arg: %s", _Arg.begin()); + return 0; +} + +#define gfx_symbol_0(symb) \ + if (_Symbol == #symb) { \ + Gfx _Gfx[] = { symb() }; \ + memcpy(aHead, _Gfx, sizeof(_Gfx)); \ + aHead += (sizeof(_Gfx) / sizeof(_Gfx[0])); \ + return; \ + } + +#define gfx_symbol_1(symb, ptr) \ + if (_Symbol == #symb) { \ + s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + if (ptr) { aGfxData->mPointerList.Add(aHead); } \ + Gfx _Gfx[] = { symb(_Arg0) }; \ + memcpy(aHead, _Gfx, sizeof(_Gfx)); \ + aHead += (sizeof(_Gfx) / sizeof(_Gfx[0])); \ + return; \ + } + +#define gfx_symbol_2(symb, ptr) \ + if (_Symbol == #symb) { \ + s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + s64 _Arg1 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + if (ptr) { aGfxData->mPointerList.Add(aHead); } \ + Gfx _Gfx[] = { symb(_Arg0, _Arg1) }; \ + memcpy(aHead, _Gfx, sizeof(_Gfx)); \ + aHead += (sizeof(_Gfx) / sizeof(_Gfx[0])); \ + return; \ + } + +#define gfx_symbol_3(symb, ptr) \ + if (_Symbol == #symb) { \ + s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + s64 _Arg1 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + s64 _Arg2 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + if (ptr) { aGfxData->mPointerList.Add(aHead); } \ + Gfx _Gfx[] = { symb(_Arg0, _Arg1, _Arg2) }; \ + memcpy(aHead, _Gfx, sizeof(_Gfx)); \ + aHead += (sizeof(_Gfx) / sizeof(_Gfx[0])); \ + return; \ + } + +#define gfx_symbol_4(symb) \ + if (_Symbol == #symb) { \ + s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + s64 _Arg1 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + s64 _Arg2 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + s64 _Arg3 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + Gfx _Gfx[] = { symb(_Arg0, _Arg1, _Arg2, _Arg3) }; \ + memcpy(aHead, _Gfx, sizeof(_Gfx)); \ + aHead += (sizeof(_Gfx) / sizeof(_Gfx[0])); \ + return; \ + } + +#define gfx_symbol_5(symb) \ + if (_Symbol == #symb) { \ + s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + s64 _Arg1 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + s64 _Arg2 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + s64 _Arg3 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + s64 _Arg4 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + Gfx _Gfx[] = { symb(_Arg0, _Arg1, _Arg2, _Arg3, _Arg4) }; \ + memcpy(aHead, _Gfx, sizeof(_Gfx)); \ + aHead += (sizeof(_Gfx) / sizeof(_Gfx[0])); \ + return; \ + } + +#define gfx_symbol_6(symb) \ + if (_Symbol == #symb) { \ + s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + s64 _Arg1 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + s64 _Arg2 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + s64 _Arg3 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + s64 _Arg4 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + s64 _Arg5 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + Gfx _Gfx[] = { symb(_Arg0, _Arg1, _Arg2, _Arg3, _Arg4, _Arg5) }; \ + memcpy(aHead, _Gfx, sizeof(_Gfx)); \ + aHead += (sizeof(_Gfx) / sizeof(_Gfx[0])); \ + return; \ + } + +#define gfx_symbol_7(symb) \ + if (_Symbol == #symb) { \ + s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + s64 _Arg1 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + s64 _Arg2 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + s64 _Arg3 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + s64 _Arg4 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + s64 _Arg5 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + s64 _Arg6 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + Gfx _Gfx[] = { symb(_Arg0, _Arg1, _Arg2, _Arg3, _Arg4, _Arg5, _Arg6) }; \ + memcpy(aHead, _Gfx, sizeof(_Gfx)); \ + aHead += (sizeof(_Gfx) / sizeof(_Gfx[0])); \ + return; \ + } + +#define gfx_symbol_8(symb) \ + if (_Symbol == #symb) { \ + s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + s64 _Arg1 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + s64 _Arg2 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + s64 _Arg3 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + s64 _Arg4 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + s64 _Arg5 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + s64 _Arg6 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + s64 _Arg7 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ + Gfx _Gfx[] = { symb(_Arg0, _Arg1, _Arg2, _Arg3, _Arg4, _Arg5, _Arg6, _Arg7) }; \ + memcpy(aHead, _Gfx, sizeof(_Gfx)); \ + aHead += (sizeof(_Gfx) / sizeof(_Gfx[0])); \ + return; \ + } + +#define gfx_arg_with_suffix(argname, suffix) \ + const String& argname##_token = aNode->mTokens[aTokenIndex]; \ + String _Token##suffix = String("%s%s", argname##_token.begin(), #suffix); \ + s64 argname = ParseGfxSymbolArg(aGfxData, aNode, NULL, _Token##suffix.begin()); \ + +#define STR_VALUE_2(...) #__VA_ARGS__ +#define STR_VALUE(...) STR_VALUE_2(__VA_ARGS__) +#define gfx_set_combine_mode_arg(x) if (_Arg == #x) { return String("%s", STR_VALUE(x)); } +static String ConvertSetCombineModeArgToString(GfxData *aGfxData, const String& _Arg) { + gfx_set_combine_mode_arg(G_CC_PRIMITIVE); + gfx_set_combine_mode_arg(G_CC_SHADE); + gfx_set_combine_mode_arg(G_CC_MODULATEI); + gfx_set_combine_mode_arg(G_CC_MODULATEIDECALA); + gfx_set_combine_mode_arg(G_CC_MODULATEIFADE); + gfx_set_combine_mode_arg(G_CC_MODULATERGB); + gfx_set_combine_mode_arg(G_CC_MODULATERGBDECALA); + gfx_set_combine_mode_arg(G_CC_MODULATERGBFADE); + gfx_set_combine_mode_arg(G_CC_MODULATEIA); + gfx_set_combine_mode_arg(G_CC_MODULATEIFADEA); + gfx_set_combine_mode_arg(G_CC_MODULATEFADE); + gfx_set_combine_mode_arg(G_CC_MODULATERGBA); + gfx_set_combine_mode_arg(G_CC_MODULATERGBFADEA); + gfx_set_combine_mode_arg(G_CC_MODULATEI_PRIM); + gfx_set_combine_mode_arg(G_CC_MODULATEIA_PRIM); + gfx_set_combine_mode_arg(G_CC_MODULATEIDECALA_PRIM); + gfx_set_combine_mode_arg(G_CC_MODULATERGB_PRIM); + gfx_set_combine_mode_arg(G_CC_MODULATERGBA_PRIM); + gfx_set_combine_mode_arg(G_CC_MODULATERGBDECALA_PRIM); + gfx_set_combine_mode_arg(G_CC_FADE); + gfx_set_combine_mode_arg(G_CC_FADEA); + gfx_set_combine_mode_arg(G_CC_DECALRGB); + gfx_set_combine_mode_arg(G_CC_DECALRGBA); + gfx_set_combine_mode_arg(G_CC_DECALFADE); + gfx_set_combine_mode_arg(G_CC_DECALFADEA); + gfx_set_combine_mode_arg(G_CC_BLENDI); + gfx_set_combine_mode_arg(G_CC_BLENDIA); + gfx_set_combine_mode_arg(G_CC_BLENDIDECALA); + gfx_set_combine_mode_arg(G_CC_BLENDRGBA); + gfx_set_combine_mode_arg(G_CC_BLENDRGBDECALA); + gfx_set_combine_mode_arg(G_CC_BLENDRGBFADEA); + gfx_set_combine_mode_arg(G_CC_ADDRGB); + gfx_set_combine_mode_arg(G_CC_ADDRGBDECALA); + gfx_set_combine_mode_arg(G_CC_ADDRGBFADE); + gfx_set_combine_mode_arg(G_CC_REFLECTRGB); + gfx_set_combine_mode_arg(G_CC_REFLECTRGBDECALA); + gfx_set_combine_mode_arg(G_CC_HILITERGB); + gfx_set_combine_mode_arg(G_CC_HILITERGBA); + gfx_set_combine_mode_arg(G_CC_HILITERGBDECALA); + gfx_set_combine_mode_arg(G_CC_SHADEDECALA); + gfx_set_combine_mode_arg(G_CC_SHADEFADEA); + gfx_set_combine_mode_arg(G_CC_BLENDPE); + gfx_set_combine_mode_arg(G_CC_BLENDPEDECALA); + gfx_set_combine_mode_arg(_G_CC_BLENDPE); + gfx_set_combine_mode_arg(_G_CC_BLENDPEDECALA); + gfx_set_combine_mode_arg(_G_CC_TWOCOLORTEX); + gfx_set_combine_mode_arg(_G_CC_SPARSEST); + gfx_set_combine_mode_arg(G_CC_TEMPLERP); + gfx_set_combine_mode_arg(G_CC_TRILERP); + gfx_set_combine_mode_arg(G_CC_INTERFERENCE); + gfx_set_combine_mode_arg(G_CC_1CYUV2RGB); + gfx_set_combine_mode_arg(G_CC_YUV2RGB); + gfx_set_combine_mode_arg(G_CC_PASS2); + gfx_set_combine_mode_arg(G_CC_MODULATEI2); + gfx_set_combine_mode_arg(G_CC_MODULATEIA2); + gfx_set_combine_mode_arg(G_CC_MODULATERGB2); + gfx_set_combine_mode_arg(G_CC_MODULATERGBA2); + gfx_set_combine_mode_arg(G_CC_MODULATEI_PRIM2); + gfx_set_combine_mode_arg(G_CC_MODULATEIA_PRIM2); + gfx_set_combine_mode_arg(G_CC_MODULATERGB_PRIM2); + gfx_set_combine_mode_arg(G_CC_MODULATERGBA_PRIM2); + gfx_set_combine_mode_arg(G_CC_DECALRGB2); + gfx_set_combine_mode_arg(G_CC_BLENDI2); + gfx_set_combine_mode_arg(G_CC_BLENDIA2); + gfx_set_combine_mode_arg(G_CC_CHROMA_KEY2); + gfx_set_combine_mode_arg(G_CC_HILITERGB2); + gfx_set_combine_mode_arg(G_CC_HILITERGBA2); + gfx_set_combine_mode_arg(G_CC_HILITERGBDECALA2); + gfx_set_combine_mode_arg(G_CC_HILITERGBPASSA2); + PrintError(" ERROR: Unknown gfx gsDPSetCombineMode arg: %s", _Arg.begin()); + return ""; +} + +static Array ParseGfxSetCombineMode(GfxData* aGfxData, DataNode* aNode, u64* pTokenIndex) { + String _Buffer = ConvertSetCombineModeArgToString(aGfxData, aNode->mTokens[(*pTokenIndex)++]); + Array _Args; + String _Token; + for (u64 i = 0, n = _Buffer.Length(); i <= n; ++i) { + if (i == n || _Buffer[i] == ' ' || _Buffer[i] == '\t' || _Buffer[i] == ',') { + if (_Token.Length() != 0) { + String _Arg("%s%s", (_Args.Count() < 4 ? "G_CCMUX_" : "G_ACMUX_"), _Token.begin()); + _Args.Add(ParseGfxSymbolArg(aGfxData, aNode, NULL, _Arg.begin())); + _Token.Clear(); + } + } else { + _Token.Add(_Buffer[i]); + } + } + if (_Args.Count() < 8) { + PrintError(" ERROR: gsDPSetCombineMode %s: Not enough arguments", _Buffer.begin()); + } + return _Args; +} + +static void UpdateTextureInfo(GfxData* aGfxData, s64 *aTexPtr, s32 aFormat, s32 aSize, s32 aWidth, s32 aHeight) { + + // Update current texture pointers + if (aTexPtr && (*aTexPtr)) { + aGfxData->mGfxContext.mCurrentPalette = aGfxData->mGfxContext.mCurrentTexture; + aGfxData->mGfxContext.mCurrentTexture = (DataNode*) (*aTexPtr); + } + + // Update texture info if not loaded from a file + if (aGfxData->mGfxContext.mCurrentTexture && aGfxData->mGfxContext.mCurrentTexture->mData && aGfxData->mGfxContext.mCurrentTexture->mData->mPngData.Empty()) { + if (aFormat != -1) aGfxData->mGfxContext.mCurrentTexture->mData->mRawFormat = aFormat; + if (aSize != -1) aGfxData->mGfxContext.mCurrentTexture->mData->mRawSize = aSize; + if (aWidth != -1) aGfxData->mGfxContext.mCurrentTexture->mData->mRawWidth = aWidth; + if (aHeight != -1) aGfxData->mGfxContext.mCurrentTexture->mData->mRawHeight = aHeight; + } +} + +static void ParseGfxSymbol(GfxData* aGfxData, DataNode* aNode, Gfx*& aHead, u64& aTokenIndex) { + const String& _Symbol = aNode->mTokens[aTokenIndex++]; + + // Simple symbols + gfx_symbol_0(gsDPFullSync); + gfx_symbol_0(gsDPTileSync); + gfx_symbol_0(gsDPPipeSync); + gfx_symbol_0(gsDPLoadSync); + gfx_symbol_0(gsDPNoOp); + gfx_symbol_1(gsDPNoOpTag, false); + gfx_symbol_1(gsDPSetCycleType, false); + gfx_symbol_2(gsSPLight, true); + gfx_symbol_3(gsSPVertex, true); + gfx_symbol_4(gsSP1Triangle); + gfx_symbol_8(gsSP2Triangles); + gfx_symbol_1(gsSPNumLights, false); + gfx_symbol_1(gsDPSetDepthSource, false); + gfx_symbol_1(gsDPSetTextureLUT, false); + gfx_symbol_2(gsDPLoadTLUTCmd, false); + gfx_symbol_5(gsDPLoadBlock); + gfx_symbol_2(gsDPSetRenderMode, false); + gfx_symbol_2(gsSPGeometryMode, false); + gfx_symbol_6(gsDPSetPrimColor); + gfx_symbol_4(gsDPSetEnvColor); + gfx_symbol_4(gsDPSetFogColor); + gfx_symbol_2(gsSPFogPosition, false); + gfx_symbol_1(gsDPSetAlphaCompare, false); + gfx_symbol_2(gsSPCopyLightEXT, false); + + // Special symbols + if (_Symbol == "gsSPTexture") { + s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _Arg1 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _Arg2 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _Arg3 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _Arg4 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + gSPTexture(aHead++, _Arg0, _Arg1, _Arg2, _Arg3, _Arg4); + return; + } + if (_Symbol == "gsSPSetGeometryMode") { + s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + gSPSetGeometryMode(aHead++, _Arg0); + return; + } + if (_Symbol == "gsSPClearGeometryMode") { + s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + gSPClearGeometryMode(aHead++, _Arg0); + return; + } + if (_Symbol == "gsSPDisplayList") { + s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + aGfxData->mPointerList.Add(aHead); + gSPDisplayList(aHead++, _Arg0); + return; + } + if (_Symbol == "gsSPBranchList") { + s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + aGfxData->mPointerList.Add(aHead); + gSPBranchList(aHead++, _Arg0); + return; + } + if (_Symbol == "gsSPEndDisplayList") { + gSPEndDisplayList(aHead++); + + // Convert raw texture to PNG if all raw members are set + if (aGfxData->mGfxContext.mCurrentTexture != NULL && + aGfxData->mGfxContext.mCurrentTexture->mData != NULL && + aGfxData->mGfxContext.mCurrentTexture->mData->mPngData.Empty() && + aGfxData->mGfxContext.mCurrentTexture->mData->mRawFormat != -1 && + aGfxData->mGfxContext.mCurrentTexture->mData->mRawSize != -1 && + aGfxData->mGfxContext.mCurrentTexture->mData->mRawWidth != -1 && + aGfxData->mGfxContext.mCurrentTexture->mData->mRawHeight != -1) { + DynOS_Tex_ConvertTextureDataToPng(aGfxData, aGfxData->mGfxContext.mCurrentTexture->mData); + } + + // End the display list parsing after hitting gsSPEndDisplayList + aTokenIndex = 0x7FFFFFFF; + return; + } + + // Complex symbols + if (_Symbol == "gsSPSetLights1") { + Lights1 *_Light = (Lights1 *) ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + gSPNumLights(aHead++, NUMLIGHTS_1); + aGfxData->mPointerList.Add(aHead); + gSPLight(aHead++, &_Light->l[0], 1); + aGfxData->mPointerList.Add(aHead); + gSPLight(aHead++, &_Light->a, 2); + return; + } + if (_Symbol == "gsDPSetCombineMode") { + Array _Args0 = ParseGfxSetCombineMode(aGfxData, aNode, &aTokenIndex); + Array _Args1 = ParseGfxSetCombineMode(aGfxData, aNode, &aTokenIndex); + Gfx _Gfx = {{ + _SHIFTL(G_SETCOMBINE, 24, 8) | _SHIFTL(GCCc0w0(_Args0[0x0], _Args0[0x2], _Args0[0x4], _Args0[0x6]) | GCCc1w0(_Args1[0x0], _Args1[0x2]), 0, 24), + (u32) (GCCc0w1(_Args0[0x1], _Args0[0x3], _Args0[0x5], _Args0[0x7]) | GCCc1w1(_Args1[0x1], _Args1[0x4], _Args1[0x6], _Args1[0x3], _Args1[0x5], _Args1[0x7])) + }}; + *(aHead++) = _Gfx; + return; + } + if (_Symbol == "gsDPSetCombineLERP") { + s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, "G_CCMUX_"); + s64 _Arg1 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, "G_CCMUX_"); + s64 _Arg2 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, "G_CCMUX_"); + s64 _Arg3 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, "G_CCMUX_"); + s64 _Arg4 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, "G_ACMUX_"); + s64 _Arg5 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, "G_ACMUX_"); + s64 _Arg6 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, "G_ACMUX_"); + s64 _Arg7 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, "G_ACMUX_"); + s64 _Arg8 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, "G_CCMUX_"); + s64 _Arg9 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, "G_CCMUX_"); + s64 _ArgA = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, "G_CCMUX_"); + s64 _ArgB = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, "G_CCMUX_"); + s64 _ArgC = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, "G_ACMUX_"); + s64 _ArgD = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, "G_ACMUX_"); + s64 _ArgE = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, "G_ACMUX_"); + s64 _ArgF = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, "G_ACMUX_"); + Gfx _Gfx = {{ + _SHIFTL(G_SETCOMBINE, 24, 8) | _SHIFTL(GCCc0w0(_Arg0, _Arg2, _Arg4, _Arg6) | GCCc1w0(_Arg8, _ArgA), 0, 24), + (u32) (GCCc0w1(_Arg1, _Arg3, _Arg5, _Arg7) | GCCc1w1(_Arg9, _ArgC, _ArgE, _ArgB, _ArgD, _ArgF)) + }}; + *(aHead++) = _Gfx; + return; + } + + // TexData symbols + if (_Symbol == "gsDPSetTextureImage") { + s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _Arg1 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _Arg2 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _Arg3 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + UpdateTextureInfo(aGfxData, &_Arg3, (s32) _Arg0, (s32) _Arg1, -1, -1); + aGfxData->mPointerList.Add(aHead); + gDPSetTextureImage(aHead++, _Arg0, _Arg1, _Arg2, _Arg3); + return; + } + if (_Symbol == "gsDPSetTile") { + s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _Arg1 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _Arg2 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _Arg3 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _Arg4 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _Arg5 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _Arg6 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _Arg7 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _Arg8 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _Arg9 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _ArgA = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _ArgB = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + UpdateTextureInfo(aGfxData, NULL, (s32) _Arg0, (s32) _Arg1, -1, -1); + gDPSetTile(aHead++, _Arg0, _Arg1, _Arg2, _Arg3, _Arg4, _Arg5, _Arg6, _Arg7, _Arg8, _Arg9, _ArgA, _ArgB); + return; + } + if (_Symbol == "gsDPLoadTile") { + s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _Arg1 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _Arg2 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _Arg3 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _Arg4 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + UpdateTextureInfo(aGfxData, NULL, -1, -1, (s32) (_Arg3 >> G_TEXTURE_IMAGE_FRAC) + 1, (s32) (_Arg4 >> G_TEXTURE_IMAGE_FRAC) + 1); + gDPLoadTile(aHead++, _Arg0, _Arg1, _Arg2, _Arg3, _Arg4); + return; + } + if (_Symbol == "gsDPSetTileSize") { + s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _Arg1 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _Arg2 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _Arg3 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _Arg4 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + UpdateTextureInfo(aGfxData, NULL, -1, -1, (s32) (_Arg3 >> G_TEXTURE_IMAGE_FRAC) + 1, (s32) (_Arg4 >> G_TEXTURE_IMAGE_FRAC) + 1); + gDPSetTileSize(aHead++, _Arg0, _Arg1, _Arg2, _Arg3, _Arg4); + return; + } + if (_Symbol == "gsDPLoadTextureBlock") { + s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _Arg1 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + gfx_arg_with_suffix(arg2_0, _LOAD_BLOCK); + gfx_arg_with_suffix(arg2_1, _INCR); + gfx_arg_with_suffix(arg2_2, _SHIFT); + gfx_arg_with_suffix(arg2_3, _BYTES); + gfx_arg_with_suffix(arg2_4, _LINE_BYTES); + s64 _Arg2 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _Arg3 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _Arg4 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _Arg5 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _Arg6 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _Arg7 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _Arg8 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _Arg9 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _ArgA = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + s64 _ArgB = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); + UpdateTextureInfo(aGfxData, &_Arg0, (s32) _Arg1, (s32) _Arg2, (s32) _Arg3, (s32) _Arg4); + + aGfxData->mPointerList.Add(aHead); + gDPSetTextureImage(aHead++, _Arg1, arg2_0, 1, _Arg0); + gDPSetTile(aHead++, _Arg1, arg2_0, 0, 0, G_TX_LOADTILE, 0, _Arg7, _Arg9, _ArgB, _Arg6, _Arg8, _ArgA); + gDPLoadSync(aHead++); + gDPLoadBlock(aHead++, G_TX_LOADTILE, 0, 0, (((_Arg3) * (_Arg4) + arg2_1) >> arg2_2) - 1, CALC_DXT(_Arg3, arg2_3)); + gDPPipeSync(aHead++); + gDPSetTile(aHead++, _Arg1, _Arg2, ((((_Arg3) * arg2_4) + 7) >> 3), 0, G_TX_RENDERTILE, _Arg5, _Arg7, _Arg9, _ArgB, _Arg6, _Arg8, _ArgA); + gDPSetTileSize(aHead++, G_TX_RENDERTILE, 0, 0, ((_Arg3) - 1) << G_TEXTURE_IMAGE_FRAC, ((_Arg4) - 1) << G_TEXTURE_IMAGE_FRAC); + return; + } + + // Unknown + PrintError(" ERROR: Unknown gfx symbol: %s", _Symbol.begin()); +} + +DataNode* DynOS_Gfx_Parse(GfxData* aGfxData, DataNode* aNode) { + if (aNode->mData) return aNode; + + // Display list data + aNode->mData = New(aNode->mTokens.Count() * DISPLAY_LIST_SIZE_PER_TOKEN); + Gfx* _Head = aNode->mData; + for (u64 _TokenIndex = 0; _TokenIndex < aNode->mTokens.Count();) { // Don't increment _TokenIndex here! + ParseGfxSymbol(aGfxData, aNode, _Head, _TokenIndex); + } + aNode->mSize = (u32) (_Head - aNode->mData); + aNode->mLoadIndex = aGfxData->mLoadIndex++; + return aNode; +} + +#pragma GCC diagnostic pop diff --git a/data/dynos_bin_lights.cpp b/data/dynos_bin_lights.cpp new file mode 100644 index 000000000..ba3a9bea4 --- /dev/null +++ b/data/dynos_bin_lights.cpp @@ -0,0 +1,36 @@ +#include "dynos.cpp.h" + + ///////////// + // Parsing // +///////////// + +DataNode* DynOS_Lights_Parse(GfxData* aGfxData, DataNode* aNode) { + if (aNode->mData) return aNode; + + // Check tokens count + if (aNode->mTokens.Count() < 10) { + PrintError(" ERROR: %s: not enough data", aNode->mName.begin()); + return aNode; + } + + // Parse def token + if (aNode->mTokens[0] != "gdSPDefLights1") { + PrintError(" ERROR: Invalid def token: should be gdSPDefLights1, 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(); + u8 r1 = (u8) aNode->mTokens[4].ParseInt(); + u8 g1 = (u8) aNode->mTokens[5].ParseInt(); + u8 b1 = (u8) aNode->mTokens[6].ParseInt(); + s8 x1 = (s8) aNode->mTokens[7].ParseInt(); + s8 y1 = (s8) aNode->mTokens[8].ParseInt(); + s8 z1 = (s8) aNode->mTokens[9].ParseInt(); + aNode->mData = New(); + *aNode->mData = gdSPDefLights1(ar, ag, ab, r1, g1, b1, x1, y1, z1); + aNode->mLoadIndex = aGfxData->mLoadIndex++; + return aNode; +} diff --git a/data/dynos_lvl_read.cpp b/data/dynos_bin_lvl.cpp similarity index 59% rename from data/dynos_lvl_read.cpp rename to data/dynos_bin_lvl.cpp index d87acadb3..224c78ec8 100644 --- a/data/dynos_lvl_read.cpp +++ b/data/dynos_bin_lvl.cpp @@ -41,9 +41,9 @@ void *DynOS_Lvl_GetFunctionPointerFromName(const String &aName) { return NULL; } -// -// Parse level script file -// + ///////////// + // Parsing // +///////////// #define LEVEL_SCRIPT_SIZE_PER_TOKEN 4 @@ -58,17 +58,630 @@ static LevelScript ParseLevelScriptSymbolArg(GfxData* aGfxData, DataNodemGeoLayouts) { + if (_Arg == _Node->mName) { + return (s64) DynOS_Geo_Parse(aGfxData, _Node, false)->mData; + } + } + + // Collisions + for (auto& _Node : aGfxData->mCollisions) { + if (_Arg == _Node->mName) { + return (s64) DynOS_Col_Parse(aGfxData, _Node, false)->mData; + } + } + + // MacroObjects + for (auto& _Node : aGfxData->mMacroObjects) { + if (_Arg == _Node->mName) { + return (s64) DynOS_MacroObject_Parse(aGfxData, _Node, false)->mData; + } + } + // Integers s32 x; if ((_Arg[1] == 'x' && sscanf(_Arg.begin(), "%x", &x) == 1) || (sscanf(_Arg.begin(), "%d", &x) == 1)) { return (LevelScript) x; } + // Recursive descent parsing + bool rdSuccess = false; + s64 rdValue = DynOS_RecursiveDescent_Parse(_Arg.begin(), &rdSuccess); + if (rdSuccess) { + return (LevelScript)rdValue; + } + + // Unknown PrintError(" ERROR: Unknown lvl arg: %s", _Arg.begin()); return 0; @@ -587,40 +1221,40 @@ static LevelScript ParseLevelScriptSymbolArg(GfxData* aGfxData, DataNodemPointerList.Add(aHead + n); } \ - LevelScript _Ls[] = { symb(_Arg0) }; \ - memcpy(aHead, _Ls, sizeof(_Ls)); \ - aHead += (sizeof(_Ls) / sizeof(_Ls[0])); \ - return; \ + if (n != 0) { aGfxData->mPointerList.Add(aHead + n); } \ + LevelScript _Ls[] = { symb(_Arg0) }; \ + memcpy(aHead, _Ls, sizeof(_Ls)); \ + aHead += (sizeof(_Ls) / sizeof(_Ls[0])); \ + return; \ } -#define lvl_symbol_2(symb, n1, n2) \ - if (_Symbol == #symb) { \ +#define lvl_symbol_2(symb, n1, n2) \ + if (_Symbol == #symb) { \ LevelScript _Arg0 = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex); \ LevelScript _Arg1 = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex); \ - if (n1 != 0) { aGfxData->mPointerList.Add(aHead + n1); } \ - if (n2 != 0) { aGfxData->mPointerList.Add(aHead + n2); } \ - LevelScript _Ls[] = { symb(_Arg0, _Arg1) }; \ - memcpy(aHead, _Ls, sizeof(_Ls)); \ - aHead += (sizeof(_Ls) / sizeof(_Ls[0])); \ - return; \ + if (n1 != 0) { aGfxData->mPointerList.Add(aHead + n1); } \ + if (n2 != 0) { aGfxData->mPointerList.Add(aHead + n2); } \ + LevelScript _Ls[] = { symb(_Arg0, _Arg1) }; \ + memcpy(aHead, _Ls, sizeof(_Ls)); \ + aHead += (sizeof(_Ls) / sizeof(_Ls[0])); \ + return; \ } -#define lvl_symbol_3(symb, n1, n2, n3) \ - if (_Symbol == #symb) { \ +#define lvl_symbol_3(symb, n1, n2, n3) \ + if (_Symbol == #symb) { \ LevelScript _Arg0 = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex); \ LevelScript _Arg1 = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex); \ LevelScript _Arg2 = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex); \ - if (n1 != 0) { aGfxData->mPointerList.Add(aHead + n1); } \ - if (n2 != 0) { aGfxData->mPointerList.Add(aHead + n2); } \ - if (n3 != 0) { aGfxData->mPointerList.Add(aHead + n3); } \ - LevelScript _Ls[] = { symb(_Arg0, _Arg1, _Arg2) }; \ - memcpy(aHead, _Ls, sizeof(_Ls)); \ - aHead += (sizeof(_Ls) / sizeof(_Ls[0])); \ - return; \ + if (n1 != 0) { aGfxData->mPointerList.Add(aHead + n1); } \ + if (n2 != 0) { aGfxData->mPointerList.Add(aHead + n2); } \ + if (n3 != 0) { aGfxData->mPointerList.Add(aHead + n3); } \ + LevelScript _Ls[] = { symb(_Arg0, _Arg1, _Arg2) }; \ + memcpy(aHead, _Ls, sizeof(_Ls)); \ + aHead += (sizeof(_Ls) / sizeof(_Ls[0])); \ + return; \ } #define lvl_symbol_4(symb, n1, n2, n3) \ @@ -714,6 +1348,12 @@ static LevelScript ParseLevelScriptSymbolArg(GfxData* aGfxData, DataNode* aNode, LevelScript*& aHead, u64& aTokenIndex, Array& aSwitchNodes) { const String& _Symbol = aNode->mTokens[aTokenIndex++]; @@ -749,9 +1389,9 @@ static void ParseLevelScriptSymbol(GfxData* aGfxData, DataNode* aNo lvl_symbol_0(POP_POOL); lvl_symbol_3(FIXED_LOAD, 1, 2, 3); lvl_symbol_3(LOAD_RAW, 1, 2, 0); - lvl_symbol_3(LOAD_MIO0, 1, 2, 0); + lvl_symbol_noop(LOAD_MIO0, 3); lvl_symbol_1(LOAD_MARIO_HEAD, 0); - lvl_symbol_3(LOAD_MIO0_TEXTURE, 1, 2, 0); + lvl_symbol_noop(LOAD_MIO0_TEXTURE, 3); // levels lvl_symbol_0(INIT_LEVEL); @@ -812,7 +1452,7 @@ static void ParseLevelScriptSymbol(GfxData* aGfxData, DataNode* aNo PrintError(" ERROR: Unknown lvl symbol: %s", _Symbol.begin()); } -static DataNode* ParseLevelScriptData(GfxData* aGfxData, DataNode* aNode, bool aDisplayPercent) { +DataNode* DynOS_Lvl_Parse(GfxData* aGfxData, DataNode* aNode, bool aDisplayPercent) { if (aNode->mData) return aNode; // Level script data @@ -857,7 +1497,7 @@ bool DynOS_Lvl_GeneratePack_Internal(const SysPath &aPackFolder, ArraymModelIdentifier); - ParseLevelScriptData(_GfxData, _LvlRoot, true); + DynOS_Lvl_Parse(_GfxData, _LvlRoot, true); // Write if no error if (_GfxData->mErrorCount == 0) { diff --git a/data/dynos_bin_macro_object.cpp b/data/dynos_bin_macro_object.cpp new file mode 100644 index 000000000..ab4c715da --- /dev/null +++ b/data/dynos_bin_macro_object.cpp @@ -0,0 +1,466 @@ +#include "dynos.cpp.h" + +extern "C" { +#include "include/level_misc_macros.h" +#include "include/macro_preset_names.h" +} + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnarrowing" + + ///////////// + // Parsing // +///////////// + +#define MACRO_OBJECT_SIZE_PER_TOKEN 4 + +#define macro_object_constant(x) if (_Arg == #x) { return (s64) (x); } +static s64 ParseMacroObjectSymbolArg(GfxData* aGfxData, DataNode* aNode, u64& aTokenIndex) { + const String& _Arg = aNode->mTokens[aTokenIndex++]; + + // Surface constants + macro_object_constant(macro_yellow_coin); + macro_object_constant(macro_yellow_coin_2); + macro_object_constant(macro_moving_blue_coin); + macro_object_constant(macro_sliding_blue_coin); + macro_object_constant(macro_red_coin); + macro_object_constant(macro_empty_5); + macro_object_constant(macro_coin_line_horizontal); + macro_object_constant(macro_coin_ring_horizontal); + macro_object_constant(macro_coin_arrow); + macro_object_constant(macro_coin_line_horizontal_flying); + macro_object_constant(macro_coin_line_vertical); + macro_object_constant(macro_coin_ring_horizontal_flying); + macro_object_constant(macro_coin_ring_vertical); + macro_object_constant(macro_coin_arrow_flying); + macro_object_constant(macro_hidden_star_trigger); + macro_object_constant(macro_empty_15); + macro_object_constant(macro_empty_16); + macro_object_constant(macro_empty_17); + macro_object_constant(macro_empty_18); + macro_object_constant(macro_empty_19); + macro_object_constant(macro_fake_star); + macro_object_constant(macro_wooden_signpost); + macro_object_constant(macro_cannon_closed); + macro_object_constant(macro_bobomb_buddy_opens_cannon); + macro_object_constant(macro_butterfly); + macro_object_constant(macro_bouncing_fireball_copy); + macro_object_constant(macro_fish_group_3); + macro_object_constant(macro_fish_group); + macro_object_constant(macro_unknown_28); + macro_object_constant(macro_hidden_1up_in_pole); + macro_object_constant(macro_huge_goomba); + macro_object_constant(macro_tiny_goomba); + macro_object_constant(macro_goomba_triplet_spawner); + macro_object_constant(macro_goomba_quintuplet_spawner); + macro_object_constant(macro_sign_on_wall); + macro_object_constant(macro_chuckya); + macro_object_constant(macro_cannon_open); + macro_object_constant(macro_goomba); + macro_object_constant(macro_homing_amp); + macro_object_constant(macro_circling_amp); + macro_object_constant(macro_unknown_40); + macro_object_constant(macro_unknown_41); + macro_object_constant(macro_free_bowling_ball); + macro_object_constant(macro_snufit); + macro_object_constant(macro_recovery_heart); + macro_object_constant(macro_1up_sliding); + macro_object_constant(macro_1up); + macro_object_constant(macro_1up_jump_on_approach); + macro_object_constant(macro_hidden_1up); + macro_object_constant(macro_hidden_1up_trigger); + macro_object_constant(macro_1up_2); + macro_object_constant(macro_1up_3); + macro_object_constant(macro_empty_52); + macro_object_constant(macro_blue_coin_switch); + macro_object_constant(macro_hidden_blue_coin); + macro_object_constant(macro_wing_cap_switch); + macro_object_constant(macro_metal_cap_switch); + macro_object_constant(macro_vanish_cap_switch); + macro_object_constant(macro_yellow_cap_switch); + macro_object_constant(macro_unknown_59); + macro_object_constant(macro_box_wing_cap); + macro_object_constant(macro_box_metal_cap); + macro_object_constant(macro_box_vanish_cap); + macro_object_constant(macro_box_koopa_shell); + macro_object_constant(macro_box_one_coin); + macro_object_constant(macro_box_three_coins); + macro_object_constant(macro_box_ten_coins); + macro_object_constant(macro_box_1up); + macro_object_constant(macro_box_star_1); + macro_object_constant(macro_breakable_box_no_coins); + macro_object_constant(macro_breakable_box_three_coins); + macro_object_constant(macro_pushable_metal_box); + macro_object_constant(macro_breakable_box_small); + macro_object_constant(macro_floor_switch_hidden_objects); + macro_object_constant(macro_hidden_box); + macro_object_constant(macro_hidden_object_2); + macro_object_constant(macro_hidden_object_3); + macro_object_constant(macro_breakable_box_giant); + macro_object_constant(macro_koopa_shell_underwater); + macro_object_constant(macro_box_1up_running_away); + macro_object_constant(macro_empty_80); + macro_object_constant(macro_bullet_bill_cannon); + macro_object_constant(macro_heave_ho); + macro_object_constant(macro_empty_83); + macro_object_constant(macro_thwomp); + macro_object_constant(macro_fire_spitter); + macro_object_constant(macro_fire_fly_guy); + macro_object_constant(macro_jumping_box); + macro_object_constant(macro_butterfly_triplet); + macro_object_constant(macro_butterfly_triplet_2); + macro_object_constant(macro_empty_90); + macro_object_constant(macro_empty_91); + macro_object_constant(macro_empty_92); + macro_object_constant(macro_bully); + macro_object_constant(macro_bully_2); + macro_object_constant(macro_empty_95); + macro_object_constant(macro_unknown_96); + macro_object_constant(macro_bouncing_fireball); + macro_object_constant(macro_flamethrower); + macro_object_constant(macro_empty_99); + macro_object_constant(macro_empty_100); + macro_object_constant(macro_empty_101); + macro_object_constant(macro_empty_102); + macro_object_constant(macro_empty_103); + macro_object_constant(macro_empty_104); + macro_object_constant(macro_empty_105); + macro_object_constant(macro_wooden_post); + macro_object_constant(macro_water_bomb_spawner); + macro_object_constant(macro_enemy_lakitu); + macro_object_constant(macro_bob_koopa_the_quick); + macro_object_constant(macro_koopa_race_endpoint); + macro_object_constant(macro_bobomb); + macro_object_constant(macro_water_bomb_cannon_copy); + macro_object_constant(macro_bobomb_buddy_opens_cannon_copy); + macro_object_constant(macro_water_bomb_cannon); + macro_object_constant(macro_bobomb_still); + macro_object_constant(macro_empty_116); + macro_object_constant(macro_empty_117); + macro_object_constant(macro_empty_118); + macro_object_constant(macro_empty_119); + macro_object_constant(macro_empty_120); + macro_object_constant(macro_empty_121); + macro_object_constant(macro_empty_122); + macro_object_constant(macro_unknown_123); + macro_object_constant(macro_empty_124); + macro_object_constant(macro_unagi); + macro_object_constant(macro_sushi); + macro_object_constant(macro_empty_127); + macro_object_constant(macro_empty_128); + macro_object_constant(macro_empty_129); + macro_object_constant(macro_empty_130); + macro_object_constant(macro_empty_131); + macro_object_constant(macro_empty_132); + macro_object_constant(macro_empty_133); + macro_object_constant(macro_empty_134); + macro_object_constant(macro_empty_135); + macro_object_constant(macro_empty_136); + macro_object_constant(macro_unknown_137); + macro_object_constant(macro_tornado); + macro_object_constant(macro_pokey); + macro_object_constant(macro_pokey_copy); + macro_object_constant(macro_tox_box); + macro_object_constant(macro_empty_142); + macro_object_constant(macro_empty_143); + macro_object_constant(macro_empty_144); + macro_object_constant(macro_empty_145); + macro_object_constant(macro_empty_146); + macro_object_constant(macro_empty_147); + macro_object_constant(macro_empty_148); + macro_object_constant(macro_empty_149); + macro_object_constant(macro_empty_150); + macro_object_constant(macro_monty_mole_2); + macro_object_constant(macro_monty_mole); + macro_object_constant(macro_monty_mole_hole); + macro_object_constant(macro_fly_guy); + macro_object_constant(macro_empty_155); + macro_object_constant(macro_wiggler); + macro_object_constant(macro_empty_157); + macro_object_constant(macro_empty_158); + macro_object_constant(macro_empty_159); + macro_object_constant(macro_empty_160); + macro_object_constant(macro_empty_161); + macro_object_constant(macro_empty_162); + macro_object_constant(macro_empty_163); + macro_object_constant(macro_empty_164); + macro_object_constant(macro_spindrift); + macro_object_constant(macro_mr_blizzard); + macro_object_constant(macro_mr_blizzard_copy); + macro_object_constant(macro_empty_168); + macro_object_constant(macro_small_penguin); + macro_object_constant(macro_tuxies_mother); + macro_object_constant(macro_tuxies_mother_copy); + macro_object_constant(macro_mr_blizzard_2); + macro_object_constant(macro_empty_173); + macro_object_constant(macro_empty_174); + macro_object_constant(macro_empty_175); + macro_object_constant(macro_empty_176); + macro_object_constant(macro_empty_177); + macro_object_constant(macro_empty_178); + macro_object_constant(macro_empty_179); + macro_object_constant(macro_empty_180); + macro_object_constant(macro_empty_181); + macro_object_constant(macro_empty_182); + macro_object_constant(macro_empty_183); + macro_object_constant(macro_empty_184); + macro_object_constant(macro_empty_185); + macro_object_constant(macro_empty_186); + macro_object_constant(macro_empty_187); + macro_object_constant(macro_empty_188); + macro_object_constant(macro_haunted_chair_copy); + macro_object_constant(macro_haunted_chair); + macro_object_constant(macro_haunted_chair_copy2); + macro_object_constant(macro_boo); + macro_object_constant(macro_boo_copy); + macro_object_constant(macro_boo_group); + macro_object_constant(macro_boo_with_cage); + macro_object_constant(macro_beta_key); + macro_object_constant(macro_empty_197); + macro_object_constant(macro_empty_198); + macro_object_constant(macro_empty_199); + macro_object_constant(macro_empty_200); + macro_object_constant(macro_empty_201); + macro_object_constant(macro_empty_202); + macro_object_constant(macro_empty_203); + macro_object_constant(macro_empty_204); + macro_object_constant(macro_empty_205); + macro_object_constant(macro_empty_206); + macro_object_constant(macro_empty_207); + macro_object_constant(macro_empty_208); + macro_object_constant(macro_empty_209); + macro_object_constant(macro_empty_210); + macro_object_constant(macro_empty_211); + macro_object_constant(macro_empty_212); + macro_object_constant(macro_empty_213); + macro_object_constant(macro_empty_214); + macro_object_constant(macro_empty_215); + macro_object_constant(macro_empty_216); + macro_object_constant(macro_empty_217); + macro_object_constant(macro_empty_218); + macro_object_constant(macro_empty_219); + macro_object_constant(macro_empty_220); + macro_object_constant(macro_empty_221); + macro_object_constant(macro_empty_222); + macro_object_constant(macro_empty_223); + macro_object_constant(macro_empty_224); + macro_object_constant(macro_empty_225); + macro_object_constant(macro_empty_226); + macro_object_constant(macro_empty_227); + macro_object_constant(macro_empty_228); + macro_object_constant(macro_empty_229); + macro_object_constant(macro_empty_230); + macro_object_constant(macro_empty_231); + macro_object_constant(macro_empty_232); + macro_object_constant(macro_empty_233); + macro_object_constant(macro_chirp_chirp); + macro_object_constant(macro_seaweed_bundle); + macro_object_constant(macro_beta_chest); + macro_object_constant(macro_water_mine); + macro_object_constant(macro_fish_group_4); + macro_object_constant(macro_fish_group_2); + macro_object_constant(macro_jet_stream_ring_spawner); + macro_object_constant(macro_jet_stream_ring_spawner_copy); + macro_object_constant(macro_skeeter); + macro_object_constant(macro_clam_shell); + macro_object_constant(macro_empty_244); + macro_object_constant(macro_empty_245); + macro_object_constant(macro_empty_246); + macro_object_constant(macro_empty_247); + macro_object_constant(macro_empty_248); + macro_object_constant(macro_empty_249); + macro_object_constant(macro_empty_250); + macro_object_constant(macro_ukiki); + macro_object_constant(macro_ukiki_2); + macro_object_constant(macro_piranha_plant); + macro_object_constant(macro_empty_254); + macro_object_constant(macro_whomp); + macro_object_constant(macro_chain_chomp); + macro_object_constant(macro_empty_257); + macro_object_constant(macro_koopa); + macro_object_constant(macro_koopa_shellless); + macro_object_constant(macro_wooden_post_copy); + macro_object_constant(macro_fire_piranha_plant); + macro_object_constant(macro_fire_piranha_plant_2); + macro_object_constant(macro_thi_koopa_the_quick); + macro_object_constant(macro_empty_264); + macro_object_constant(macro_empty_265); + macro_object_constant(macro_empty_266); + macro_object_constant(macro_empty_267); + macro_object_constant(macro_empty_268); + macro_object_constant(macro_empty_269); + macro_object_constant(macro_empty_270); + macro_object_constant(macro_empty_271); + macro_object_constant(macro_empty_272); + macro_object_constant(macro_empty_273); + macro_object_constant(macro_empty_274); + macro_object_constant(macro_empty_275); + macro_object_constant(macro_empty_276); + macro_object_constant(macro_empty_277); + macro_object_constant(macro_empty_278); + macro_object_constant(macro_empty_279); + macro_object_constant(macro_empty_280); + macro_object_constant(macro_moneybag); + macro_object_constant(macro_empty_282); + macro_object_constant(macro_empty_283); + macro_object_constant(macro_empty_284); + macro_object_constant(macro_empty_285); + macro_object_constant(macro_empty_286); + macro_object_constant(macro_empty_287); + macro_object_constant(macro_empty_288); + macro_object_constant(macro_swoop); + macro_object_constant(macro_swoop_2); + macro_object_constant(macro_mr_i); + macro_object_constant(macro_scuttlebug_spawner); + macro_object_constant(macro_scuttlebug); + macro_object_constant(macro_empty_294); + macro_object_constant(macro_empty_295); + macro_object_constant(macro_empty_296); + macro_object_constant(macro_empty_297); + macro_object_constant(macro_empty_298); + macro_object_constant(macro_empty_299); + macro_object_constant(macro_empty_300); + macro_object_constant(macro_empty_301); + macro_object_constant(macro_empty_302); + macro_object_constant(macro_unknown_303); + macro_object_constant(macro_empty_304); + macro_object_constant(macro_empty_305); + macro_object_constant(macro_empty_306); + macro_object_constant(macro_empty_307); + macro_object_constant(macro_empty_308); + macro_object_constant(macro_empty_309); + macro_object_constant(macro_empty_310); + macro_object_constant(macro_empty_311); + macro_object_constant(macro_empty_312); + macro_object_constant(macro_ttc_rotating_cube); + macro_object_constant(macro_ttc_rotating_prism); + macro_object_constant(macro_ttc_pendulum); + macro_object_constant(macro_ttc_large_treadmill); + macro_object_constant(macro_ttc_small_treadmill); + macro_object_constant(macro_ttc_push_block); + macro_object_constant(macro_ttc_rotating_hexagon); + macro_object_constant(macro_ttc_rotating_triangle); + macro_object_constant(macro_ttc_pit_block); + macro_object_constant(macro_ttc_pit_block_2); + macro_object_constant(macro_ttc_elevator_platform); + macro_object_constant(macro_ttc_clock_hand); + macro_object_constant(macro_ttc_spinner); + macro_object_constant(macro_ttc_small_gear); + macro_object_constant(macro_ttc_large_gear); + macro_object_constant(macro_ttc_large_treadmill_2); + macro_object_constant(macro_ttc_small_treadmill_2); + macro_object_constant(macro_empty_330); + macro_object_constant(macro_empty_331); + macro_object_constant(macro_empty_332); + macro_object_constant(macro_empty_333); + macro_object_constant(macro_empty_334); + macro_object_constant(macro_empty_335); + macro_object_constant(macro_empty_336); + macro_object_constant(macro_empty_337); + macro_object_constant(macro_empty_338); + macro_object_constant(macro_box_star_2); + macro_object_constant(macro_box_star_3); + macro_object_constant(macro_box_star_4); + macro_object_constant(macro_box_star_5); + macro_object_constant(macro_box_star_6); + macro_object_constant(macro_empty_344); + macro_object_constant(macro_empty_345); + macro_object_constant(macro_empty_346); + macro_object_constant(macro_empty_347); + macro_object_constant(macro_empty_348); + macro_object_constant(macro_empty_349); + macro_object_constant(macro_bits_sliding_platform); + macro_object_constant(macro_bits_twin_sliding_platforms); + macro_object_constant(macro_bits_unknown_352); + macro_object_constant(macro_bits_octagonal_platform); + macro_object_constant(macro_bits_staircase); + macro_object_constant(macro_empty_355); + macro_object_constant(macro_empty_356); + macro_object_constant(macro_bits_ferris_wheel_axle); + macro_object_constant(macro_bits_arrow_platform); + macro_object_constant(macro_bits_seesaw_platform); + macro_object_constant(macro_bits_tilting_w_platform); + macro_object_constant(macro_empty_361); + macro_object_constant(macro_empty_362); + macro_object_constant(macro_empty_363); + macro_object_constant(macro_empty_364); + macro_object_constant(macro_empty_365); + + // Other constants + macro_object_constant(NULL); + + // Integers + s32 x; + if ((_Arg[1] == 'x' && sscanf(_Arg.begin(), "%x", &x) == 1) || (sscanf(_Arg.begin(), "%d", &x) == 1)) { + return (s64) x; + } + + // Unknown + PrintError(" ERROR: Unknown macro object arg: %s", _Arg.begin()); + return 0; +} + +#define macro_object_symbol_0(symb) \ + if (_Symbol == #symb) { \ + MacroObject _Mo[] = { symb() }; \ + memcpy(aHead, _Mo, sizeof(_Mo)); \ + aHead += (sizeof(_Mo) / sizeof(_Mo[0])); \ + return; \ + } + +#define macro_object_symbol_5(symb) \ + if (_Symbol == #symb) { \ + s64 _Arg0 = ParseMacroObjectSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg1 = ParseMacroObjectSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg2 = ParseMacroObjectSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg3 = ParseMacroObjectSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg4 = ParseMacroObjectSymbolArg(aGfxData, aNode, aTokenIndex); \ + MacroObject _Mo[] = { symb(_Arg0, _Arg1, _Arg2, _Arg3, _Arg4) }; \ + memcpy(aHead, _Mo, sizeof(_Mo)); \ + aHead += (sizeof(_Mo) / sizeof(_Mo[0])); \ + return; \ + } + +#define macro_object_symbol_6(symb) \ + if (_Symbol == #symb) { \ + s64 _Arg0 = ParseMacroObjectSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg1 = ParseMacroObjectSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg2 = ParseMacroObjectSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg3 = ParseMacroObjectSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg4 = ParseMacroObjectSymbolArg(aGfxData, aNode, aTokenIndex); \ + s64 _Arg5 = ParseMacroObjectSymbolArg(aGfxData, aNode, aTokenIndex); \ + MacroObject _Mo[] = { symb(_Arg0, _Arg1, _Arg2, _Arg3, _Arg4, _Arg5) }; \ + memcpy(aHead, _Mo, sizeof(_Mo)); \ + aHead += (sizeof(_Mo) / sizeof(_Mo[0])); \ + return; \ + } + +static void ParseMacroObjectSymbol(GfxData* aGfxData, DataNode* aNode, MacroObject*& aHead, u64& aTokenIndex, Array& aSwitchNodes) { + const String& _Symbol = aNode->mTokens[aTokenIndex++]; + + macro_object_symbol_5(MACRO_OBJECT); + macro_object_symbol_6(MACRO_OBJECT_WITH_BEH_PARAM); + macro_object_symbol_0(MACRO_OBJECT_END); + + // Unknown + PrintError(" ERROR: Unknown macro object symbol: %s", _Symbol.begin()); +} + +DataNode* DynOS_MacroObject_Parse(GfxData* aGfxData, DataNode* aNode, bool aDisplayPercent) { + if (aNode->mData) return aNode; + + // MacroObject data + aNode->mData = New(aNode->mTokens.Count() * MACRO_OBJECT_SIZE_PER_TOKEN); + MacroObject* _Head = aNode->mData; + Array _SwitchNodes; + for (u64 _TokenIndex = 0; _TokenIndex < aNode->mTokens.Count();) { // Don't increment _TokenIndex here! + ParseMacroObjectSymbol(aGfxData, aNode, _Head, _TokenIndex, _SwitchNodes); + if (aDisplayPercent && aGfxData->mErrorCount == 0) { PrintNoNewLine("%3d%%\b\b\b\b", (s32) (_TokenIndex * 100) / aNode->mTokens.Count()); } + } + if (aDisplayPercent && aGfxData->mErrorCount == 0) { Print("100%%"); } + aNode->mSize = (u32)(_Head - aNode->mData); + aNode->mLoadIndex = aGfxData->mLoadIndex++; + return aNode; +} + +#pragma GCC diagnostic pop diff --git a/data/dynos_bin_tex.cpp b/data/dynos_bin_tex.cpp new file mode 100644 index 000000000..277536115 --- /dev/null +++ b/data/dynos_bin_tex.cpp @@ -0,0 +1,110 @@ +#include "dynos.cpp.h" +extern "C" { +#define STB_IMAGE_WRITE_IMPLEMENTATION +#include "stb/stb_image_write.h" +} + + /////////// + // Utils // +/////////// + +static TexData* LoadTextureFromFile(GfxData *aGfxData, const String& aFile) { + + // Image file + String _TexturePath = aFile.SubString(aFile.Find('/') + 1); // Remove the "actors/" + SysPath _Filename = fstring("%s/%s.png", aGfxData->mPackFolder.c_str(), _TexturePath.begin()); + FILE *_File = fopen(_Filename.c_str(), "rb"); + if (!_File) { + PrintError(" ERROR: Unable to open file \"%s\"", _Filename.c_str()); + return NULL; + } + + // Texture data + fseek(_File, 0, SEEK_END); + TexData* _Texture = New(); + _Texture->mPngData.Resize(ftell(_File)); rewind(_File); + fread(_Texture->mPngData.begin(), sizeof(u8), _Texture->mPngData.Count(), _File); + fclose(_File); + return _Texture; +} + +void DynOS_Tex_ConvertTextureDataToPng(GfxData *aGfxData, TexData* aTexture) { + + // Convert to RGBA32 + const u8 *_Palette = (aGfxData->mGfxContext.mCurrentPalette ? aGfxData->mGfxContext.mCurrentPalette->mData->mRawData.begin() : NULL); + u8 *_Buffer = DynOS_Gfx_TextureConvertToRGBA32(aTexture->mRawData.begin(), aTexture->mRawData.Count(), aTexture->mRawFormat, aTexture->mRawSize, _Palette); + if (_Buffer == NULL) { + PrintError(" ERROR: Unknown texture format"); + return; + } + + // Convert to PNG + s32 _PngLength = 0; + u8 *_PngData = stbi_write_png_to_mem(_Buffer, 0, aTexture->mRawWidth, aTexture->mRawHeight, 4, &_PngLength); + if (!_PngData || !_PngLength) { + PrintError(" ERROR: Cannot convert texture to PNG"); + return; + } + + aTexture->mPngData = Array(_PngData, _PngData + _PngLength); + Delete(_PngData); +} + + ///////////// + // Parsing // +///////////// + +DataNode* DynOS_Tex_Parse(GfxData* aGfxData, DataNode* aNode) { + if (aNode->mData) return aNode; + + // Check tokens Count + if (aNode->mTokens.Count() < 1) { + PrintError(" ERROR: %s: not enough data", aNode->mName.begin()); + return aNode; + } + + // #include"[texture].inc.c" + s32 i0 = aNode->mTokens[0].Find("#include"); + if (i0 != -1) { + s32 i1 = aNode->mTokens[0].Find(".inc.c"); + if (i1 == -1) { + PrintError(" ERROR: %s: missing .inc.c in String %s", aNode->mName.begin(), aNode->mTokens[0].begin()); + return aNode; + } + + // Filename + String _Filename = aNode->mTokens[0].SubString(i0 + 9, i1 - i0 - 9); + aNode->mData = LoadTextureFromFile(aGfxData, _Filename); + aNode->mLoadIndex = aGfxData->mLoadIndex++; + return aNode; + } + + // double quoted String + s32 dq0 = aNode->mTokens[0].Find('\"'); + if (dq0 != -1) { + s32 dq1 = aNode->mTokens[0].Find('\"', dq0 + 1); + if (dq1 == -1) { + PrintError(" ERROR: %s: missing second quote in String %s", aNode->mName.begin(), aNode->mTokens[0].begin()); + return aNode; + } + + // Filename + String _Filename = aNode->mTokens[0].SubString(dq0 + 1, dq1 - dq0 - 1); + aNode->mData = LoadTextureFromFile(aGfxData, _Filename); + aNode->mLoadIndex = aGfxData->mLoadIndex++; + return aNode; + } + + // Stream of bytes + aNode->mData = New(); + aNode->mData->mRawWidth = -1; // Unknown for now, will be set later + aNode->mData->mRawHeight = -1; // Unknown for now, will be set later + aNode->mData->mRawFormat = -1; // Unknown for now, will be set later + aNode->mData->mRawSize = -1; // Unknown for now, will be set later + aNode->mData->mRawData.Resize(aNode->mTokens.Count()); + for (u64 j = 0; j != aNode->mTokens.Count(); ++j) { + aNode->mData->mRawData[j] = aNode->mTokens[j].ParseInt(); + } + aNode->mLoadIndex = aGfxData->mLoadIndex++; + return aNode; +} diff --git a/data/dynos_bin_utils.cpp b/data/dynos_bin_utils.cpp new file mode 100644 index 000000000..6648681d5 --- /dev/null +++ b/data/dynos_bin_utils.cpp @@ -0,0 +1,157 @@ +#include "dynos.cpp.h" + + /////////////////////// + // Recursive Descent // +/////////////////////// + +static char* sRdString = NULL; +static bool sRdError = false; + +static s64 ParseExpression(); + +static void ParseWhitespace() { + while (*sRdString == ' ' || *sRdString == '\t' || *sRdString == '\r' || *sRdString == '\n') { + sRdString++; + } +} + +static s64 ParseNumeric() { + String numeric = ""; + char* c = sRdString; + + // check for hex + if (*c == '0' && *(c+1) == 'x') { + numeric.Add(*c); + c++; + numeric.Add(*c); + c++; + } + + // continue adding to string + while (*c >= '0' && *c <= '9') { + numeric.Add(*c); + c++; + } + + // advance parsing + sRdString = c; + ParseWhitespace(); + + // parse + return numeric.ParseInt(); +} + +static s64 ParseFactor() { + char* c = sRdString; + + // check for unary op + if (*c == '-') { + sRdString++; + ParseWhitespace(); + s64 f1 = ParseFactor(); + return -f1; + } else if (*c == '+') { + sRdString++; + ParseWhitespace(); + s64 f1 = ParseFactor(); + return +f1; + } else if (*c == '!') { + sRdString++; + ParseWhitespace(); + s64 f1 = ParseFactor(); + return !f1; + } else if (*c == '~') { + sRdString++; + ParseWhitespace(); + s64 f1 = ParseFactor(); + return ~f1; + } + + // check for numeric + if (*c >= '0' && *c <= '9') { + return ParseNumeric(); + + // check for sub expression + } else if (*c >= '(') { + sRdString++; + ParseWhitespace(); + s64 e1 = ParseExpression(); + if (*sRdString == ')') { + sRdString++; + ParseWhitespace(); + return e1; + } + } + + sRdError = true; + return 0; +} + +static s64 ParseTerm() { + s64 f1 = ParseFactor(); + + if (*sRdString == '*') { + sRdString++; + ParseWhitespace(); + s64 f2 = ParseFactor(); + return f1 * f2; + } else if (*sRdString == '/') { + sRdString++; + ParseWhitespace(); + s64 f2 = ParseFactor(); + return f1 / f2; + } else if (*sRdString == '%') { + sRdString++; + ParseWhitespace(); + s64 f2 = ParseFactor(); + return f1 % f2; + } + + return f1; +} + +static s64 ParseAddSubExpression() { + s64 t1 = ParseTerm(); + + if (*sRdString == '+') { + sRdString++; + ParseWhitespace(); + s64 t2 = ParseTerm(); + return t1 + t2; + } else if (*sRdString == '+') { + sRdString++; + ParseWhitespace(); + s64 t2 = ParseTerm(); + return t1 - t2; + } + + return t1; +} + +static s64 ParseExpression() { + s64 e1 = ParseAddSubExpression(); + + if (*sRdString == '<' && *(sRdString + 1) == '<') { + sRdString += 2; + ParseWhitespace(); + s64 e2 = ParseAddSubExpression(); + return e1 << e2; + } else if (*sRdString == '>' && *(sRdString + 1) == '>') { + sRdString += 2; + ParseWhitespace(); + s64 e2 = ParseAddSubExpression(); + return e1 >> e2; + } + + return e1; +} + +s64 DynOS_RecursiveDescent_Parse(const char* expr, bool* success) { + sRdString = (char*)expr; + sRdError = false; + s64 value = ParseExpression(); + sRdString = NULL; + *success = !sRdError; + //Print(">>> PARSING %s == %d :: %u", expr, value, *success); + return value; +} diff --git a/data/dynos_bin_vtx.cpp b/data/dynos_bin_vtx.cpp new file mode 100644 index 000000000..ccd958cfe --- /dev/null +++ b/data/dynos_bin_vtx.cpp @@ -0,0 +1,28 @@ +#include "dynos.cpp.h" + + ///////////// + // Parsing // +///////////// + +DataNode* DynOS_Vtx_Parse(GfxData* aGfxData, DataNode* aNode) { + if (aNode->mData) return aNode; + + // Vertex data + aNode->mSize = (u32) (aNode->mTokens.Count() / 10); + aNode->mData = New(aNode->mSize); + for (u32 i = 0; i != aNode->mSize; ++i) { + f32 px = (f32) aNode->mTokens[10 * i + 0].ParseFloat(); + f32 py = (f32) aNode->mTokens[10 * i + 1].ParseFloat(); + f32 pz = (f32) aNode->mTokens[10 * i + 2].ParseFloat(); + u8 fl = (u8) aNode->mTokens[10 * i + 3].ParseInt(); + s16 tu = (s16) aNode->mTokens[10 * i + 4].ParseInt(); + s16 tv = (s16) aNode->mTokens[10 * i + 5].ParseInt(); + u8 nx = (u8) aNode->mTokens[10 * i + 6].ParseInt(); + u8 ny = (u8) aNode->mTokens[10 * i + 7].ParseInt(); + u8 nz = (u8) aNode->mTokens[10 * i + 8].ParseInt(); + u8 a = (u8) aNode->mTokens[10 * i + 9].ParseInt(); + aNode->mData[i] = { { { px, py, pz }, fl, { tu, tv }, { nx, ny, nz, a } } }; + } + aNode->mLoadIndex = aGfxData->mLoadIndex++; + return aNode; +} diff --git a/data/dynos_gfx_read.cpp b/data/dynos_gfx_read.cpp index 1fc06ef60..b968a6988 100644 --- a/data/dynos_gfx_read.cpp +++ b/data/dynos_gfx_read.cpp @@ -1,27 +1,7 @@ #include "dynos.cpp.h" extern "C" { -#include "geo_commands.h" -#define STB_IMAGE_WRITE_IMPLEMENTATION -#include "stb/stb_image_write.h" } -#define LAYER_FORCE 0 -#define LAYER_OPAQUE 1 -#define LAYER_OPAQUE_DECAL 2 -#define LAYER_OPAQUE_INTER 3 -#define LAYER_ALPHA 4 -#define LAYER_TRANSPARENT 5 -#define LAYER_TRANSPARENT_DECAL 6 -#define LAYER_TRANSPARENT_INTER 7 -#define DISPLAY_LIST_SIZE_PER_TOKEN 4 -#define GEO_LAYOUT_SIZE_PER_TOKEN 4 - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wnarrowing" - -static DataNode* ParseDisplayListData(GfxData* aGfxData, DataNode* aNode); -static DataNode* ParseGeoLayoutData(GfxData* aGfxData, DataNode* aNode, bool aDisplayPercent); - // // Model files // @@ -206,6 +186,8 @@ static void ScanModelFile(GfxData *aGfxData, const SysPath &aFilename) { _DataType = DATA_TYPE_COLLISION; } else if (_Buffer == "LevelScript") { _DataType = DATA_TYPE_LEVEL_SCRIPT; + } else if (_Buffer == "MacroObject") { + _DataType = DATA_TYPE_MACRO_OBJECT; } else { PrintError(" ERROR: Unknown type name: %s", _Buffer.begin()); } @@ -231,6 +213,7 @@ static void ScanModelFile(GfxData *aGfxData, const SysPath &aFilename) { case DATA_TYPE_GEO_LAYOUT: AppendNewNode(aGfxData, aGfxData->mGeoLayouts, _Buffer, pDataName, pDataTokens); break; case DATA_TYPE_COLLISION: AppendNewNode(aGfxData, aGfxData->mCollisions, _Buffer, pDataName, pDataTokens); break; case DATA_TYPE_LEVEL_SCRIPT: AppendNewNode(aGfxData, aGfxData->mLevelScripts, _Buffer, pDataName, pDataTokens); break; + case DATA_TYPE_MACRO_OBJECT: AppendNewNode(aGfxData, aGfxData->mMacroObjects, _Buffer, pDataName, pDataTokens); break; case DATA_TYPE_UNUSED: pDataTokens = (Array *) 1; break; } _Buffer.Clear(); @@ -298,1330 +281,6 @@ static void ScanModelFile(GfxData *aGfxData, const SysPath &aFilename) { Print("Data read from file \"%s\"", aFilename.c_str()); } -// -// Lights -// - -static DataNode* ParseLightData(GfxData* aGfxData, DataNode* aNode) { - if (aNode->mData) return aNode; - - // Check tokens count - if (aNode->mTokens.Count() < 10) { - PrintError(" ERROR: %s: not enough data", aNode->mName.begin()); - return aNode; - } - - // Parse def token - if (aNode->mTokens[0] != "gdSPDefLights1") { - PrintError(" ERROR: Invalid def token: should be gdSPDefLights1, 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(); - u8 r1 = (u8) aNode->mTokens[4].ParseInt(); - u8 g1 = (u8) aNode->mTokens[5].ParseInt(); - u8 b1 = (u8) aNode->mTokens[6].ParseInt(); - s8 x1 = (s8) aNode->mTokens[7].ParseInt(); - s8 y1 = (s8) aNode->mTokens[8].ParseInt(); - s8 z1 = (s8) aNode->mTokens[9].ParseInt(); - aNode->mData = New(); - *aNode->mData = gdSPDefLights1(ar, ag, ab, r1, g1, b1, x1, y1, z1); - aNode->mLoadIndex = aGfxData->mLoadIndex++; - return aNode; -} - -// -// Textures -// - -static TexData* LoadTextureFromFile(GfxData *aGfxData, const String& aFile) { - - // Image file - String _TexturePath = aFile.SubString(aFile.Find('/') + 1); // Remove the "actors/" - SysPath _Filename = fstring("%s/%s.png", aGfxData->mPackFolder.c_str(), _TexturePath.begin()); - FILE *_File = fopen(_Filename.c_str(), "rb"); - if (!_File) { - PrintError(" ERROR: Unable to open file \"%s\"", _Filename.c_str()); - return NULL; - } - - // Texture data - fseek(_File, 0, SEEK_END); - TexData* _Texture = New(); - _Texture->mPngData.Resize(ftell(_File)); rewind(_File); - fread(_Texture->mPngData.begin(), sizeof(u8), _Texture->mPngData.Count(), _File); - fclose(_File); - return _Texture; -} - -static void ConvertTextureDataToPng(GfxData *aGfxData, TexData* aTexture) { - - // Convert to RGBA32 - const u8 *_Palette = (aGfxData->mGfxContext.mCurrentPalette ? aGfxData->mGfxContext.mCurrentPalette->mData->mRawData.begin() : NULL); - u8 *_Buffer = DynOS_Gfx_TextureConvertToRGBA32(aTexture->mRawData.begin(), aTexture->mRawData.Count(), aTexture->mRawFormat, aTexture->mRawSize, _Palette); - if (_Buffer == NULL) { - PrintError(" ERROR: Unknown texture format"); - return; - } - - // Convert to PNG - s32 _PngLength = 0; - u8 *_PngData = stbi_write_png_to_mem(_Buffer, 0, aTexture->mRawWidth, aTexture->mRawHeight, 4, &_PngLength); - if (!_PngData || !_PngLength) { - PrintError(" ERROR: Cannot convert texture to PNG"); - return; - } - - aTexture->mPngData = Array(_PngData, _PngData + _PngLength); - Delete(_PngData); -} - -static DataNode* ParseTextureData(GfxData* aGfxData, DataNode* aNode) { - if (aNode->mData) return aNode; - - // Check tokens Count - if (aNode->mTokens.Count() < 1) { - PrintError(" ERROR: %s: not enough data", aNode->mName.begin()); - return aNode; - } - - // #include"[texture].inc.c" - s32 i0 = aNode->mTokens[0].Find("#include"); - if (i0 != -1) { - s32 i1 = aNode->mTokens[0].Find(".inc.c"); - if (i1 == -1) { - PrintError(" ERROR: %s: missing .inc.c in String %s", aNode->mName.begin(), aNode->mTokens[0].begin()); - return aNode; - } - - // Filename - String _Filename = aNode->mTokens[0].SubString(i0 + 9, i1 - i0 - 9); - aNode->mData = LoadTextureFromFile(aGfxData, _Filename); - aNode->mLoadIndex = aGfxData->mLoadIndex++; - return aNode; - } - - // double quoted String - s32 dq0 = aNode->mTokens[0].Find('\"'); - if (dq0 != -1) { - s32 dq1 = aNode->mTokens[0].Find('\"', dq0 + 1); - if (dq1 == -1) { - PrintError(" ERROR: %s: missing second quote in String %s", aNode->mName.begin(), aNode->mTokens[0].begin()); - return aNode; - } - - // Filename - String _Filename = aNode->mTokens[0].SubString(dq0 + 1, dq1 - dq0 - 1); - aNode->mData = LoadTextureFromFile(aGfxData, _Filename); - aNode->mLoadIndex = aGfxData->mLoadIndex++; - return aNode; - } - - // Stream of bytes - aNode->mData = New(); - aNode->mData->mRawWidth = -1; // Unknown for now, will be set later - aNode->mData->mRawHeight = -1; // Unknown for now, will be set later - aNode->mData->mRawFormat = -1; // Unknown for now, will be set later - aNode->mData->mRawSize = -1; // Unknown for now, will be set later - aNode->mData->mRawData.Resize(aNode->mTokens.Count()); - for (u64 j = 0; j != aNode->mTokens.Count(); ++j) { - aNode->mData->mRawData[j] = aNode->mTokens[j].ParseInt(); - } - aNode->mLoadIndex = aGfxData->mLoadIndex++; - return aNode; -} - -// -// Vertices -// - -static DataNode* ParseVertexData(GfxData* aGfxData, DataNode* aNode) { - if (aNode->mData) return aNode; - - // Vertex data - aNode->mSize = (u32) (aNode->mTokens.Count() / 10); - aNode->mData = New(aNode->mSize); - for (u32 i = 0; i != aNode->mSize; ++i) { - f32 px = (f32) aNode->mTokens[10 * i + 0].ParseFloat(); - f32 py = (f32) aNode->mTokens[10 * i + 1].ParseFloat(); - f32 pz = (f32) aNode->mTokens[10 * i + 2].ParseFloat(); - u8 fl = (u8) aNode->mTokens[10 * i + 3].ParseInt(); - s16 tu = (s16) aNode->mTokens[10 * i + 4].ParseInt(); - s16 tv = (s16) aNode->mTokens[10 * i + 5].ParseInt(); - u8 nx = (u8) aNode->mTokens[10 * i + 6].ParseInt(); - u8 ny = (u8) aNode->mTokens[10 * i + 7].ParseInt(); - u8 nz = (u8) aNode->mTokens[10 * i + 8].ParseInt(); - u8 a = (u8) aNode->mTokens[10 * i + 9].ParseInt(); - aNode->mData[i] = { { { px, py, pz }, fl, { tu, tv }, { nx, ny, nz, a } } }; - } - aNode->mLoadIndex = aGfxData->mLoadIndex++; - return aNode; -} - -// -// Display lists -// - -#define gfx_constant(x) if (_Arg == #x) { return (s64) (x); } -static s64 ParseGfxSymbolArg(GfxData* aGfxData, DataNode* aNode, u64* pTokenIndex, const char *aPrefix) { - assert(aPrefix != NULL); - String _Token = (pTokenIndex != NULL ? aNode->mTokens[(*pTokenIndex)++] : ""); - String _Arg("%s%s", aPrefix, _Token.begin()); - - // Offset - s32 _Offset = 0; - s32 _Plus = _Arg.Find('+'); - if (_Plus != -1) { - _Offset = _Arg.SubString(_Plus + 1).ParseInt(); - _Arg = _Arg.SubString(0, _Plus); - } - - // Constants - gfx_constant(NULL); - gfx_constant(G_ON); - gfx_constant(G_OFF); - - // Combine modes - gfx_constant(G_CCMUX_COMBINED); - gfx_constant(G_CCMUX_TEXEL0); - gfx_constant(G_CCMUX_TEXEL1); - gfx_constant(G_CCMUX_PRIMITIVE); - gfx_constant(G_CCMUX_SHADE); - gfx_constant(G_CCMUX_ENVIRONMENT); - gfx_constant(G_CCMUX_CENTER); - gfx_constant(G_CCMUX_SCALE); - gfx_constant(G_CCMUX_COMBINED_ALPHA); - gfx_constant(G_CCMUX_TEXEL0_ALPHA); - gfx_constant(G_CCMUX_TEXEL1_ALPHA); - gfx_constant(G_CCMUX_PRIMITIVE_ALPHA); - gfx_constant(G_CCMUX_SHADE_ALPHA); - gfx_constant(G_CCMUX_ENV_ALPHA); - gfx_constant(G_CCMUX_LOD_FRACTION); - gfx_constant(G_CCMUX_PRIM_LOD_FRAC); - gfx_constant(G_CCMUX_NOISE); - gfx_constant(G_CCMUX_K4); - gfx_constant(G_CCMUX_K5); - gfx_constant(G_CCMUX_1); - gfx_constant(G_CCMUX_0); - gfx_constant(G_ACMUX_COMBINED); - gfx_constant(G_ACMUX_TEXEL0); - gfx_constant(G_ACMUX_TEXEL1); - gfx_constant(G_ACMUX_PRIMITIVE); - gfx_constant(G_ACMUX_SHADE); - gfx_constant(G_ACMUX_ENVIRONMENT); - gfx_constant(G_ACMUX_LOD_FRACTION); - gfx_constant(G_ACMUX_PRIM_LOD_FRAC); - gfx_constant(G_ACMUX_1); - gfx_constant(G_ACMUX_0); - - // Light constants - gfx_constant(NUMLIGHTS_0); - gfx_constant(NUMLIGHTS_1); - gfx_constant(NUMLIGHTS_2); - gfx_constant(NUMLIGHTS_3); - gfx_constant(NUMLIGHTS_4); - gfx_constant(NUMLIGHTS_5); - gfx_constant(NUMLIGHTS_6); - gfx_constant(NUMLIGHTS_7); - - // Image formats - gfx_constant(G_IM_FMT_RGBA); - gfx_constant(G_IM_FMT_YUV); - gfx_constant(G_IM_FMT_CI); - gfx_constant(G_IM_FMT_IA); - gfx_constant(G_IM_FMT_I); - gfx_constant(G_IM_SIZ_4b); - gfx_constant(G_IM_SIZ_8b); - gfx_constant(G_IM_SIZ_16b); - gfx_constant(G_IM_SIZ_32b); - gfx_constant(G_IM_SIZ_DD); - - // Image constants - gfx_constant(G_IM_SIZ_4b_BYTES); - gfx_constant(G_IM_SIZ_4b_TILE_BYTES); - gfx_constant(G_IM_SIZ_4b_LINE_BYTES); - gfx_constant(G_IM_SIZ_8b_BYTES); - gfx_constant(G_IM_SIZ_8b_TILE_BYTES); - gfx_constant(G_IM_SIZ_8b_LINE_BYTES); - gfx_constant(G_IM_SIZ_16b_BYTES); - gfx_constant(G_IM_SIZ_16b_TILE_BYTES); - gfx_constant(G_IM_SIZ_16b_LINE_BYTES); - gfx_constant(G_IM_SIZ_32b_BYTES); - gfx_constant(G_IM_SIZ_32b_TILE_BYTES); - gfx_constant(G_IM_SIZ_32b_LINE_BYTES); - gfx_constant(G_IM_SIZ_4b_LOAD_BLOCK); - gfx_constant(G_IM_SIZ_8b_LOAD_BLOCK); - gfx_constant(G_IM_SIZ_16b_LOAD_BLOCK); - gfx_constant(G_IM_SIZ_32b_LOAD_BLOCK); - gfx_constant(G_IM_SIZ_4b_SHIFT); - gfx_constant(G_IM_SIZ_8b_SHIFT); - gfx_constant(G_IM_SIZ_16b_SHIFT); - gfx_constant(G_IM_SIZ_32b_SHIFT); - gfx_constant(G_IM_SIZ_4b_INCR); - gfx_constant(G_IM_SIZ_8b_INCR); - gfx_constant(G_IM_SIZ_16b_INCR); - gfx_constant(G_IM_SIZ_32b_INCR); - - // Tile formats - gfx_constant(G_TX_RENDERTILE); - gfx_constant(G_TX_LOADTILE); - gfx_constant(G_TX_NOMIRROR); - gfx_constant(G_TX_WRAP); - gfx_constant(G_TX_MIRROR); - gfx_constant(G_TX_CLAMP); - gfx_constant(G_TX_NOMASK); - gfx_constant(G_TX_NOLOD); - gfx_constant(G_TX_WRAP|G_TX_NOMIRROR); - gfx_constant(G_TX_WRAP|G_TX_MIRROR); - gfx_constant(G_TX_CLAMP|G_TX_NOMIRROR); - gfx_constant(G_TX_CLAMP|G_TX_MIRROR); - - // Render modes - gfx_constant(G_RM_AA_ZB_OPA_SURF); - gfx_constant(G_RM_AA_ZB_OPA_SURF2); - gfx_constant(G_RM_AA_ZB_XLU_SURF); - gfx_constant(G_RM_AA_ZB_XLU_SURF2); - gfx_constant(G_RM_AA_ZB_OPA_DECAL); - gfx_constant(G_RM_AA_ZB_OPA_DECAL2); - gfx_constant(G_RM_AA_ZB_XLU_DECAL); - gfx_constant(G_RM_AA_ZB_XLU_DECAL2); - gfx_constant(G_RM_AA_ZB_OPA_INTER); - gfx_constant(G_RM_AA_ZB_OPA_INTER2); - gfx_constant(G_RM_AA_ZB_XLU_INTER); - gfx_constant(G_RM_AA_ZB_XLU_INTER2); - gfx_constant(G_RM_AA_ZB_XLU_LINE); - gfx_constant(G_RM_AA_ZB_XLU_LINE2); - gfx_constant(G_RM_AA_ZB_DEC_LINE); - gfx_constant(G_RM_AA_ZB_DEC_LINE2); - gfx_constant(G_RM_AA_ZB_TEX_EDGE); - gfx_constant(G_RM_AA_ZB_TEX_EDGE2); - gfx_constant(G_RM_AA_ZB_TEX_INTER); - gfx_constant(G_RM_AA_ZB_TEX_INTER2); - gfx_constant(G_RM_AA_ZB_SUB_SURF); - gfx_constant(G_RM_AA_ZB_SUB_SURF2); - gfx_constant(G_RM_AA_ZB_PCL_SURF); - gfx_constant(G_RM_AA_ZB_PCL_SURF2); - gfx_constant(G_RM_AA_ZB_OPA_TERR); - gfx_constant(G_RM_AA_ZB_OPA_TERR2); - gfx_constant(G_RM_AA_ZB_TEX_TERR); - gfx_constant(G_RM_AA_ZB_TEX_TERR2); - gfx_constant(G_RM_AA_ZB_SUB_TERR); - gfx_constant(G_RM_AA_ZB_SUB_TERR2); - gfx_constant(G_RM_RA_ZB_OPA_SURF); - gfx_constant(G_RM_RA_ZB_OPA_SURF2); - gfx_constant(G_RM_RA_ZB_OPA_DECAL); - gfx_constant(G_RM_RA_ZB_OPA_DECAL2); - gfx_constant(G_RM_RA_ZB_OPA_INTER); - gfx_constant(G_RM_RA_ZB_OPA_INTER2); - gfx_constant(G_RM_AA_OPA_SURF); - gfx_constant(G_RM_AA_OPA_SURF2); - gfx_constant(G_RM_AA_XLU_SURF); - gfx_constant(G_RM_AA_XLU_SURF2); - gfx_constant(G_RM_AA_XLU_LINE); - gfx_constant(G_RM_AA_XLU_LINE2); - gfx_constant(G_RM_AA_DEC_LINE); - gfx_constant(G_RM_AA_DEC_LINE2); - gfx_constant(G_RM_AA_TEX_EDGE); - gfx_constant(G_RM_AA_TEX_EDGE2); - gfx_constant(G_RM_AA_SUB_SURF); - gfx_constant(G_RM_AA_SUB_SURF2); - gfx_constant(G_RM_AA_PCL_SURF); - gfx_constant(G_RM_AA_PCL_SURF2); - gfx_constant(G_RM_AA_OPA_TERR); - gfx_constant(G_RM_AA_OPA_TERR2); - gfx_constant(G_RM_AA_TEX_TERR); - gfx_constant(G_RM_AA_TEX_TERR2); - gfx_constant(G_RM_AA_SUB_TERR); - gfx_constant(G_RM_AA_SUB_TERR2); - gfx_constant(G_RM_RA_OPA_SURF); - gfx_constant(G_RM_RA_OPA_SURF2); - gfx_constant(G_RM_ZB_OPA_SURF); - gfx_constant(G_RM_ZB_OPA_SURF2); - gfx_constant(G_RM_ZB_XLU_SURF); - gfx_constant(G_RM_ZB_XLU_SURF2); - gfx_constant(G_RM_ZB_OPA_DECAL); - gfx_constant(G_RM_ZB_OPA_DECAL2); - gfx_constant(G_RM_ZB_XLU_DECAL); - gfx_constant(G_RM_ZB_XLU_DECAL2); - gfx_constant(G_RM_ZB_CLD_SURF); - gfx_constant(G_RM_ZB_CLD_SURF2); - gfx_constant(G_RM_ZB_OVL_SURF); - gfx_constant(G_RM_ZB_OVL_SURF2); - gfx_constant(G_RM_ZB_PCL_SURF); - gfx_constant(G_RM_ZB_PCL_SURF2); - gfx_constant(G_RM_OPA_SURF); - gfx_constant(G_RM_OPA_SURF2); - gfx_constant(G_RM_XLU_SURF); - gfx_constant(G_RM_XLU_SURF2); - gfx_constant(G_RM_CLD_SURF); - gfx_constant(G_RM_CLD_SURF2); - gfx_constant(G_RM_TEX_EDGE); - gfx_constant(G_RM_TEX_EDGE2); - gfx_constant(G_RM_PCL_SURF); - gfx_constant(G_RM_PCL_SURF2); - gfx_constant(G_RM_ADD); - gfx_constant(G_RM_ADD2); - gfx_constant(G_RM_NOOP); - gfx_constant(G_RM_NOOP2); - gfx_constant(G_RM_VISCVG); - gfx_constant(G_RM_VISCVG2); - gfx_constant(G_RM_OPA_CI); - gfx_constant(G_RM_OPA_CI2); - gfx_constant(G_RM_CUSTOM_AA_ZB_XLU_SURF); - gfx_constant(G_RM_CUSTOM_AA_ZB_XLU_SURF2); - gfx_constant(G_RM_FOG_SHADE_A); - gfx_constant(G_RM_FOG_PRIM_A); - gfx_constant(G_RM_PASS); - - // Geometry modes - gfx_constant(G_ZBUFFER); - gfx_constant(G_SHADE); - gfx_constant(G_TEXTURE_ENABLE); - gfx_constant(G_SHADING_SMOOTH); - gfx_constant(G_CULL_FRONT); - gfx_constant(G_CULL_BACK); - gfx_constant(G_CULL_BOTH); - gfx_constant(G_FOG); - gfx_constant(G_LIGHTING); - gfx_constant(G_TEXTURE_GEN); - gfx_constant(G_TEXTURE_GEN_LINEAR); - gfx_constant(G_LOD); - gfx_constant(G_CLIPPING); - gfx_constant(G_FOG|G_TEXTURE_GEN); - gfx_constant(G_LIGHTING|G_CULL_BACK); - gfx_constant(G_LIGHTING|G_SHADING_SMOOTH); - gfx_constant(G_CULL_BACK|G_SHADING_SMOOTH); - gfx_constant(G_LIGHTING|G_CULL_BACK|G_SHADING_SMOOTH); - gfx_constant(G_TEXTURE_GEN|G_SHADING_SMOOTH); - gfx_constant(G_TEXTURE_GEN|G_LIGHTING|G_CULL_BACK); - gfx_constant(G_TEXTURE_GEN|G_CULL_BACK|G_SHADING_SMOOTH); - - // Alpha modes - gfx_constant(G_AC_NONE); - gfx_constant(G_AC_THRESHOLD); - gfx_constant(G_AC_DITHER); - - // Other modes - gfx_constant(G_MDSFT_ALPHACOMPARE); - gfx_constant(G_MDSFT_ZSRCSEL); - gfx_constant(G_MDSFT_RENDERMODE); - gfx_constant(G_MDSFT_BLENDER); - gfx_constant(G_MDSFT_BLENDMASK); - gfx_constant(G_MDSFT_ALPHADITHER); - gfx_constant(G_MDSFT_RGBDITHER); - gfx_constant(G_MDSFT_COMBKEY); - gfx_constant(G_MDSFT_TEXTCONV); - gfx_constant(G_MDSFT_TEXTFILT); - gfx_constant(G_MDSFT_TEXTLUT); - gfx_constant(G_MDSFT_TEXTLOD); - gfx_constant(G_MDSFT_TEXTDETAIL); - gfx_constant(G_MDSFT_TEXTPERSP); - gfx_constant(G_MDSFT_CYCLETYPE); - gfx_constant(G_MDSFT_COLORDITHER); - gfx_constant(G_MDSFT_PIPELINE); - gfx_constant(G_PM_1PRIMITIVE); - gfx_constant(G_PM_NPRIMITIVE); - gfx_constant(G_CYC_1CYCLE); - gfx_constant(G_CYC_2CYCLE); - gfx_constant(G_CYC_COPY); - gfx_constant(G_CYC_FILL); - gfx_constant(G_TP_NONE); - gfx_constant(G_TP_PERSP); - gfx_constant(G_TD_CLAMP); - gfx_constant(G_TD_SHARPEN); - gfx_constant(G_TD_DETAIL); - gfx_constant(G_TL_TILE); - gfx_constant(G_TL_LOD); - gfx_constant(G_TT_NONE); - gfx_constant(G_TT_RGBA16); - gfx_constant(G_TT_IA16); - gfx_constant(G_TF_POINT); - gfx_constant(G_TF_AVERAGE); - gfx_constant(G_TF_BILERP); - gfx_constant(G_TC_CONV); - gfx_constant(G_TC_FILTCONV); - gfx_constant(G_TC_FILT); - gfx_constant(G_CK_NONE); - gfx_constant(G_CK_KEY); - gfx_constant(G_CD_MAGICSQ); - gfx_constant(G_CD_BAYER); - gfx_constant(G_CD_NOISE); - gfx_constant(G_CD_DISABLE); - gfx_constant(G_CD_ENABLE); - gfx_constant(G_AD_PATTERN); - gfx_constant(G_AD_NOTPATTERN); - gfx_constant(G_AD_NOISE); - gfx_constant(G_AD_DISABLE); - gfx_constant(G_AC_NONE); - gfx_constant(G_AC_THRESHOLD); - gfx_constant(G_AC_DITHER); - gfx_constant(G_ZS_PIXEL); - gfx_constant(G_ZS_PRIM); - - // Common values - gfx_constant((4-1)<mLights) { - - // Light pointer - if (_Arg == _Node->mName) { - return (s64) ParseLightData(aGfxData, _Node)->mData; - } - - // Ambient pointer - String _Ambient("&%s.a", _Node->mName.begin()); - if (_Arg == _Ambient) { - return (s64) &(ParseLightData(aGfxData, _Node)->mData->a); - } - - // Diffuse pointer - String _Diffuse("&%s.l", _Node->mName.begin()); - if (_Arg == _Diffuse) { - return (s64) &(ParseLightData(aGfxData, _Node)->mData->l[0]); - } - } - - // Textures - for (auto& _Node : aGfxData->mTextures) { - if (_Arg == _Node->mName) { - return (s64) ParseTextureData(aGfxData, _Node); - } - } - - // Vertex arrays - for (auto& _Node : aGfxData->mVertices) { - if (_Arg == _Node->mName) { - return (s64) (ParseVertexData(aGfxData, _Node)->mData + _Offset); - } - } - - // Display lists - for (auto& _Node : aGfxData->mDisplayLists) { - if (_Arg == _Node->mName) { - return (s64) ParseDisplayListData(aGfxData, _Node); - } - } - - // Integers - s32 x; - if ((_Arg[1] == 'x' && sscanf(_Arg.begin(), "%x", &x) == 1) || (sscanf(_Arg.begin(), "%d", &x) == 1)) { - return (s64) x; - } - - // Unknown - PrintError(" ERROR: Unknown gfx arg: %s", _Arg.begin()); - return 0; -} - -#define gfx_symbol_0(symb) \ - if (_Symbol == #symb) { \ - Gfx _Gfx[] = { symb() }; \ - memcpy(aHead, _Gfx, sizeof(_Gfx)); \ - aHead += (sizeof(_Gfx) / sizeof(_Gfx[0])); \ - return; \ - } - -#define gfx_symbol_1(symb, ptr) \ - if (_Symbol == #symb) { \ - s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - if (ptr) { aGfxData->mPointerList.Add(aHead); } \ - Gfx _Gfx[] = { symb(_Arg0) }; \ - memcpy(aHead, _Gfx, sizeof(_Gfx)); \ - aHead += (sizeof(_Gfx) / sizeof(_Gfx[0])); \ - return; \ - } - -#define gfx_symbol_2(symb, ptr) \ - if (_Symbol == #symb) { \ - s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - s64 _Arg1 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - if (ptr) { aGfxData->mPointerList.Add(aHead); } \ - Gfx _Gfx[] = { symb(_Arg0, _Arg1) }; \ - memcpy(aHead, _Gfx, sizeof(_Gfx)); \ - aHead += (sizeof(_Gfx) / sizeof(_Gfx[0])); \ - return; \ - } - -#define gfx_symbol_3(symb, ptr) \ - if (_Symbol == #symb) { \ - s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - s64 _Arg1 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - s64 _Arg2 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - if (ptr) { aGfxData->mPointerList.Add(aHead); } \ - Gfx _Gfx[] = { symb(_Arg0, _Arg1, _Arg2) }; \ - memcpy(aHead, _Gfx, sizeof(_Gfx)); \ - aHead += (sizeof(_Gfx) / sizeof(_Gfx[0])); \ - return; \ - } - -#define gfx_symbol_4(symb) \ - if (_Symbol == #symb) { \ - s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - s64 _Arg1 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - s64 _Arg2 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - s64 _Arg3 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - Gfx _Gfx[] = { symb(_Arg0, _Arg1, _Arg2, _Arg3) }; \ - memcpy(aHead, _Gfx, sizeof(_Gfx)); \ - aHead += (sizeof(_Gfx) / sizeof(_Gfx[0])); \ - return; \ - } - -#define gfx_symbol_5(symb) \ - if (_Symbol == #symb) { \ - s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - s64 _Arg1 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - s64 _Arg2 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - s64 _Arg3 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - s64 _Arg4 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - Gfx _Gfx[] = { symb(_Arg0, _Arg1, _Arg2, _Arg3, _Arg4) }; \ - memcpy(aHead, _Gfx, sizeof(_Gfx)); \ - aHead += (sizeof(_Gfx) / sizeof(_Gfx[0])); \ - return; \ - } - -#define gfx_symbol_6(symb) \ - if (_Symbol == #symb) { \ - s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - s64 _Arg1 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - s64 _Arg2 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - s64 _Arg3 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - s64 _Arg4 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - s64 _Arg5 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - Gfx _Gfx[] = { symb(_Arg0, _Arg1, _Arg2, _Arg3, _Arg4, _Arg5) }; \ - memcpy(aHead, _Gfx, sizeof(_Gfx)); \ - aHead += (sizeof(_Gfx) / sizeof(_Gfx[0])); \ - return; \ - } - -#define gfx_symbol_7(symb) \ - if (_Symbol == #symb) { \ - s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - s64 _Arg1 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - s64 _Arg2 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - s64 _Arg3 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - s64 _Arg4 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - s64 _Arg5 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - s64 _Arg6 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - Gfx _Gfx[] = { symb(_Arg0, _Arg1, _Arg2, _Arg3, _Arg4, _Arg5, _Arg6) }; \ - memcpy(aHead, _Gfx, sizeof(_Gfx)); \ - aHead += (sizeof(_Gfx) / sizeof(_Gfx[0])); \ - return; \ - } - -#define gfx_symbol_8(symb) \ - if (_Symbol == #symb) { \ - s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - s64 _Arg1 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - s64 _Arg2 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - s64 _Arg3 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - s64 _Arg4 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - s64 _Arg5 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - s64 _Arg6 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - s64 _Arg7 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); \ - Gfx _Gfx[] = { symb(_Arg0, _Arg1, _Arg2, _Arg3, _Arg4, _Arg5, _Arg6, _Arg7) }; \ - memcpy(aHead, _Gfx, sizeof(_Gfx)); \ - aHead += (sizeof(_Gfx) / sizeof(_Gfx[0])); \ - return; \ - } - -#define gfx_arg_with_suffix(argname, suffix) \ - const String& argname##_token = aNode->mTokens[aTokenIndex]; \ - String _Token##suffix = String("%s%s", argname##_token.begin(), #suffix); \ - s64 argname = ParseGfxSymbolArg(aGfxData, aNode, NULL, _Token##suffix.begin()); \ - -#define STR_VALUE_2(...) #__VA_ARGS__ -#define STR_VALUE(...) STR_VALUE_2(__VA_ARGS__) -#define gfx_set_combine_mode_arg(x) if (_Arg == #x) { return String("%s", STR_VALUE(x)); } -static String ConvertSetCombineModeArgToString(GfxData *aGfxData, const String& _Arg) { - gfx_set_combine_mode_arg(G_CC_PRIMITIVE); - gfx_set_combine_mode_arg(G_CC_SHADE); - gfx_set_combine_mode_arg(G_CC_MODULATEI); - gfx_set_combine_mode_arg(G_CC_MODULATEIDECALA); - gfx_set_combine_mode_arg(G_CC_MODULATEIFADE); - gfx_set_combine_mode_arg(G_CC_MODULATERGB); - gfx_set_combine_mode_arg(G_CC_MODULATERGBDECALA); - gfx_set_combine_mode_arg(G_CC_MODULATERGBFADE); - gfx_set_combine_mode_arg(G_CC_MODULATEIA); - gfx_set_combine_mode_arg(G_CC_MODULATEIFADEA); - gfx_set_combine_mode_arg(G_CC_MODULATEFADE); - gfx_set_combine_mode_arg(G_CC_MODULATERGBA); - gfx_set_combine_mode_arg(G_CC_MODULATERGBFADEA); - gfx_set_combine_mode_arg(G_CC_MODULATEI_PRIM); - gfx_set_combine_mode_arg(G_CC_MODULATEIA_PRIM); - gfx_set_combine_mode_arg(G_CC_MODULATEIDECALA_PRIM); - gfx_set_combine_mode_arg(G_CC_MODULATERGB_PRIM); - gfx_set_combine_mode_arg(G_CC_MODULATERGBA_PRIM); - gfx_set_combine_mode_arg(G_CC_MODULATERGBDECALA_PRIM); - gfx_set_combine_mode_arg(G_CC_FADE); - gfx_set_combine_mode_arg(G_CC_FADEA); - gfx_set_combine_mode_arg(G_CC_DECALRGB); - gfx_set_combine_mode_arg(G_CC_DECALRGBA); - gfx_set_combine_mode_arg(G_CC_DECALFADE); - gfx_set_combine_mode_arg(G_CC_DECALFADEA); - gfx_set_combine_mode_arg(G_CC_BLENDI); - gfx_set_combine_mode_arg(G_CC_BLENDIA); - gfx_set_combine_mode_arg(G_CC_BLENDIDECALA); - gfx_set_combine_mode_arg(G_CC_BLENDRGBA); - gfx_set_combine_mode_arg(G_CC_BLENDRGBDECALA); - gfx_set_combine_mode_arg(G_CC_BLENDRGBFADEA); - gfx_set_combine_mode_arg(G_CC_ADDRGB); - gfx_set_combine_mode_arg(G_CC_ADDRGBDECALA); - gfx_set_combine_mode_arg(G_CC_ADDRGBFADE); - gfx_set_combine_mode_arg(G_CC_REFLECTRGB); - gfx_set_combine_mode_arg(G_CC_REFLECTRGBDECALA); - gfx_set_combine_mode_arg(G_CC_HILITERGB); - gfx_set_combine_mode_arg(G_CC_HILITERGBA); - gfx_set_combine_mode_arg(G_CC_HILITERGBDECALA); - gfx_set_combine_mode_arg(G_CC_SHADEDECALA); - gfx_set_combine_mode_arg(G_CC_SHADEFADEA); - gfx_set_combine_mode_arg(G_CC_BLENDPE); - gfx_set_combine_mode_arg(G_CC_BLENDPEDECALA); - gfx_set_combine_mode_arg(_G_CC_BLENDPE); - gfx_set_combine_mode_arg(_G_CC_BLENDPEDECALA); - gfx_set_combine_mode_arg(_G_CC_TWOCOLORTEX); - gfx_set_combine_mode_arg(_G_CC_SPARSEST); - gfx_set_combine_mode_arg(G_CC_TEMPLERP); - gfx_set_combine_mode_arg(G_CC_TRILERP); - gfx_set_combine_mode_arg(G_CC_INTERFERENCE); - gfx_set_combine_mode_arg(G_CC_1CYUV2RGB); - gfx_set_combine_mode_arg(G_CC_YUV2RGB); - gfx_set_combine_mode_arg(G_CC_PASS2); - gfx_set_combine_mode_arg(G_CC_MODULATEI2); - gfx_set_combine_mode_arg(G_CC_MODULATEIA2); - gfx_set_combine_mode_arg(G_CC_MODULATERGB2); - gfx_set_combine_mode_arg(G_CC_MODULATERGBA2); - gfx_set_combine_mode_arg(G_CC_MODULATEI_PRIM2); - gfx_set_combine_mode_arg(G_CC_MODULATEIA_PRIM2); - gfx_set_combine_mode_arg(G_CC_MODULATERGB_PRIM2); - gfx_set_combine_mode_arg(G_CC_MODULATERGBA_PRIM2); - gfx_set_combine_mode_arg(G_CC_DECALRGB2); - gfx_set_combine_mode_arg(G_CC_BLENDI2); - gfx_set_combine_mode_arg(G_CC_BLENDIA2); - gfx_set_combine_mode_arg(G_CC_CHROMA_KEY2); - gfx_set_combine_mode_arg(G_CC_HILITERGB2); - gfx_set_combine_mode_arg(G_CC_HILITERGBA2); - gfx_set_combine_mode_arg(G_CC_HILITERGBDECALA2); - gfx_set_combine_mode_arg(G_CC_HILITERGBPASSA2); - PrintError(" ERROR: Unknown gfx gsDPSetCombineMode arg: %s", _Arg.begin()); - return ""; -} - -static Array ParseGfxSetCombineMode(GfxData* aGfxData, DataNode* aNode, u64* pTokenIndex) { - String _Buffer = ConvertSetCombineModeArgToString(aGfxData, aNode->mTokens[(*pTokenIndex)++]); - Array _Args; - String _Token; - for (u64 i = 0, n = _Buffer.Length(); i <= n; ++i) { - if (i == n || _Buffer[i] == ' ' || _Buffer[i] == '\t' || _Buffer[i] == ',') { - if (_Token.Length() != 0) { - String _Arg("%s%s", (_Args.Count() < 4 ? "G_CCMUX_" : "G_ACMUX_"), _Token.begin()); - _Args.Add(ParseGfxSymbolArg(aGfxData, aNode, NULL, _Arg.begin())); - _Token.Clear(); - } - } else { - _Token.Add(_Buffer[i]); - } - } - if (_Args.Count() < 8) { - PrintError(" ERROR: gsDPSetCombineMode %s: Not enough arguments", _Buffer.begin()); - } - return _Args; -} - -static void UpdateTextureInfo(GfxData* aGfxData, s64 *aTexPtr, s32 aFormat, s32 aSize, s32 aWidth, s32 aHeight) { - - // Update current texture pointers - if (aTexPtr && (*aTexPtr)) { - aGfxData->mGfxContext.mCurrentPalette = aGfxData->mGfxContext.mCurrentTexture; - aGfxData->mGfxContext.mCurrentTexture = (DataNode*) (*aTexPtr); - } - - // Update texture info if not loaded from a file - if (aGfxData->mGfxContext.mCurrentTexture && aGfxData->mGfxContext.mCurrentTexture->mData && aGfxData->mGfxContext.mCurrentTexture->mData->mPngData.Empty()) { - if (aFormat != -1) aGfxData->mGfxContext.mCurrentTexture->mData->mRawFormat = aFormat; - if (aSize != -1) aGfxData->mGfxContext.mCurrentTexture->mData->mRawSize = aSize; - if (aWidth != -1) aGfxData->mGfxContext.mCurrentTexture->mData->mRawWidth = aWidth; - if (aHeight != -1) aGfxData->mGfxContext.mCurrentTexture->mData->mRawHeight = aHeight; - } -} - -static void ParseGfxSymbol(GfxData* aGfxData, DataNode* aNode, Gfx*& aHead, u64& aTokenIndex) { - const String& _Symbol = aNode->mTokens[aTokenIndex++]; - - // Simple symbols - gfx_symbol_0(gsDPFullSync); - gfx_symbol_0(gsDPTileSync); - gfx_symbol_0(gsDPPipeSync); - gfx_symbol_0(gsDPLoadSync); - gfx_symbol_0(gsDPNoOp); - gfx_symbol_1(gsDPNoOpTag, false); - gfx_symbol_1(gsDPSetCycleType, false); - gfx_symbol_2(gsSPLight, true); - gfx_symbol_3(gsSPVertex, true); - gfx_symbol_4(gsSP1Triangle); - gfx_symbol_8(gsSP2Triangles); - gfx_symbol_1(gsSPNumLights, false); - gfx_symbol_1(gsDPSetDepthSource, false); - gfx_symbol_1(gsDPSetTextureLUT, false); - gfx_symbol_2(gsDPLoadTLUTCmd, false); - gfx_symbol_5(gsDPLoadBlock); - gfx_symbol_2(gsDPSetRenderMode, false); - gfx_symbol_2(gsSPGeometryMode, false); - gfx_symbol_6(gsDPSetPrimColor); - gfx_symbol_4(gsDPSetEnvColor); - gfx_symbol_4(gsDPSetFogColor); - gfx_symbol_2(gsSPFogPosition, false); - gfx_symbol_1(gsDPSetAlphaCompare, false); - gfx_symbol_2(gsSPCopyLightEXT, false); - - // Special symbols - if (_Symbol == "gsSPTexture") { - s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _Arg1 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _Arg2 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _Arg3 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _Arg4 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - gSPTexture(aHead++, _Arg0, _Arg1, _Arg2, _Arg3, _Arg4); - return; - } - if (_Symbol == "gsSPSetGeometryMode") { - s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - gSPSetGeometryMode(aHead++, _Arg0); - return; - } - if (_Symbol == "gsSPClearGeometryMode") { - s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - gSPClearGeometryMode(aHead++, _Arg0); - return; - } - if (_Symbol == "gsSPDisplayList") { - s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - aGfxData->mPointerList.Add(aHead); - gSPDisplayList(aHead++, _Arg0); - return; - } - if (_Symbol == "gsSPBranchList") { - s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - aGfxData->mPointerList.Add(aHead); - gSPBranchList(aHead++, _Arg0); - return; - } - if (_Symbol == "gsSPEndDisplayList") { - gSPEndDisplayList(aHead++); - - // Convert raw texture to PNG if all raw members are set - if (aGfxData->mGfxContext.mCurrentTexture != NULL && - aGfxData->mGfxContext.mCurrentTexture->mData != NULL && - aGfxData->mGfxContext.mCurrentTexture->mData->mPngData.Empty() && - aGfxData->mGfxContext.mCurrentTexture->mData->mRawFormat != -1 && - aGfxData->mGfxContext.mCurrentTexture->mData->mRawSize != -1 && - aGfxData->mGfxContext.mCurrentTexture->mData->mRawWidth != -1 && - aGfxData->mGfxContext.mCurrentTexture->mData->mRawHeight != -1) { - ConvertTextureDataToPng(aGfxData, aGfxData->mGfxContext.mCurrentTexture->mData); - } - - // End the display list parsing after hitting gsSPEndDisplayList - aTokenIndex = 0x7FFFFFFF; - return; - } - - // Complex symbols - if (_Symbol == "gsSPSetLights1") { - Lights1 *_Light = (Lights1 *) ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - gSPNumLights(aHead++, NUMLIGHTS_1); - aGfxData->mPointerList.Add(aHead); - gSPLight(aHead++, &_Light->l[0], 1); - aGfxData->mPointerList.Add(aHead); - gSPLight(aHead++, &_Light->a, 2); - return; - } - if (_Symbol == "gsDPSetCombineMode") { - Array _Args0 = ParseGfxSetCombineMode(aGfxData, aNode, &aTokenIndex); - Array _Args1 = ParseGfxSetCombineMode(aGfxData, aNode, &aTokenIndex); - Gfx _Gfx = {{ - _SHIFTL(G_SETCOMBINE, 24, 8) | _SHIFTL(GCCc0w0(_Args0[0x0], _Args0[0x2], _Args0[0x4], _Args0[0x6]) | GCCc1w0(_Args1[0x0], _Args1[0x2]), 0, 24), - (u32) (GCCc0w1(_Args0[0x1], _Args0[0x3], _Args0[0x5], _Args0[0x7]) | GCCc1w1(_Args1[0x1], _Args1[0x4], _Args1[0x6], _Args1[0x3], _Args1[0x5], _Args1[0x7])) - }}; - *(aHead++) = _Gfx; - return; - } - if (_Symbol == "gsDPSetCombineLERP") { - s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, "G_CCMUX_"); - s64 _Arg1 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, "G_CCMUX_"); - s64 _Arg2 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, "G_CCMUX_"); - s64 _Arg3 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, "G_CCMUX_"); - s64 _Arg4 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, "G_ACMUX_"); - s64 _Arg5 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, "G_ACMUX_"); - s64 _Arg6 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, "G_ACMUX_"); - s64 _Arg7 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, "G_ACMUX_"); - s64 _Arg8 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, "G_CCMUX_"); - s64 _Arg9 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, "G_CCMUX_"); - s64 _ArgA = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, "G_CCMUX_"); - s64 _ArgB = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, "G_CCMUX_"); - s64 _ArgC = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, "G_ACMUX_"); - s64 _ArgD = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, "G_ACMUX_"); - s64 _ArgE = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, "G_ACMUX_"); - s64 _ArgF = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, "G_ACMUX_"); - Gfx _Gfx = {{ - _SHIFTL(G_SETCOMBINE, 24, 8) | _SHIFTL(GCCc0w0(_Arg0, _Arg2, _Arg4, _Arg6) | GCCc1w0(_Arg8, _ArgA), 0, 24), - (u32) (GCCc0w1(_Arg1, _Arg3, _Arg5, _Arg7) | GCCc1w1(_Arg9, _ArgC, _ArgE, _ArgB, _ArgD, _ArgF)) - }}; - *(aHead++) = _Gfx; - return; - } - - // TexData symbols - if (_Symbol == "gsDPSetTextureImage") { - s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _Arg1 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _Arg2 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _Arg3 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - UpdateTextureInfo(aGfxData, &_Arg3, (s32) _Arg0, (s32) _Arg1, -1, -1); - aGfxData->mPointerList.Add(aHead); - gDPSetTextureImage(aHead++, _Arg0, _Arg1, _Arg2, _Arg3); - return; - } - if (_Symbol == "gsDPSetTile") { - s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _Arg1 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _Arg2 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _Arg3 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _Arg4 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _Arg5 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _Arg6 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _Arg7 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _Arg8 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _Arg9 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _ArgA = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _ArgB = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - UpdateTextureInfo(aGfxData, NULL, (s32) _Arg0, (s32) _Arg1, -1, -1); - gDPSetTile(aHead++, _Arg0, _Arg1, _Arg2, _Arg3, _Arg4, _Arg5, _Arg6, _Arg7, _Arg8, _Arg9, _ArgA, _ArgB); - return; - } - if (_Symbol == "gsDPLoadTile") { - s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _Arg1 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _Arg2 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _Arg3 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _Arg4 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - UpdateTextureInfo(aGfxData, NULL, -1, -1, (s32) (_Arg3 >> G_TEXTURE_IMAGE_FRAC) + 1, (s32) (_Arg4 >> G_TEXTURE_IMAGE_FRAC) + 1); - gDPLoadTile(aHead++, _Arg0, _Arg1, _Arg2, _Arg3, _Arg4); - return; - } - if (_Symbol == "gsDPSetTileSize") { - s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _Arg1 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _Arg2 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _Arg3 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _Arg4 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - UpdateTextureInfo(aGfxData, NULL, -1, -1, (s32) (_Arg3 >> G_TEXTURE_IMAGE_FRAC) + 1, (s32) (_Arg4 >> G_TEXTURE_IMAGE_FRAC) + 1); - gDPSetTileSize(aHead++, _Arg0, _Arg1, _Arg2, _Arg3, _Arg4); - return; - } - if (_Symbol == "gsDPLoadTextureBlock") { - s64 _Arg0 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _Arg1 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - gfx_arg_with_suffix(arg2_0, _LOAD_BLOCK); - gfx_arg_with_suffix(arg2_1, _INCR); - gfx_arg_with_suffix(arg2_2, _SHIFT); - gfx_arg_with_suffix(arg2_3, _BYTES); - gfx_arg_with_suffix(arg2_4, _LINE_BYTES); - s64 _Arg2 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _Arg3 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _Arg4 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _Arg5 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _Arg6 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _Arg7 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _Arg8 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _Arg9 = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _ArgA = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - s64 _ArgB = ParseGfxSymbolArg(aGfxData, aNode, &aTokenIndex, ""); - UpdateTextureInfo(aGfxData, &_Arg0, (s32) _Arg1, (s32) _Arg2, (s32) _Arg3, (s32) _Arg4); - - aGfxData->mPointerList.Add(aHead); - gDPSetTextureImage(aHead++, _Arg1, arg2_0, 1, _Arg0); - gDPSetTile(aHead++, _Arg1, arg2_0, 0, 0, G_TX_LOADTILE, 0, _Arg7, _Arg9, _ArgB, _Arg6, _Arg8, _ArgA); - gDPLoadSync(aHead++); - gDPLoadBlock(aHead++, G_TX_LOADTILE, 0, 0, (((_Arg3) * (_Arg4) + arg2_1) >> arg2_2) - 1, CALC_DXT(_Arg3, arg2_3)); - gDPPipeSync(aHead++); - gDPSetTile(aHead++, _Arg1, _Arg2, ((((_Arg3) * arg2_4) + 7) >> 3), 0, G_TX_RENDERTILE, _Arg5, _Arg7, _Arg9, _ArgB, _Arg6, _Arg8, _ArgA); - gDPSetTileSize(aHead++, G_TX_RENDERTILE, 0, 0, ((_Arg3) - 1) << G_TEXTURE_IMAGE_FRAC, ((_Arg4) - 1) << G_TEXTURE_IMAGE_FRAC); - return; - } - - // Unknown - PrintError(" ERROR: Unknown gfx symbol: %s", _Symbol.begin()); -} - -static DataNode* ParseDisplayListData(GfxData* aGfxData, DataNode* aNode) { - if (aNode->mData) return aNode; - - // Display list data - aNode->mData = New(aNode->mTokens.Count() * DISPLAY_LIST_SIZE_PER_TOKEN); - Gfx* _Head = aNode->mData; - for (u64 _TokenIndex = 0; _TokenIndex < aNode->mTokens.Count();) { // Don't increment _TokenIndex here! - ParseGfxSymbol(aGfxData, aNode, _Head, _TokenIndex); - } - aNode->mSize = (u32) (_Head - aNode->mData); - aNode->mLoadIndex = aGfxData->mLoadIndex++; - return aNode; -} - -// -// Geo layouts -// - -#define geo_constant(x) if (_Arg == #x) { return (s64) (x); } -static s64 ParseGeoSymbolArg(GfxData* aGfxData, DataNode* aNode, u64& aTokenIndex) { - const String& _Arg = aNode->mTokens[aTokenIndex++]; - - // Geo functions - void *_GeoFunctionPtr = DynOS_Geo_GetFunctionPointerFromName(_Arg); - if (_GeoFunctionPtr != NULL) { - return (s64) _GeoFunctionPtr; - } - - // Layer constants - geo_constant(LAYER_FORCE); - geo_constant(LAYER_OPAQUE); - geo_constant(LAYER_OPAQUE_DECAL); - geo_constant(LAYER_OPAQUE_INTER); - geo_constant(LAYER_ALPHA); - geo_constant(LAYER_TRANSPARENT); - geo_constant(LAYER_TRANSPARENT_DECAL); - geo_constant(LAYER_TRANSPARENT_INTER); - - // Background constants - geo_constant(BACKGROUND_OCEAN_SKY); - geo_constant(BACKGROUND_FLAMING_SKY); - geo_constant(BACKGROUND_UNDERWATER_CITY); - geo_constant(BACKGROUND_BELOW_CLOUDS); - geo_constant(BACKGROUND_SNOW_MOUNTAINS); - geo_constant(BACKGROUND_DESERT); - geo_constant(BACKGROUND_HAUNTED); - geo_constant(BACKGROUND_GREEN_SKY); - geo_constant(BACKGROUND_ABOVE_CLOUDS); - geo_constant(BACKGROUND_PURPLE_SKY); - - // Shadow constants - geo_constant(SHADOW_CIRCLE_9_VERTS); - geo_constant(SHADOW_CIRCLE_4_VERTS); - geo_constant(SHADOW_CIRCLE_4_VERTS_FLAT_UNUSED); - geo_constant(SHADOW_SQUARE_PERMANENT); - geo_constant(SHADOW_SQUARE_SCALABLE); - geo_constant(SHADOW_SQUARE_TOGGLABLE); - geo_constant(SHADOW_RECTANGLE_HARDCODED_OFFSET); - geo_constant(SHADOW_CIRCLE_PLAYER); - - // Other constants - geo_constant(NULL); - geo_constant(SCREEN_WIDTH); - geo_constant(SCREEN_HEIGHT); - geo_constant(SCREEN_WIDTH/2); - geo_constant(SCREEN_HEIGHT/2); - - // Display lists - for (auto& _Node : aGfxData->mDisplayLists) { - if (_Arg == _Node->mName) { - return (s64) ParseDisplayListData(aGfxData, _Node); - } - } - - // Geo layouts - for (auto& _Node : aGfxData->mGeoLayouts) { - if (_Arg == _Node->mName) { - return (s64) ParseGeoLayoutData(aGfxData, _Node, false)->mData; - } - } - - // Integers - s32 x; - if ((_Arg[1] == 'x' && sscanf(_Arg.begin(), "%x", &x) == 1) || (sscanf(_Arg.begin(), "%d", &x) == 1)) { - return (s64) x; - } - - // Unknown - PrintError(" ERROR: Unknown geo arg: %s", _Arg.begin()); - return 0; -} - -#define geo_symbol_0(symb) \ - if (_Symbol == #symb) { \ - GeoLayout _Gl[] = { symb() }; \ - memcpy(aHead, _Gl, sizeof(_Gl)); \ - aHead += (sizeof(_Gl) / sizeof(_Gl[0])); \ - return; \ - } - -#define geo_symbol_1(symb, n) \ - if (_Symbol == #symb) { \ - s64 _Arg0 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - if (n != 0) { aGfxData->mPointerList.Add(aHead + n); } \ - GeoLayout _Gl[] = { symb(_Arg0) }; \ - memcpy(aHead, _Gl, sizeof(_Gl)); \ - aHead += (sizeof(_Gl) / sizeof(_Gl[0])); \ - return; \ - } - -#define geo_symbol_2(symb, n) \ - if (_Symbol == #symb) { \ - s64 _Arg0 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - s64 _Arg1 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - if (n != 0) { aGfxData->mPointerList.Add(aHead + n); } \ - GeoLayout _Gl[] = { symb(_Arg0, _Arg1) }; \ - memcpy(aHead, _Gl, sizeof(_Gl)); \ - aHead += (sizeof(_Gl) / sizeof(_Gl[0])); \ - return; \ - } - -#define geo_symbol_3(symb, n) \ - if (_Symbol == #symb) { \ - s64 _Arg0 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - s64 _Arg1 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - s64 _Arg2 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - if (n != 0) { aGfxData->mPointerList.Add(aHead + n); } \ - GeoLayout _Gl[] = { symb(_Arg0, _Arg1, _Arg2) }; \ - memcpy(aHead, _Gl, sizeof(_Gl)); \ - aHead += (sizeof(_Gl) / sizeof(_Gl[0])); \ - return; \ - } - -#define geo_symbol_4(symb, n) \ - if (_Symbol == #symb) { \ - s64 _Arg0 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - s64 _Arg1 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - s64 _Arg2 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - s64 _Arg3 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - if (n != 0) { aGfxData->mPointerList.Add(aHead + n); } \ - GeoLayout _Gl[] = { symb(_Arg0, _Arg1, _Arg2, _Arg3) }; \ - memcpy(aHead, _Gl, sizeof(_Gl)); \ - aHead += (sizeof(_Gl) / sizeof(_Gl[0])); \ - return; \ - } - -#define geo_symbol_5(symb, n) \ - if (_Symbol == #symb) { \ - s64 _Arg0 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - s64 _Arg1 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - s64 _Arg2 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - s64 _Arg3 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - s64 _Arg4 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - if (n != 0) { aGfxData->mPointerList.Add(aHead + n); } \ - GeoLayout _Gl[] = { symb(_Arg0, _Arg1, _Arg2, _Arg3, _Arg4) }; \ - memcpy(aHead, _Gl, sizeof(_Gl)); \ - aHead += (sizeof(_Gl) / sizeof(_Gl[0])); \ - return; \ - } - -#define geo_symbol_6(symb, n) \ - if (_Symbol == #symb) { \ - s64 _Arg0 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - s64 _Arg1 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - s64 _Arg2 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - s64 _Arg3 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - s64 _Arg4 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - s64 _Arg5 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - if (n != 0) { aGfxData->mPointerList.Add(aHead + n); } \ - GeoLayout _Gl[] = { symb(_Arg0, _Arg1, _Arg2, _Arg3, _Arg4, _Arg5) }; \ - memcpy(aHead, _Gl, sizeof(_Gl)); \ - aHead += (sizeof(_Gl) / sizeof(_Gl[0])); \ - return; \ - } - -#define geo_symbol_7(symb, n) \ - if (_Symbol == #symb) { \ - s64 _Arg0 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - s64 _Arg1 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - s64 _Arg2 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - s64 _Arg3 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - s64 _Arg4 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - s64 _Arg5 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - s64 _Arg6 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - if (n != 0) { aGfxData->mPointerList.Add(aHead + n); } \ - GeoLayout _Gl[] = { symb(_Arg0, _Arg1, _Arg2, _Arg3, _Arg4, _Arg5, _Arg6) }; \ - memcpy(aHead, _Gl, sizeof(_Gl)); \ - aHead += (sizeof(_Gl) / sizeof(_Gl[0])); \ - return; \ - } - -#define geo_symbol_8(symb, n) \ - if (_Symbol == #symb) { \ - s64 _Arg0 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - s64 _Arg1 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - s64 _Arg2 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - s64 _Arg3 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - s64 _Arg4 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - s64 _Arg5 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - s64 _Arg6 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - s64 _Arg7 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); \ - if (n != 0) { aGfxData->mPointerList.Add(aHead + n); } \ - GeoLayout _Gl[] = { symb(_Arg0, _Arg1, _Arg2, _Arg3, _Arg4, _Arg5, _Arg6, _Arg7) }; \ - memcpy(aHead, _Gl, sizeof(_Gl)); \ - aHead += (sizeof(_Gl) / sizeof(_Gl[0])); \ - return; \ - } - -static void ParseGeoSymbol(GfxData* aGfxData, DataNode* aNode, GeoLayout*& aHead, u64& aTokenIndex, Array& aSwitchNodes) { - const String& _Symbol = aNode->mTokens[aTokenIndex++]; - - // Restore context after each command if inside a switch - if (!aSwitchNodes.Empty() && !aGfxData->mGeoNodeStack.Empty()) { - aGfxData->mGfxContext = aGfxData->mGeoNodeStack[aGfxData->mGeoNodeStack.Count() - 1]; - } - - geo_symbol_1(GEO_BRANCH_AND_LINK, 1); - geo_symbol_0(GEO_END); - geo_symbol_2(GEO_BRANCH, 1); - geo_symbol_0(GEO_RETURN); - geo_symbol_5(GEO_NODE_SCREEN_AREA, 0); - geo_symbol_1(GEO_NODE_ORTHO, 0); - geo_symbol_3(GEO_CAMERA_FRUSTUM, 0); - geo_symbol_4(GEO_CAMERA_FRUSTUM_WITH_FUNC, 2); - geo_symbol_0(GEO_NODE_START); - geo_symbol_1(GEO_ZBUFFER, 0); - geo_symbol_2(GEO_RENDER_RANGE, 0); - geo_symbol_8(GEO_CAMERA, 4); - geo_symbol_7(GEO_TRANSLATE_ROTATE, 0); - geo_symbol_8(GEO_TRANSLATE_ROTATE_WITH_DL, 4); - geo_symbol_4(GEO_TRANSLATE, 0); - geo_symbol_5(GEO_TRANSLATE_WITH_DL, 2); - geo_symbol_4(GEO_ROTATE, 0); - geo_symbol_5(GEO_ROTATE_WITH_DL, 2); - geo_symbol_2(GEO_ROTATE_Y, 0); - geo_symbol_3(GEO_ROTATE_Y_WITH_DL, 1); - geo_symbol_4(GEO_TRANSLATE_NODE, 0); - geo_symbol_5(GEO_TRANSLATE_NODE_WITH_DL, 2); - geo_symbol_4(GEO_ROTATION_NODE, 0); - geo_symbol_5(GEO_ROTATION_NODE_WITH_DL, 2); - geo_symbol_5(GEO_ANIMATED_PART, 2); - geo_symbol_4(GEO_BILLBOARD_WITH_PARAMS, 0); - geo_symbol_5(GEO_BILLBOARD_WITH_PARAMS_AND_DL, 2); - geo_symbol_0(GEO_BILLBOARD); - geo_symbol_2(GEO_DISPLAY_LIST, 1); - geo_symbol_3(GEO_SHADOW, 0); - geo_symbol_0(GEO_RENDER_OBJ); - geo_symbol_2(GEO_ASM, 1); - geo_symbol_2(GEO_BACKGROUND, 1); - geo_symbol_1(GEO_BACKGROUND_COLOR, 0); - geo_symbol_0(GEO_NOP_1A); - geo_symbol_5(GEO_HELD_OBJECT, 2); - geo_symbol_2(GEO_SCALE, 0); - geo_symbol_3(GEO_SCALE_WITH_DL, 2); - geo_symbol_0(GEO_NOP_1E); - geo_symbol_0(GEO_NOP_1F); - geo_symbol_1(GEO_CULLING_RADIUS, 0); - - // Switch node - if (_Symbol == "GEO_SWITCH_CASE") { - - // Start a switch - aSwitchNodes.Add(0); - - s64 _Arg0 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); - s64 _Arg1 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); - aGfxData->mPointerList.Add(aHead + 1); - GeoLayout _Gl[] = { GEO_SWITCH_CASE(_Arg0, _Arg1) }; - memcpy(aHead, _Gl, sizeof(_Gl)); - aHead += (sizeof(_Gl) / sizeof(_Gl[0])); - return; - } - - // Open node - if (_Symbol == "GEO_OPEN_NODE") { - - // We're inside a switch - if (!aSwitchNodes.Empty()) { - aSwitchNodes[aSwitchNodes.Count() - 1]++; - } - - // Push context - aGfxData->mGeoNodeStack.Add(aGfxData->mGfxContext); - - *(aHead++) = GEO_OPEN_NODE(); - return; - } - - // Close node - if (_Symbol == "GEO_CLOSE_NODE") { - - // Are we still inside a switch? - if (!aSwitchNodes.Empty()) { - aSwitchNodes[aSwitchNodes.Count() - 1]--; - - // We're not anymore - if (aSwitchNodes[aSwitchNodes.Count() - 1] == 0) { - aSwitchNodes.Pop(); - } - } - - // Pop context - if (!aGfxData->mGeoNodeStack.Empty()) { - aGfxData->mGfxContext = aGfxData->mGeoNodeStack[aGfxData->mGeoNodeStack.Count() - 1]; - aGfxData->mGeoNodeStack.Pop(); - } - - *(aHead++) = GEO_CLOSE_NODE(); - return; - } - - // Unknown - PrintError(" ERROR: Unknown geo symbol: %s", _Symbol.begin()); -} - -static DataNode* ParseGeoLayoutData(GfxData* aGfxData, DataNode* aNode, bool aDisplayPercent) { - if (aNode->mData) return aNode; - - // Geo layout data - aNode->mData = New(aNode->mTokens.Count() * GEO_LAYOUT_SIZE_PER_TOKEN); - GeoLayout* _Head = aNode->mData; - Array _SwitchNodes; - for (u64 _TokenIndex = 0; _TokenIndex < aNode->mTokens.Count();) { // Don't increment _TokenIndex here! - ParseGeoSymbol(aGfxData, aNode, _Head, _TokenIndex, _SwitchNodes); - if (aDisplayPercent && aGfxData->mErrorCount == 0) { PrintNoNewLine("%3d%%\b\b\b\b", (s32) (_TokenIndex * 100) / aNode->mTokens.Count()); } - } - if (aDisplayPercent && aGfxData->mErrorCount == 0) { Print("100%%"); } - aNode->mSize = (u32)(_Head - aNode->mData); - aNode->mLoadIndex = aGfxData->mLoadIndex++; - return aNode; -} - // // Animation files // @@ -1791,15 +450,6 @@ static void ClearGfxDataNodes(DataNodes &aDataNodes) { } } -static DataNode *GetGeoLayout(GfxData *aGfxData, const String& aGeoRoot) { - for (DataNode *_Node : aGfxData->mGeoLayouts) { - if (_Node->mName == aGeoRoot) { - return _Node; - } - } - return NULL; -} - static String GetActorFolder(const Array> &aActorsFolders, u64 aModelIdentifier) { for (const auto &_Pair : aActorsFolders) { if (_Pair.first == aModelIdentifier) { @@ -1809,78 +459,101 @@ static String GetActorFolder(const Array> &aActorsFolders, u64 return String(); } -static bool DynOS_Gfx_GeneratePack_Internal(const SysPath &aPackFolder, Array> _ActorsFolders, GfxData *_GfxData) { - bool generated = false; +static void DynOS_Col_Generate(const SysPath &aPackFolder, Array> _ActorsFolders, GfxData *_GfxData) { + for (auto &_ColNode : _GfxData->mCollisions) { + String _ColRootName = _ColNode->mName; + + // 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())) { + continue; + } + + // Init + _GfxData->mErrorCount = 0; + _GfxData->mLoadIndex = 0; + + // Parse data + PrintNoNewLine("%s.col: Model identifier: %X - Processing... ", _ColRootName.begin(), _GfxData->mModelIdentifier); + DynOS_Col_Parse(_GfxData, _ColNode, true); + + // Write if no error + if (_GfxData->mErrorCount == 0) { + DynOS_Col_WriteBinary(_ColFilename, _GfxData, _ColNode); + } else { + Print(" %u error(s): Unable to parse data", _GfxData->mErrorCount); + } + + // Clear data pointers + ClearGfxDataNodes(_GfxData->mCollisions); + } +} + +static void DynOS_Actor_Generate(const SysPath &aPackFolder, Array> _ActorsFolders, GfxData *_GfxData) { for (auto &_GeoNode : _GfxData->mGenerateGeoLayouts) { String _GeoRootName = _GeoNode->mName; - DataNode *_GeoRoot = GetGeoLayout(_GfxData, _GeoRootName); - if (_GeoRoot != NULL) { + // 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())) { + continue; + } - // 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())) { - continue; - } + // Init + _GfxData->mLoadIndex = 0; + _GfxData->mErrorCount = 0; + _GfxData->mModelIdentifier = _GeoNode->mModelIdentifier; + _GfxData->mPackFolder = aPackFolder; + _GfxData->mPointerList = { NULL }; // The NULL pointer is needed, so we add it here + _GfxData->mGfxContext.mCurrentTexture = NULL; + _GfxData->mGfxContext.mCurrentPalette = NULL; + _GfxData->mGeoNodeStack.Clear(); - // Init - _GfxData->mLoadIndex = 0; - _GfxData->mErrorCount = 0; - _GfxData->mModelIdentifier = _GeoRoot->mModelIdentifier; - _GfxData->mPackFolder = aPackFolder; - _GfxData->mPointerList = { NULL }; // The NULL pointer is needed, so we add it here - _GfxData->mGfxContext.mCurrentTexture = NULL; - _GfxData->mGfxContext.mCurrentPalette = NULL; - _GfxData->mGeoNodeStack.Clear(); + // Parse data + PrintNoNewLine("%s.bin: Model identifier: %X - Processing... ", _GeoRootName.begin(), _GfxData->mModelIdentifier); + DynOS_Geo_Parse(_GfxData, _GeoNode, true); - // Parse data - PrintNoNewLine("%s.bin: Model identifier: %X - Processing... ", _GeoRootName.begin(), _GfxData->mModelIdentifier); - ParseGeoLayoutData(_GfxData, _GeoRoot, true); + // Init animation data + for (auto &_AnimBuffer : _GfxData->mAnimValues) Delete(_AnimBuffer); + for (auto &_AnimBuffer : _GfxData->mAnimIndices) Delete(_AnimBuffer); + for (auto &_AnimNode : _GfxData->mAnimations) Delete(_AnimNode); + _GfxData->mAnimValues.Clear(); + _GfxData->mAnimIndices.Clear(); + _GfxData->mAnimations.Clear(); + _GfxData->mAnimationTable.Clear(); - // Init animation data - for (auto &_AnimBuffer : _GfxData->mAnimValues) Delete(_AnimBuffer); - for (auto &_AnimBuffer : _GfxData->mAnimIndices) Delete(_AnimBuffer); - for (auto &_AnimNode : _GfxData->mAnimations) Delete(_AnimNode); - _GfxData->mAnimValues.Clear(); - _GfxData->mAnimIndices.Clear(); - _GfxData->mAnimations.Clear(); - _GfxData->mAnimationTable.Clear(); + // Scan anims folder for animation data + String _ActorFolder = GetActorFolder(_ActorsFolders, _GfxData->mModelIdentifier); + SysPath _AnimsFolder = fstring("%s/%s/anims", aPackFolder.c_str(), _ActorFolder.begin()); + ScanAnimationFolder(_GfxData, _AnimsFolder); - // Scan anims folder for animation data - String _ActorFolder = GetActorFolder(_ActorsFolders, _GfxData->mModelIdentifier); - SysPath _AnimsFolder = fstring("%s/%s/anims", aPackFolder.c_str(), _ActorFolder.begin()); - ScanAnimationFolder(_GfxData, _AnimsFolder); - - // Create table for player model animations - if ((_GeoRootName == "mario_geo" || _GeoRootName == "luigi_geo" || _GeoRootName == "toad_player_geo" || _GeoRootName == "wario_geo" || _GeoRootName == "waluigi_geo") && !_GfxData->mAnimations.Empty()) { - _GfxData->mAnimationTable.Resize(256); - for (s32 i = 0; i != 256; ++i) { - String _AnimName("anim_%02X", i); - if (_GfxData->mAnimations.FindIf([&_AnimName](const DataNode *aNode) { return aNode->mName == _AnimName; }) != -1) { - _GfxData->mAnimationTable[i] = { _AnimName, NULL }; - } else { - _GfxData->mAnimationTable[i] = { "NULL", NULL }; - } + // Create table for player model animations + if ((_GeoRootName == "mario_geo" || _GeoRootName == "luigi_geo" || _GeoRootName == "toad_player_geo" || _GeoRootName == "wario_geo" || _GeoRootName == "waluigi_geo") && !_GfxData->mAnimations.Empty()) { + _GfxData->mAnimationTable.Resize(256); + for (s32 i = 0; i != 256; ++i) { + String _AnimName("anim_%02X", i); + if (_GfxData->mAnimations.FindIf([&_AnimName](const DataNode *aNode) { return aNode->mName == _AnimName; }) != -1) { + _GfxData->mAnimationTable[i] = { _AnimName, NULL }; + } else { + _GfxData->mAnimationTable[i] = { "NULL", NULL }; } } - - // Write if no error - if (_GfxData->mErrorCount == 0) { - DynOS_Gfx_WriteBinary(_BinFilename, _GfxData); - } else { - Print(" %u error(s): Unable to parse data", _GfxData->mErrorCount); - } - // Clear data pointers - ClearGfxDataNodes(_GfxData->mLights); - ClearGfxDataNodes(_GfxData->mTextures); - ClearGfxDataNodes(_GfxData->mVertices); - ClearGfxDataNodes(_GfxData->mDisplayLists); - ClearGfxDataNodes(_GfxData->mGeoLayouts); - ClearGfxDataNodes(_GfxData->mCollisions); - generated = true; } + + // Write if no error + if (_GfxData->mErrorCount == 0) { + DynOS_Gfx_WriteBinary(_BinFilename, _GfxData); + } else { + Print(" %u error(s): Unable to parse data", _GfxData->mErrorCount); + } + // Clear data pointers + ClearGfxDataNodes(_GfxData->mLights); + ClearGfxDataNodes(_GfxData->mTextures); + ClearGfxDataNodes(_GfxData->mVertices); + ClearGfxDataNodes(_GfxData->mDisplayLists); + ClearGfxDataNodes(_GfxData->mGeoLayouts); + ClearGfxDataNodes(_GfxData->mCollisions); } - return generated; } void DynOS_Gfx_GeneratePack(const SysPath &aPackFolder) { @@ -1915,8 +588,8 @@ void DynOS_Gfx_GeneratePack(const SysPath &aPackFolder) { } // Generate a binary file for each actor found in the GfxData - DynOS_Col_GeneratePack(aPackFolder, _ActorsFolders, _GfxData); - DynOS_Gfx_GeneratePack_Internal(aPackFolder, _ActorsFolders, _GfxData); + DynOS_Col_Generate(aPackFolder, _ActorsFolders, _GfxData); + DynOS_Actor_Generate(aPackFolder, _ActorsFolders, _GfxData); DynOS_Gfx_Free(_GfxData); } @@ -1943,7 +616,7 @@ void DynOS_Lvl_GeneratePack(const SysPath &aPackFolder) { ScanModelFile(_GfxData, fstring("%s/area_1/collision.inc.c", _Folder.c_str())); ScanModelFile(_GfxData, fstring("%s/area_1/geo.inc.c", _Folder.c_str())); ScanModelFile(_GfxData, fstring("%s/script.c", _Folder.c_str())); - //ScanModelFile(_GfxData, fstring("%s/area_1/macro.inc.c", _Folder.c_str())); + ScanModelFile(_GfxData, fstring("%s/area_1/macro.inc.c", _Folder.c_str())); } } closedir(aPackDir); @@ -1954,5 +627,3 @@ void DynOS_Lvl_GeneratePack(const SysPath &aPackFolder) { DynOS_Gfx_Free(_GfxData); } - -#pragma GCC diagnostic pop diff --git a/include/behavior_data.h b/include/behavior_data.h index 3c44f4003..4eb2c0d0e 100644 --- a/include/behavior_data.h +++ b/include/behavior_data.h @@ -90,7 +90,6 @@ extern const BehaviorScript bhvWaterMist2[]; extern const BehaviorScript bhvUnused0DFC[]; extern const BehaviorScript bhvMistCircParticleSpawner[]; extern const BehaviorScript bhvDirtParticleSpawner[]; -extern const BehaviorScript bhvUnused0E40[]; extern const BehaviorScript bhvSnowParticleSpawner[]; extern const BehaviorScript bhvWind[]; extern const BehaviorScript bhvEndToad[]; @@ -212,17 +211,14 @@ extern const BehaviorScript bhvSmallPenguin[]; extern const BehaviorScript bhvManyBlueFishSpawner[]; extern const BehaviorScript bhvFewBlueFishSpawner[]; extern const BehaviorScript bhvFishSpawner[]; -extern const BehaviorScript bhvFishCommon[]; extern const BehaviorScript bhvFish[]; extern const BehaviorScript bhvWdwExpressElevator[]; extern const BehaviorScript bhvWdwExpressElevatorPlatform[]; extern const BehaviorScript bhvChirpChirp[]; extern const BehaviorScript bhvChirpChirpUnused[]; extern const BehaviorScript bhvBub[]; -extern const BehaviorScript bhvCheepCheep[]; extern const BehaviorScript bhvExclamationBox[]; extern const BehaviorScript bhvRotatingExclamationMark[]; -extern const BehaviorScript bhvPlaysSound[]; extern const BehaviorScript bhvSoundSpawner[]; extern const BehaviorScript bhvRockSolid[]; extern const BehaviorScript bhvBowserSubDoor[]; @@ -233,7 +229,7 @@ extern const BehaviorScript bhvJrbSlidingBox[]; extern const BehaviorScript bhvShipPart3[]; extern const BehaviorScript bhvInSunkenShip3[]; extern const BehaviorScript bhvSunkenShipPart[]; -extern const BehaviorScript bhvUnused243C[]; +extern const BehaviorScript bhvSunkenShipSetRotation[]; extern const BehaviorScript bhvSunkenShipPart2[]; extern const BehaviorScript bhvInSunkenShip[]; extern const BehaviorScript bhvInSunkenShip2[]; @@ -281,7 +277,6 @@ extern const BehaviorScript bhvTree[]; extern const BehaviorScript bhvSparkle[]; extern const BehaviorScript bhvSparkleSpawn[]; extern const BehaviorScript bhvSparkleParticleSpawner[]; -extern const BehaviorScript bhvSomeGfx[]; extern const BehaviorScript bhvScuttlebug[]; extern const BehaviorScript bhvScuttlebugSpawn[]; extern const BehaviorScript bhvWhompKingBoss[];