mirror of
https://github.com/HarbourMasters/Shipwright
synced 2026-10-21 10:51:32 -04:00
Fix extracting from MQ rom padded to 64MB (#7376)
Also show error message instead of just proceeding to start if vanilla o2r already extracted
This commit is contained in:
@@ -366,7 +366,7 @@ size_t Extractor::GetCurRomSize() const {
|
||||
|
||||
bool Extractor::ValidateAndFixRom() {
|
||||
// The MQ debug rom sometimes has the header patched to look like a US rom.
|
||||
// Check the crc as if it were changed back, but leave mRomData as the original dump for torch.
|
||||
// Check the crc as if it were changed back. CallTorch changes it back for real.
|
||||
const uint8_t region = mRomData[0x3E];
|
||||
if (GetRomVerCrc() == OOT_PAL_GC_MQ_DBG) {
|
||||
mRomData[0x3E] = 'P';
|
||||
@@ -666,6 +666,13 @@ bool Extractor::CallTorch(std::string installPath, std::string exportdir, std::a
|
||||
*totalExtract = SohTorch::CountAssetFiles(srcDir + "/" + GetTorchVersionDir());
|
||||
*extractCount = 0;
|
||||
|
||||
// MQ debug dumps only hold 54MB of data, the rest is dump-specific padding, and some have
|
||||
// the region byte changed. Trim and restore it so every dump matches the one config.yml hash.
|
||||
if (GetRomVerCrc() == OOT_PAL_GC_MQ_DBG && mRomData.size() == MB64) {
|
||||
mRomData.resize(MB54);
|
||||
mRomData[0x3E] = 'P';
|
||||
}
|
||||
|
||||
// config.yml decides whether this is oot.o2r or oot-mq.o2r.
|
||||
std::string archiveName = SohTorch::Extract(std::move(mRomData), srcDir, tempdir, portVersion, extractCount);
|
||||
bool success = !archiveName.empty();
|
||||
|
||||
+43
-15
@@ -430,7 +430,12 @@ void OTRGlobals::RunExtract(int argc, char* argv[]) {
|
||||
Extractor extract;
|
||||
PromptSteps promptStep = PS_FILE_CHECK;
|
||||
bool generatedIsMQ = false;
|
||||
// Whether generatedIsMQ is set, i.e. the first prompted rom extracted fine
|
||||
bool generatedFirst = false;
|
||||
bool lastExtractFailed = false;
|
||||
std::atomic<size_t> extractCount = 0, totalExtract = 0;
|
||||
// Set by the extraction thread, shown as a popup by the main thread once the task finishes
|
||||
std::atomic<bool> extractFailed = false;
|
||||
|
||||
std::string installPath = std::filesystem::absolute(Ship::Context::GetAppBundlePath()).string();
|
||||
std::string dataPath = std::filesystem::absolute(Ship::Context::GetAppDirectoryPath(appShortName)).string();
|
||||
@@ -613,15 +618,17 @@ void OTRGlobals::RunExtract(int argc, char* argv[]) {
|
||||
std::string msg = "Archive for current ROM, " + archive + ", already exists.\nExtract again?";
|
||||
SohGui::RegisterPopup("Confirm Re-extract", msg.c_str(), "Yes", "No", [&]() {
|
||||
extractionTask = threadPool->submit_task([&]() -> void {
|
||||
extract.CallTorch(installPath, Ship::Context::GetAppDirectoryPath(appShortName),
|
||||
&extractCount, &totalExtract);
|
||||
extractFailed =
|
||||
!extract.CallTorch(installPath, Ship::Context::GetAppDirectoryPath(appShortName),
|
||||
&extractCount, &totalExtract);
|
||||
extractCount = totalExtract = 0;
|
||||
});
|
||||
});
|
||||
} else {
|
||||
extractionTask = threadPool->submit_task([&]() -> void {
|
||||
extract.CallTorch(installPath, Ship::Context::GetAppDirectoryPath(appShortName),
|
||||
&extractCount, &totalExtract);
|
||||
extractFailed =
|
||||
!extract.CallTorch(installPath, Ship::Context::GetAppDirectoryPath(appShortName),
|
||||
&extractCount, &totalExtract);
|
||||
extractCount = totalExtract = 0;
|
||||
});
|
||||
}
|
||||
@@ -677,9 +684,13 @@ void OTRGlobals::RunExtract(int argc, char* argv[]) {
|
||||
continue;
|
||||
}
|
||||
extractionTask = threadPool->submit_task([&]() -> void {
|
||||
extract.CallTorch(installPath, Ship::Context::GetAppDirectoryPath(appShortName),
|
||||
&extractCount, &totalExtract);
|
||||
generatedIsMQ = extract.IsMasterQuest();
|
||||
extractFailed =
|
||||
!extract.CallTorch(installPath, Ship::Context::GetAppDirectoryPath(appShortName),
|
||||
&extractCount, &totalExtract);
|
||||
if (!extractFailed) {
|
||||
generatedIsMQ = extract.IsMasterQuest();
|
||||
generatedFirst = true;
|
||||
}
|
||||
promptStep = PS_SECOND;
|
||||
extractCount = 0;
|
||||
totalExtract = 0;
|
||||
@@ -687,17 +698,28 @@ void OTRGlobals::RunExtract(int argc, char* argv[]) {
|
||||
continue;
|
||||
}
|
||||
case PS_SECOND: {
|
||||
// Keep asking until the user says no, so a failed or cancelled rom can be retried
|
||||
SohGui::RegisterPopup(
|
||||
"Extraction Complete", "ROM Extracted. Extract another?", "Yes", "No",
|
||||
lastExtractFailed ? "Extract Another" : "Extraction Complete",
|
||||
lastExtractFailed ? "Try extracting another ROM?" : "ROM Extracted. Extract another?",
|
||||
"Yes", "No",
|
||||
[&]() {
|
||||
if (!extract.ManuallySearchForRomMatchingType(generatedIsMQ ? RomSearchMode::Vanilla
|
||||
: RomSearchMode::MQ)) {
|
||||
extractStep = ES_VERIFY;
|
||||
} else {
|
||||
RomSearchMode mode = RomSearchMode::Both;
|
||||
if (generatedFirst) {
|
||||
mode = generatedIsMQ ? RomSearchMode::Vanilla : RomSearchMode::MQ;
|
||||
}
|
||||
if (extract.ManuallySearchForRomMatchingType(mode)) {
|
||||
extractionTask = threadPool->submit_task([&]() -> void {
|
||||
extract.CallTorch(installPath, Ship::Context::GetAppDirectoryPath(appShortName),
|
||||
&extractCount, &totalExtract);
|
||||
extractStep = ES_VERIFY;
|
||||
extractFailed = !extract.CallTorch(
|
||||
installPath, Ship::Context::GetAppDirectoryPath(appShortName),
|
||||
&extractCount, &totalExtract);
|
||||
if (!extractFailed && generatedFirst) {
|
||||
extractStep = ES_VERIFY;
|
||||
} else if (!extractFailed) {
|
||||
// A retry of the first rom worked, so still offer the other type
|
||||
generatedIsMQ = extract.IsMasterQuest();
|
||||
generatedFirst = true;
|
||||
}
|
||||
extractCount = 0;
|
||||
totalExtract = 0;
|
||||
});
|
||||
@@ -754,6 +776,12 @@ void OTRGlobals::RunExtract(int argc, char* argv[]) {
|
||||
} catch (const std::exception& e) {
|
||||
SohGui::RegisterPopup("Extraction Crashed", e.what(), "Close", "", []() { exit(1); });
|
||||
}
|
||||
lastExtractFailed = extractFailed;
|
||||
if (extractFailed) {
|
||||
SohGui::RegisterPopup("Extraction Failed",
|
||||
"The ROM could not be extracted. Check the log for details.", "OK", "");
|
||||
extractFailed = false;
|
||||
}
|
||||
extractionTask.reset();
|
||||
} else {
|
||||
if (!ImGui::IsPopupOpen("ROM Extraction")) {
|
||||
|
||||
Reference in New Issue
Block a user