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();
}
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

View File

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

View File

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

View File

@ -10,19 +10,19 @@
namespace metaforce {
class Console;
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 {
Invalid = 0,
MetroidPrime1,
MetroidPrime2,
MetroidPrime3,
MetroidPrimeTrilogy,
};
struct MetaforceVersionInfo {
std::string version;
ERegion region;
EGame game;
bool isTrilogy;
};
class CStopwatch;
@ -45,6 +45,7 @@ public:
virtual bool IsPAL() const = 0;
virtual bool IsJapanese() const = 0;
virtual bool IsUSA() const = 0;
virtual bool IsKorean() const = 0;
virtual bool IsTrilogy() const = 0;
virtual std::string_view GetVersionString() const = 0;
virtual void Quit() = 0;

View File

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

View File

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