Add CDvdFile::DiscInfo and update version detection

This commit is contained in:
Luke Street 2022-02-23 01:28:35 -05:00
parent 107ca74702
commit 9966ca13fb
6 changed files with 80 additions and 53 deletions

View File

@ -220,4 +220,16 @@ void CDvdFile::Shutdown() {
m_RequestQueue.clear(); m_RequestQueue.clear();
} }
SDiscInfo CDvdFile::DiscInfo() {
SDiscInfo out{};
if (!m_DvdRoot) {
return out;
}
const auto& header = m_DvdRoot->getHeader();
std::memcpy(out.gameId.data(), header.m_gameID, sizeof(header.m_gameID));
out.version = header.m_discVersion;
out.gameTitle = header.m_gameTitle;
return out;
}
} // namespace metaforce } // namespace metaforce

View File

@ -22,6 +22,12 @@ enum class ESeekOrigin { Begin = 0, Cur = 1, End = 2 };
struct DVDFileInfo; struct DVDFileInfo;
class IDvdRequest; class IDvdRequest;
struct SDiscInfo {
std::array<char, 6> gameId;
uint8_t version;
std::string gameTitle;
};
class CDvdFile { class CDvdFile {
friend class CResLoader; friend class CResLoader;
friend class CFileDvdRequest; friend class CFileDvdRequest;
@ -45,6 +51,7 @@ class CDvdFile {
public: public:
static bool Initialize(const std::string_view& path); static bool Initialize(const std::string_view& path);
static SDiscInfo DiscInfo();
static void Shutdown(); static void Shutdown();
CDvdFile(std::string_view path); CDvdFile(std::string_view path);

View File

@ -464,8 +464,6 @@ public:
g_mainMP1->Shutdown(); g_mainMP1->Shutdown();
} }
g_mainMP1.reset(); g_mainMP1.reset();
// m_renderTex.reset();
// m_pipelineConv.reset();
m_cvarManager.serialize(); m_cvarManager.serialize();
m_voiceEngine.reset(); m_voiceEngine.reset();
m_amuseAllocWrapper.reset(); m_amuseAllocWrapper.reset();
@ -473,13 +471,11 @@ public:
} }
void onCharKeyDown(uint8_t code, aurora::ModifierKey mods, bool isRepeat) noexcept override { void onCharKeyDown(uint8_t code, aurora::ModifierKey mods, bool isRepeat) noexcept override {
// if (!ImGuiWindowCallback::m_keyboardCaptured && g_mainMP1) {
if (g_mainMP1) { if (g_mainMP1) {
if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) {
as->charKeyDown(code, mods, isRepeat); as->charKeyDown(code, mods, isRepeat);
} }
} }
// }
} }
void onCharKeyUp(uint8_t code, aurora::ModifierKey mods) noexcept override { void onCharKeyUp(uint8_t code, aurora::ModifierKey mods) noexcept override {

View File

@ -10,19 +10,19 @@
namespace metaforce { namespace metaforce {
class Console; class Console;
class CVarManager; class CVarManager;
enum class ERegion { Invalid = -1, NTSC_U = 'E', PAL = 'P', NTSC_J = 'J' }; enum class ERegion { USA, JPN, PAL, KOR };
enum class EGame { enum class EGame {
Invalid = 0, Invalid = 0,
MetroidPrime1, MetroidPrime1,
MetroidPrime2, MetroidPrime2,
MetroidPrime3, MetroidPrime3,
MetroidPrimeTrilogy,
}; };
struct MetaforceVersionInfo { struct MetaforceVersionInfo {
std::string version; std::string version;
ERegion region; ERegion region;
EGame game; EGame game;
bool isTrilogy;
}; };
class CStopwatch; class CStopwatch;
@ -45,6 +45,7 @@ public:
virtual bool IsPAL() const = 0; virtual bool IsPAL() const = 0;
virtual bool IsJapanese() const = 0; virtual bool IsJapanese() const = 0;
virtual bool IsUSA() const = 0; virtual bool IsUSA() const = 0;
virtual bool IsKorean() const = 0;
virtual bool IsTrilogy() const = 0; virtual bool IsTrilogy() const = 0;
virtual std::string_view GetVersionString() const = 0; virtual std::string_view GetVersionString() const = 0;
virtual void Quit() = 0; virtual void Quit() = 0;

View File

@ -72,6 +72,8 @@
#include "Runtime/MP1/CCredits.hpp" #include "Runtime/MP1/CCredits.hpp"
#include <magic_enum.hpp>
#ifdef ENABLE_DISCORD #ifdef ENABLE_DISCORD
#include <discord_rpc.h> #include <discord_rpc.h>
#endif #endif
@ -100,6 +102,8 @@ inline void* memmem(const void* haystack, size_t hlen, const void* needle, size_
#endif #endif
namespace metaforce::MP1 { namespace metaforce::MP1 {
static logvisor::Module Log{"MP1"};
namespace { namespace {
struct AudioGroupInfo { struct AudioGroupInfo {
const char* name; const char* name;
@ -574,47 +578,61 @@ void CMain::HandleDiscordErrored(int errorCode, const char* message) {
DiscordLog.report(logvisor::Error, FMT_STRING("Discord Error: {}"), message); DiscordLog.report(logvisor::Error, FMT_STRING("Discord Error: {}"), message);
} }
void CMain::Init(const FileStoreManager& storeMgr, CVarManager* cvarMgr, void CMain::Init(const FileStoreManager& storeMgr, CVarManager* cvarMgr, boo::IAudioVoiceEngine* voiceEngine,
boo::IAudioVoiceEngine* voiceEngine, amuse::IBackendVoiceAllocator& backend) { amuse::IBackendVoiceAllocator& backend) {
InitializeDiscord(); InitializeDiscord();
m_cvarMgr = cvarMgr; m_cvarMgr = cvarMgr;
m_cvarCommons = std::make_unique<CVarCommons>(*m_cvarMgr); m_cvarCommons = std::make_unique<CVarCommons>(*m_cvarMgr);
bool loadedVersion = false; const auto discInfo = CDvdFile::DiscInfo();
#if 0 if (discInfo.gameId[4] != '0' || discInfo.gameId[5] != '1') {
if (CDvdFile::FileExists("version.yaml")) { Log.report(logvisor::Fatal, FMT_STRING("Unknown game ID {}"), std::string_view{discInfo.gameId.data(), 6});
CDvdFile file("version.yaml"); }
if (file) { if (strncmp(discInfo.gameId.data(), "GM8", 3) == 0 || strncmp(discInfo.gameId.data(), "R3I", 3) == 0) {
std::unique_ptr<u8[]> buf = std::make_unique<u8[]>(file.Length()); m_version.game = EGame::MetroidPrime1;
u32 readLen = file.SyncRead(buf.get(), file.Length()); } else if (strncmp(discInfo.gameId.data(), "G2M", 3) == 0 || strncmp(discInfo.gameId.data(), "R32", 3) == 0) {
if (readLen == file.Length()) { m_version.game = EGame::MetroidPrime2;
CMemoryInStream memoryInStream(buf.get(), file.Length()); } else if (strncmp(discInfo.gameId.data(), "R3M", 3) == 0) {
athena::io::FromYAMLStream(m_version, memoryInStream); m_version.game = EGame::MetroidPrime3;
loadedVersion = true; } else if (strncmp(discInfo.gameId.data(), "RM3", 3) == 0) {
MainLog.report(logvisor::Level::Info, FMT_STRING("Loaded version info")); m_version.game = EGame::MetroidPrimeTrilogy;
} } else {
Log.report(logvisor::Fatal, FMT_STRING("Unknown game ID {}"), std::string_view{discInfo.gameId.data(), 6});
}
switch (discInfo.gameId[3]) {
case 'E':
if (m_version.game == EGame::MetroidPrime1 && discInfo.version == 48) {
m_version.region = ERegion::KOR;
} else {
m_version.region = ERegion::USA;
} }
} else break;
#endif case 'J':
if (CDvdFile::FileExists("default.dol")) { m_version.region = ERegion::JPN;
break;
case 'P':
m_version.region = ERegion::PAL;
break;
default:
Log.report(logvisor::Fatal, FMT_STRING("Unknown region {}"), discInfo.gameId[3]);
}
if (m_version.game != EGame::MetroidPrime1 && m_version.game != EGame::MetroidPrimeTrilogy) {
Log.report(logvisor::Fatal, FMT_STRING("Unsupported game {}"), magic_enum::enum_name(m_version.game));
}
{
CDvdFile file("default.dol"); CDvdFile file("default.dol");
if (file) { if (!file) {
std::unique_ptr<u8[]> buf = std::make_unique<u8[]>(file.Length()); Log.report(logvisor::Fatal, FMT_STRING("Failed to open default.dol"));
u32 readLen = file.SyncRead(buf.get(), file.Length());
const char* buildInfo =
static_cast<char*>(memmem(buf.get(), readLen, "MetroidBuildInfo", 16)) + 19;
if (buildInfo != nullptr) {
// TODO
m_version = MetaforceVersionInfo{
.version = std::string(buildInfo),
.region = ERegion::NTSC_U,
.game = EGame::MetroidPrime1,
.isTrilogy = false,
};
loadedVersion = true;
MainLog.report(logvisor::Level::Info, FMT_STRING("Loaded version info"));
}
} }
std::unique_ptr<u8[]> buf = std::make_unique<u8[]>(file.Length());
u32 readLen = file.SyncRead(buf.get(), file.Length());
const char* buildInfo = static_cast<char*>(memmem(buf.get(), readLen, "MetroidBuildInfo", 16)) + 19;
if (buildInfo == nullptr) {
Log.report(logvisor::Fatal, FMT_STRING("Failed to locate MetroidBuildInfo"));
}
m_version.version = buildInfo;
} }
InitializeSubsystems(); InitializeSubsystems();
@ -624,16 +642,8 @@ void CMain::Init(const FileStoreManager& storeMgr, CVarManager* cvarMgr,
x70_tweaks.RegisterResourceTweaks(m_cvarMgr); x70_tweaks.RegisterResourceTweaks(m_cvarMgr);
AddWorldPaks(); AddWorldPaks();
if (loadedVersion) { MainLog.report(logvisor::Level::Info, FMT_STRING("Loading data from {} version {} from region {}"),
if (GetGame() != EGame::MetroidPrime1) { magic_enum::enum_name(GetGame()), GetVersionString(), magic_enum::enum_name(GetRegion()));
MainLog.report(logvisor::Level::Fatal,
FMT_STRING("Attempted to initialize URDE in MP1 mode with non-MP1 data!!!!"));
}
MainLog.report(logvisor::Level::Info, FMT_STRING("Loading data from Metroid Prime version {} from region {}{}"),
GetVersionString(), GetRegion(), IsTrilogy() ? " from trilogy" : "");
} else {
MainLog.report(logvisor::Level::Fatal, FMT_STRING("Unable to load version info"));
}
auto args = aurora::get_args(); auto args = aurora::get_args();
for (auto it = args.begin(); it != args.end(); ++it) { for (auto it = args.begin(); it != args.end(); ++it) {

View File

@ -287,9 +287,10 @@ public:
size_t GetExpectedIdSize() const override { return sizeof(u32); } size_t GetExpectedIdSize() const override { return sizeof(u32); }
bool IsPAL() const override { return m_version.region == ERegion::PAL; } bool IsPAL() const override { return m_version.region == ERegion::PAL; }
bool IsJapanese() const override { return m_version.region == ERegion::NTSC_J; } bool IsJapanese() const override { return m_version.region == ERegion::JPN; }
bool IsUSA() const override { return m_version.region == ERegion::NTSC_U; } bool IsUSA() const override { return m_version.region == ERegion::USA; }
bool IsTrilogy() const override { return m_version.isTrilogy; } bool IsKorean() const override { return m_version.region == ERegion::KOR; }
bool IsTrilogy() const override { return m_version.game == EGame::MetroidPrimeTrilogy; }
ERegion GetRegion() const override { return m_version.region; } ERegion GetRegion() const override { return m_version.region; }
EGame GetGame() const override { return m_version.game; } EGame GetGame() const override { return m_version.game; }
std::string_view GetVersionString() const override { return m_version.version; } std::string_view GetVersionString() const override { return m_version.version; }