diff --git a/DataSpec/SpecBase.cpp b/DataSpec/SpecBase.cpp index 6d6f5ecaa..846c29e5a 100644 --- a/DataSpec/SpecBase.cpp +++ b/DataSpec/SpecBase.cpp @@ -75,18 +75,20 @@ bool SpecBase::canExtract(const ExtractPassInfo& info, std::vectorgetHeader().m_gameID[3]; + m_region = ERegion(m_disc->getHeader().m_gameID[3]); const hecl::SystemString* regstr = ®NONE; - switch (region) { - case 'E': + switch (m_region) { + case ERegion::NTSC_U: regstr = ®E; break; - case 'J': + case ERegion::PAL: regstr = ®J; break; - case 'P': + case ERegion::NTSC_J: regstr = ®P; break; + default: + break; } if (m_standalone) @@ -1206,4 +1208,15 @@ void SpecBase::waitForIndexComplete() const { } } +void SpecBase::WriteVersionInfo(hecl::Database::Project &project, const hecl::ProjectPath &pakPath) { + hecl::ProjectPath versionPath(pakPath, _SYS_STR("version.yaml")); + versionPath.makeDirChain(false); + + athena::io::YAMLDocWriter yamlW("URDEVersionData"); + yamlW.writeString("version", m_version); + yamlW.writeByte("region", atUint8(m_region)); + yamlW.writeBool("is_trilogy", !m_standalone); + athena::io::FileWriter fileW(versionPath.getAbsolutePath()); + yamlW.finish(&fileW); +} } // namespace DataSpec diff --git a/DataSpec/SpecBase.hpp b/DataSpec/SpecBase.hpp index 211c5702d..2bab11ee5 100644 --- a/DataSpec/SpecBase.hpp +++ b/DataSpec/SpecBase.hpp @@ -23,6 +23,12 @@ class YAMLDocWriter; } // namespace athena::io namespace DataSpec { +enum class ERegion { + Invalid = 0, + NTSC_U = 'E', + PAL = 'P', + NTSC_J = 'J' +}; struct SpecBase : hecl::Database::IDataSpec { /* HECL Adaptors */ @@ -199,6 +205,10 @@ protected: std::unique_ptr m_disc; bool m_isWii; bool m_standalone; + ERegion m_region = ERegion::Invalid; + std::string m_version; + + void WriteVersionInfo(hecl::Database::Project& project, const hecl::ProjectPath& pakPath); }; bool IsPathAudioGroup(const hecl::ProjectPath& path); diff --git a/DataSpec/SpecMP1.cpp b/DataSpec/SpecMP1.cpp index 02ad59323..0ea5cc7ff 100644 --- a/DataSpec/SpecMP1.cpp +++ b/DataSpec/SpecMP1.cpp @@ -63,7 +63,8 @@ extern hecl::Database::DataSpecEntry SpecEntMP1PC; extern hecl::Database::DataSpecEntry SpecEntMP1ORIG; struct TextureCache { - static void Generate(PAKRouter& pakRouter, hecl::Database::Project& project, const hecl::ProjectPath& pakPath) { + static void Generate(PAKRouter& pakRouter, hecl::Database::Project& project, + const hecl::ProjectPath& pakPath) { hecl::ProjectPath texturePath(pakPath, _SYS_STR("texture_cache.yaml")); hecl::ProjectPath catalogPath(pakPath, _SYS_STR("!catalog.yaml")); texturePath.makeDirChain(false); @@ -112,9 +113,8 @@ struct TextureCache { metaPairs.emplace_back(projectPath.parsedHash32(), meta); } - std::sort(metaPairs.begin(), metaPairs.end(), [](const auto& a, const auto& b) -> bool { - return a.first < b.first; - }); + std::sort(metaPairs.begin(), metaPairs.end(), + [](const auto& a, const auto& b) -> bool { return a.first < b.first; }); athena::io::FileWriter w(outPath.getAbsolutePath()); w.writeUint32Big(metaPairs.size()); @@ -223,13 +223,13 @@ struct SpecMP1 : SpecBase { if (!buildInfo) return false; + m_version = std::string(buildInfo); /* Root Report */ ExtractReport& rep = reps.emplace_back(); rep.name = _SYS_STR("MP1"); rep.desc = _SYS_STR("Metroid Prime ") + regstr; if (buildInfo) { - std::string buildStr(buildInfo); - hecl::SystemStringConv buildView(buildStr); + hecl::SystemStringConv buildView(m_version); rep.desc += _SYS_STR(" (") + buildView + _SYS_STR(")"); } @@ -378,6 +378,14 @@ struct SpecMP1 : SpecBase { /* Generate Texture Cache containing meta data for every texture file */ TextureCache::Generate(m_pakRouter, m_project, noAramPath); + /* Write version data */ + hecl::ProjectPath versionPath; + if (m_standalone) { + versionPath = hecl::ProjectPath(m_project.getProjectWorkingPath(), _SYS_STR("out/files")); + } else { + versionPath = hecl::ProjectPath(m_project.getProjectWorkingPath(), _SYS_STR("out/files/MP1")); + } + WriteVersionInfo(m_project, versionPath); return true; } @@ -740,7 +748,8 @@ struct SpecMP1 : SpecBase { } if (!colMesh) - Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("unable to find mesh named 'CMESH' in {}")), in.getAbsolutePath()); + Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("unable to find mesh named 'CMESH' in {}")), + in.getAbsolutePath()); std::vector lights = ds.compileLights(); @@ -1131,7 +1140,8 @@ struct SpecMP1 : SpecBase { } void buildPakList(hecl::blender::Token& btok, athena::io::FileWriter& w, const std::vector& list, - const std::vector>& nameList, atUint64& resTableOffset) override { + const std::vector>& nameList, + atUint64& resTableOffset) override { w.writeUint32Big(m_pc ? 0x80030005 : 0x00030005); w.writeUint32Big(0); diff --git a/DataSpec/SpecMP2.cpp b/DataSpec/SpecMP2.cpp index b7789685c..b896ce7c5 100644 --- a/DataSpec/SpecMP2.cpp +++ b/DataSpec/SpecMP2.cpp @@ -187,12 +187,12 @@ struct SpecMP2 : SpecBase { if (!buildInfo) return false; + m_version = std::string(buildInfo); /* Root Report */ ExtractReport& rep = reps.emplace_back(); rep.name = _SYS_STR("MP2"); rep.desc = _SYS_STR("Metroid Prime 2 ") + regstr; - std::string buildStr(buildInfo); - hecl::SystemStringConv buildView(buildStr); + hecl::SystemStringConv buildView(m_version); rep.desc += _SYS_STR(" (") + buildView + _SYS_STR(")"); /* Iterate PAKs and build level options */ @@ -317,6 +317,14 @@ struct SpecMP2 : SpecBase { hecl::ProjectPath noAramPath(m_project.getProjectWorkingPath(), _SYS_STR("MP2/URDE")); TextureCache::Generate(m_pakRouter, m_project, noAramPath); + /* Write version data */ + hecl::ProjectPath versionPath; + if (m_standalone) { + versionPath = hecl::ProjectPath(m_project.getProjectWorkingPath(), _SYS_STR("out/files")); + } else { + versionPath = hecl::ProjectPath(m_project.getProjectWorkingPath(), _SYS_STR("out/files/MP2")); + } + WriteVersionInfo(m_project, versionPath); return true; } diff --git a/DataSpec/SpecMP3.cpp b/DataSpec/SpecMP3.cpp index c378bb8c0..4d5c87edf 100644 --- a/DataSpec/SpecMP3.cpp +++ b/DataSpec/SpecMP3.cpp @@ -231,12 +231,12 @@ struct SpecMP3 : SpecBase { if (!strcmp(buildInfo, "Build v3.068 3/2/2006 14:55:13")) return false; + m_version = std::string(buildInfo); /* Root Report */ ExtractReport& rep = reps.emplace_back(); rep.name = _SYS_STR("MP3"); rep.desc = _SYS_STR("Metroid Prime 3 ") + regstr; - std::string buildStr(buildInfo); - hecl::SystemStringConv buildView(buildStr); + hecl::SystemStringConv buildView(m_version); rep.desc += _SYS_STR(" (") + buildView + _SYS_STR(")"); /* Iterate PAKs and build level options */ @@ -473,12 +473,20 @@ struct SpecMP3 : SpecBase { } process.waitUntilComplete(); - - /* Extract part of .dol for RandomStatic entropy */ - hecl::ProjectPath noAramPath(m_project.getProjectWorkingPath(), _SYS_STR("MP3/URDE")); - /* Generate Texture Cache containing meta data for every texture file */ - TextureCache::Generate(m_pakRouter, m_project, noAramPath); } + + /* Extract part of .dol for RandomStatic entropy */ + hecl::ProjectPath noAramPath(m_project.getProjectWorkingPath(), _SYS_STR("MP3/URDE")); + /* Generate Texture Cache containing meta data for every texture file */ + TextureCache::Generate(m_pakRouter, m_project, noAramPath); + /* Write version data */ + hecl::ProjectPath versionPath; + if (m_standalone) { + versionPath = hecl::ProjectPath(m_project.getProjectWorkingPath(), _SYS_STR("out/files")); + } else { + versionPath = hecl::ProjectPath(m_project.getProjectWorkingPath(), _SYS_STR("out/files/MP3")); + } + WriteVersionInfo(m_project, versionPath); return true; } diff --git a/Runtime/MP1/MP1.cpp b/Runtime/MP1/MP1.cpp index ee5eb0094..7377dc3c7 100644 --- a/Runtime/MP1/MP1.cpp +++ b/Runtime/MP1/MP1.cpp @@ -61,6 +61,7 @@ #include "Runtime/Particle/CWeaponDescription.hpp" #include "Runtime/World/CPlayer.hpp" #include "Runtime/World/CStateMachine.hpp" +#include "Runtime/World/CScriptMazeNode.hpp" #include #include @@ -343,6 +344,14 @@ CGameGlobalObjects::~CGameGlobalObjects() { g_GameState = nullptr; g_TweakManager = nullptr; } +void CGameGlobalObjects::PostInitialize() { + AddPaksAndFactories(); + LoadTextureCache(); + LoadStringTable(); + m_renderer.reset(AllocateRenderer(*xcc_simplePool, *x4_resFactory)); + CEnvFxManager::Initialize(); + CScriptMazeNode::LoadMazeSeeds(); +} void CMain::AddWorldPaks() { CResLoader* loader = g_ResFactory->GetResLoader(); diff --git a/Runtime/MP1/MP1.hpp b/Runtime/MP1/MP1.hpp index eea752799..1fc05f3a8 100644 --- a/Runtime/MP1/MP1.hpp +++ b/Runtime/MP1/MP1.hpp @@ -7,40 +7,39 @@ #define MP1_VARIABLE_DELTA_TIME 1 #endif -#include "IMain.hpp" -#include "CTweaks.hpp" -#include "CPlayMovie.hpp" -#include "IOStreams.hpp" -#include "CBasics.hpp" -#include "CMemoryCardSys.hpp" -#include "CResFactory.hpp" -#include "CSimplePool.hpp" -#include "Character/CAssetFactory.hpp" -#include "World/CAi.hpp" -#include "CGameState.hpp" -#include "CInGameTweakManager.hpp" -#include "Particle/CElementGen.hpp" -#include "Character/CAnimData.hpp" -#include "Particle/CDecalManager.hpp" -#include "Particle/CGenDescription.hpp" -#include "Graphics/CBooRenderer.hpp" -#include "Audio/CAudioSys.hpp" -#include "Input/CInputGenerator.hpp" -#include "GuiSys/CGuiSys.hpp" -#include "CIOWinManager.hpp" -#include "GuiSys/CSplashScreen.hpp" -#include "CMainFlow.hpp" -#include "GuiSys/CConsoleOutputWindow.hpp" -#include "GuiSys/CErrorOutputWindow.hpp" -#include "GuiSys/CTextParser.hpp" -#include "CAudioStateWin.hpp" -#include "GameGlobalObjects.hpp" -#include "CArchitectureQueue.hpp" -#include "CTimeProvider.hpp" -#include "GuiSys/CTextExecuteBuffer.hpp" +#include "Runtime/IMain.hpp" +#include "Runtime/MP1/CTweaks.hpp" +#include "Runtime/MP1/CPlayMovie.hpp" +#include "Runtime/IOStreams.hpp" +#include "Runtime/CBasics.hpp" +#include "Runtime/CMemoryCardSys.hpp" +#include "Runtime/CResFactory.hpp" +#include "Runtime/CSimplePool.hpp" +#include "Runtime/Character/CAssetFactory.hpp" +#include "Runtime/World/CAi.hpp" +#include "Runtime/CGameState.hpp" +#include "Runtime/MP1/CInGameTweakManager.hpp" +#include "Runtime/Particle/CElementGen.hpp" +#include "Runtime/Character/CAnimData.hpp" +#include "Runtime/Particle/CDecalManager.hpp" +#include "Runtime/Particle/CGenDescription.hpp" +#include "Runtime/Graphics/CBooRenderer.hpp" +#include "Runtime/Audio/CAudioSys.hpp" +#include "Runtime/Input/CInputGenerator.hpp" +#include "Runtime/GuiSys/CGuiSys.hpp" +#include "Runtime/CIOWinManager.hpp" +#include "Runtime/GuiSys/CSplashScreen.hpp" +#include "Runtime/MP1/CMainFlow.hpp" +#include "Runtime/GuiSys/CConsoleOutputWindow.hpp" +#include "Runtime/GuiSys/CErrorOutputWindow.hpp" +#include "Runtime/GuiSys/CTextParser.hpp" +#include "Runtime/MP1/CAudioStateWin.hpp" +#include "Runtime/GameGlobalObjects.hpp" +#include "Runtime/CArchitectureQueue.hpp" +#include "Runtime/CTimeProvider.hpp" +#include "Runtime/GuiSys/CTextExecuteBuffer.hpp" #include "DataSpec/DNAMP1/Tweaks/CTweakPlayer.hpp" #include "DataSpec/DNAMP1/Tweaks/CTweakGame.hpp" -#include "World/CScriptMazeNode.hpp" #include "hecl/Console.hpp" struct DiscordUser; @@ -104,14 +103,7 @@ public: ~CGameGlobalObjects(); - void PostInitialize() { - AddPaksAndFactories(); - LoadTextureCache(); - LoadStringTable(); - m_renderer.reset(AllocateRenderer(*xcc_simplePool, *x4_resFactory)); - CEnvFxManager::Initialize(); - CScriptMazeNode::LoadMazeSeeds(); - } + void PostInitialize(); void ResetGameState() { x134_gameState = std::make_unique();