From e35402f3d127f75c1e3f6f03df29bc1be69d320d Mon Sep 17 00:00:00 2001 From: MysterD Date: Fri, 25 Mar 2022 22:05:07 -0700 Subject: [PATCH] Make DynOS only generate one bin per actor --- data/dynos_gfx_read.cpp | 147 ++++++++++++++++++++++++++++++---------- 1 file changed, 110 insertions(+), 37 deletions(-) diff --git a/data/dynos_gfx_read.cpp b/data/dynos_gfx_read.cpp index a85e2642..c5ae7eec 100644 --- a/data/dynos_gfx_read.cpp +++ b/data/dynos_gfx_read.cpp @@ -1782,44 +1782,15 @@ static String GetActorFolder(const Array> &aActorsFolders, u64 return String(); } -void DynOS_Gfx_GeneratePack(const SysPath &aPackFolder) { - Print("---------- Pack folder: \"%s\" ----------", aPackFolder.c_str()); - Array> _ActorsFolders; - GfxData *_GfxData = New(); - - // Read all the model.inc.c files and geo.inc.c files from the subfolders of the pack folder - // Animations are processed separately - DIR *aPackDir = opendir(aPackFolder.c_str()); - if (aPackDir) { - struct dirent *_PackEnt = NULL; - while ((_PackEnt = readdir(aPackDir)) != NULL) { - - // Skip . and .. - if (SysPath(_PackEnt->d_name) == ".") continue; - if (SysPath(_PackEnt->d_name) == "..") continue; - - // For each subfolder, read tokens from model.inc.c and geo.inc.c - SysPath _Folder = fstring("%s/%s", aPackFolder.c_str(), _PackEnt->d_name); - if (fs_sys_dir_exists(_Folder.c_str())) { - _GfxData->mModelIdentifier = 0; - ScanModelFile(_GfxData, fstring("%s/model.inc.c", _Folder.c_str())); - ScanModelFile(_GfxData, fstring("%s/geo.inc.c", _Folder.c_str())); - if (_GfxData->mModelIdentifier != 0) { - _ActorsFolders.Add({ _GfxData->mModelIdentifier, String(_PackEnt->d_name) }); - } - } - } - closedir(aPackDir); - } - - // Generate a binary file for each actor found in the GfxData #ifdef COOP +static bool DynOS_Gfx_GeneratePack_Internal(const SysPath &aPackFolder, Array> _ActorsFolders, GfxData *_GfxData, bool onlyConsiderActors) { + bool generated = false; for (auto &_GeoNode : _GfxData->mGeoLayouts) { String _GeoRootName = _GeoNode->mName; -#else - for (s32 i = 0; i != DynOS_Geo_GetActorCount(); ++i) { - String _GeoRootName = DynOS_Geo_GetActorName(i); -#endif + const void* actor = DynOS_Geo_GetActorLayoutFromName(_GeoRootName.begin()); + if (onlyConsiderActors && actor == NULL) { continue; } + if (!onlyConsiderActors && _GeoNode != _GfxData->mGeoLayouts[_GfxData->mGeoLayouts.Count() - 1]) { continue; } + DataNode *_GeoRoot = GetGeoLayout(_GfxData, _GeoRootName); if (_GeoRoot != NULL) { @@ -1857,13 +1828,114 @@ void DynOS_Gfx_GeneratePack(const SysPath &aPackFolder) { SysPath _AnimsFolder = fstring("%s/%s/anims", aPackFolder.c_str(), _ActorFolder.begin()); ScanAnimationFolder(_GfxData, _AnimsFolder); -#ifdef COOP // 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); + generated = true; + } + } + return generated; +} +#endif + +void DynOS_Gfx_GeneratePack(const SysPath &aPackFolder) { + Print("---------- Pack folder: \"%s\" ----------", aPackFolder.c_str()); + Array> _ActorsFolders; + GfxData *_GfxData = New(); + + // Read all the model.inc.c files and geo.inc.c files from the subfolders of the pack folder + // Animations are processed separately + DIR *aPackDir = opendir(aPackFolder.c_str()); + if (aPackDir) { + struct dirent *_PackEnt = NULL; + while ((_PackEnt = readdir(aPackDir)) != NULL) { + + // Skip . and .. + if (SysPath(_PackEnt->d_name) == ".") continue; + if (SysPath(_PackEnt->d_name) == "..") continue; + + // For each subfolder, read tokens from model.inc.c and geo.inc.c + SysPath _Folder = fstring("%s/%s", aPackFolder.c_str(), _PackEnt->d_name); + if (fs_sys_dir_exists(_Folder.c_str())) { + _GfxData->mModelIdentifier = 0; + ScanModelFile(_GfxData, fstring("%s/model.inc.c", _Folder.c_str())); + ScanModelFile(_GfxData, fstring("%s/geo.inc.c", _Folder.c_str())); + if (_GfxData->mModelIdentifier != 0) { + _ActorsFolders.Add({ _GfxData->mModelIdentifier, String(_PackEnt->d_name) }); + } + } + } + closedir(aPackDir); + } + + // Generate a binary file for each actor found in the GfxData +#ifdef COOP + bool foundActor = DynOS_Gfx_GeneratePack_Internal(aPackFolder, _ActorsFolders, _GfxData, true); + if (!foundActor) { DynOS_Gfx_GeneratePack_Internal(aPackFolder, _ActorsFolders, _GfxData, false); } #else + for (s32 i = 0; i != DynOS_Geo_GetActorCount(); ++i) { + String _GeoRootName = DynOS_Geo_GetActorName(i); + 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; + } + + // 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); + 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(); + + // 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 mario_geo animations or luigi_geo animations if ((_GeoRootName == "mario_geo" || _GeoRootName == "luigi_geo") && !_GfxData->mAnimations.Empty()) { -#endif _GfxData->mAnimationTable.Resize(256); for (s32 i = 0; i != 256; ++i) { String _AnimName("anim_%02X", i); @@ -1889,6 +1961,7 @@ void DynOS_Gfx_GeneratePack(const SysPath &aPackFolder) { ClearGfxDataNodes(_GfxData->mGeoLayouts); } } +#endif DynOS_Gfx_Free(_GfxData); }