diff --git a/ZAPD/ZRom.cpp b/ZAPD/ZRom.cpp index ae5343b..f18f3c9 100644 --- a/ZAPD/ZRom.cpp +++ b/ZAPD/ZRom.cpp @@ -44,7 +44,9 @@ namespace fs = std::filesystem; #define MM_OFF_US_10 0x1A500 #define MM_OFF_US_GC 0x1AE90 +#define MM_OFF_PAL_11 0x1A8D0 #define MM_OFF_JP_GC 0x1AE90 +#define MM_OFF_PAL_GC 0x1AE90 #define MM_OFF_JP_10 0x1C110 #define MM_OFF_JP_11 0x1C050 #define MM_OFF_DBG 0x24F60 @@ -70,8 +72,10 @@ namespace fs = std::filesystem; #define MM_NTSC_10 0x5354631C #define MM_NTSC_10_UNCOMPRESSED 0xDA6983E7 +#define MM_PAL_11 0x0A5D8F83 #define MM_NTSC_GC 0xB443EB08 #define MM_NTSC_JP_GC 0x8473D0C1 +#define MM_PAL_GC 0x6AECEC4F bool ZRom::IsMQ() { int crc = BitConverter::ToInt32BE(romData, 0x10); @@ -92,7 +96,9 @@ bool ZRom::IsMQ() { // MM - Always not MQ case MM_NTSC_10: case MM_NTSC_10_UNCOMPRESSED: + case MM_PAL_11: case MM_NTSC_GC: + case MM_PAL_GC: case MM_NTSC_JP_GC: default: return false; @@ -220,6 +226,16 @@ ZRom::ZRom(std::string romPath) version.listPath = "mm_gc_jp.txt"; version.offset = MM_OFF_JP_GC; break; + case MM_PAL_11: + version.version = "MM PAL 1.1"; + version.listPath = "mm_pal.txt"; + version.offset = MM_OFF_PAL_11; + break; + case MM_PAL_GC: + version.version = "MM PAL GC"; + version.listPath = "mm_gc_pal.txt"; + version.offset = MM_OFF_PAL_GC; + break; } auto path = StringHelper::Sprintf("%s/%s", Globals::Instance->fileListPath.string().c_str(), version.listPath.c_str()); @@ -255,9 +271,20 @@ ZRom::ZRom(std::string romPath) // An ifdef is used here because at this point the XMLs haven't been parsed, and we don't // know if this is MM or OOT #ifdef GAME_MM - if ((i >= 15 && i <= 20) || i == 22) + // PAL filelists differ For yar file locations, TODO: Find way to avoid special casing numbers + if (version.crc == MM_PAL_11 || version.crc == MM_PAL_GC) + { + if ((i >= 17 && i <= 28) || i == 30) + { + yarCompressed = true; + } + } + else { - yarCompressed = true; + if ((i >= 15 && i <= 20) || i == 22) + { + yarCompressed = true; + } } #endif diff --git a/ZAPD/ZTextMM.cpp b/ZAPD/ZTextMM.cpp index 5c63676..7c57941 100644 --- a/ZAPD/ZTextMM.cpp +++ b/ZAPD/ZTextMM.cpp @@ -11,7 +11,8 @@ REGISTER_ZFILENODE(TextMM, ZTextMM); ZTextMM::ZTextMM(ZFile* nParent) : ZResource(nParent) { - RegisterRequiredAttribute("CodeOffset"); + RegisterOptionalAttribute("CodeOffset"); + RegisterOptionalAttribute("SegmentName"); RegisterOptionalAttribute("LangOffset", "0"); } @@ -25,7 +26,19 @@ void ZTextMM::ParseRawData() void ZTextMM::ParseMM() { const auto& rawData = parent->GetRawData(); - uint32_t currentPtr = StringHelper::StrToL(registeredAttributes.at("CodeOffset").value, 16); + uint32_t currentPtr; + bool messageTableInOwnSegment = false; + + if (StringHelper::StrToL(registeredAttributes.at("CodeOffset").value, 16) != 0) + { + currentPtr = StringHelper::StrToL(registeredAttributes.at("CodeOffset").value, 16); + messageTableInOwnSegment = false; + } + else + { + currentPtr = 0; + messageTableInOwnSegment = true; + } uint32_t langPtr = currentPtr; bool isPalLang = false; @@ -40,10 +53,35 @@ void ZTextMM::ParseMM() std::vector codeData; if (Globals::Instance->fileMode == ZFileMode::ExtractDirectory) - codeData = Globals::Instance->GetBaseromFile("code"); + if (messageTableInOwnSegment) + { + if (registeredAttributes.at("SegmentName").value == "") + { + throw std::runtime_error( + StringHelper::Sprintf("ZTextMM: Missing one of required attributes: CodeOffset or SegmentName")); + } + + codeData = Globals::Instance->GetBaseromFile(registeredAttributes.at("SegmentName").value); + } + else { + codeData = Globals::Instance->GetBaseromFile("code"); + } else - codeData = - Globals::Instance->GetBaseromFile(Globals::Instance->baseRomPath.string() + "code"); + if (messageTableInOwnSegment) + { + if (registeredAttributes.at("SegmentName").value == "") + { + throw std::runtime_error( + StringHelper::Sprintf("ZTextMM: Missing one of required attributes: CodeOffset or SegmentName")); + } + codeData = Globals::Instance->GetBaseromFile(Globals::Instance->baseRomPath.string() + + registeredAttributes.at("SegmentName").value); + } + else + { + codeData = + Globals::Instance->GetBaseromFile(Globals::Instance->baseRomPath.string() + "code"); + } while (true) {