2020-01-15 12:07:48 +00:00
|
|
|
#include "Runtime/MP1/CSaveGameScreen.hpp"
|
|
|
|
|
2020-09-13 01:13:38 +00:00
|
|
|
#include "Runtime/Audio/CSfxManager.hpp"
|
2020-01-15 12:07:48 +00:00
|
|
|
#include "Runtime/CMemoryCardSys.hpp"
|
|
|
|
#include "Runtime/CSimplePool.hpp"
|
|
|
|
#include "Runtime/GameGlobalObjects.hpp"
|
|
|
|
#include "Runtime/GuiSys/CGuiFrame.hpp"
|
|
|
|
#include "Runtime/GuiSys/CGuiTableGroup.hpp"
|
|
|
|
#include "Runtime/GuiSys/CGuiTextPane.hpp"
|
|
|
|
#include "Runtime/GuiSys/CGuiWidgetDrawParms.hpp"
|
|
|
|
#include "Runtime/MP1/MP1.hpp"
|
2016-12-19 19:20:30 +00:00
|
|
|
|
2021-04-10 08:42:06 +00:00
|
|
|
namespace metaforce::MP1 {
|
2016-12-19 19:20:30 +00:00
|
|
|
|
|
|
|
using EState = CMemoryCardDriver::EState;
|
2016-12-24 00:45:51 +00:00
|
|
|
using EError = CMemoryCardDriver::EError;
|
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
void CSaveGameScreen::ResetCardDriver() {
|
|
|
|
x92_savingDisabled = false;
|
|
|
|
x6c_cardDriver.reset();
|
|
|
|
bool importState = (x0_saveCtx == ESaveContext::FrontEnd && !x90_needsDriverReset);
|
|
|
|
x6c_cardDriver = ConstructCardDriver(importState);
|
|
|
|
x6c_cardDriver->StartCardProbe();
|
|
|
|
x10_uiType = EUIType::Empty;
|
|
|
|
SetUIText();
|
2016-12-24 00:45:51 +00:00
|
|
|
}
|
2016-12-19 19:20:30 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
CIOWin::EMessageReturn CSaveGameScreen::Update(float dt) {
|
2020-09-13 01:13:38 +00:00
|
|
|
if (!PumpLoad()) {
|
2018-12-08 05:30:43 +00:00
|
|
|
return CIOWin::EMessageReturn::Normal;
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
2016-12-24 00:45:51 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
x50_loadedFrame->Update(dt);
|
|
|
|
x6c_cardDriver->Update();
|
|
|
|
|
|
|
|
if (x6c_cardDriver->x10_state == EState::DriverClosed) {
|
|
|
|
if (x90_needsDriverReset) {
|
|
|
|
ResetCardDriver();
|
|
|
|
x90_needsDriverReset = false;
|
2020-09-13 01:13:38 +00:00
|
|
|
} else {
|
2018-12-08 05:30:43 +00:00
|
|
|
x80_iowRet = CIOWin::EMessageReturn::Exit;
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
2018-12-08 05:30:43 +00:00
|
|
|
} else if (x6c_cardDriver->x10_state == EState::CardCheckDone && x10_uiType != EUIType::NotOriginalCard) {
|
|
|
|
if (x6c_cardDriver->x28_cardSerial != x8_serial) {
|
|
|
|
if (x93_inGame) {
|
|
|
|
x10_uiType = EUIType::NotOriginalCard;
|
|
|
|
x91_uiTextDirty = true;
|
|
|
|
} else {
|
|
|
|
x8_serial = x6c_cardDriver->x28_cardSerial;
|
|
|
|
x6c_cardDriver->IndexFiles();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
x6c_cardDriver->IndexFiles();
|
2016-12-24 00:45:51 +00:00
|
|
|
}
|
2018-12-08 05:30:43 +00:00
|
|
|
} else if (x6c_cardDriver->x10_state == EState::Ready) {
|
2020-09-13 01:13:38 +00:00
|
|
|
if (x90_needsDriverReset) {
|
2018-12-08 05:30:43 +00:00
|
|
|
x6c_cardDriver->StartFileCreateTransactional();
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
2018-12-08 05:30:43 +00:00
|
|
|
}
|
2016-12-24 00:45:51 +00:00
|
|
|
|
2020-09-13 01:13:38 +00:00
|
|
|
if (x80_iowRet != CIOWin::EMessageReturn::Normal) {
|
2018-12-08 05:30:43 +00:00
|
|
|
return x80_iowRet;
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
2016-12-24 00:45:51 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
EUIType oldTp = x10_uiType;
|
|
|
|
x10_uiType = SelectUIType();
|
2020-09-13 01:13:38 +00:00
|
|
|
if (oldTp != x10_uiType || x91_uiTextDirty) {
|
2018-12-08 05:30:43 +00:00
|
|
|
SetUIText();
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
2016-12-24 00:45:51 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
if (x6c_cardDriver->x10_state == EState::NoCard) {
|
|
|
|
auto res = CMemoryCardSys::CardProbe(kabufuda::ECardSlot::SlotA);
|
2020-09-13 01:13:38 +00:00
|
|
|
if (res.x0_error == CMemoryCardSys::ECardResult::READY ||
|
|
|
|
res.x0_error == CMemoryCardSys::ECardResult::WRONGDEVICE) {
|
2018-12-08 05:30:43 +00:00
|
|
|
ResetCardDriver();
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
2018-12-08 05:30:43 +00:00
|
|
|
} else if (x6c_cardDriver->x10_state == EState::CardFormatted) {
|
|
|
|
ResetCardDriver();
|
|
|
|
} else if (x6c_cardDriver->x10_state == EState::FileBad && x6c_cardDriver->x14_error == EError::FileMissing) {
|
|
|
|
x6c_cardDriver->StartFileCreate();
|
|
|
|
}
|
|
|
|
|
|
|
|
return CIOWin::EMessageReturn::Normal;
|
2016-12-19 19:20:30 +00:00
|
|
|
}
|
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
bool CSaveGameScreen::PumpLoad() {
|
2020-09-13 01:13:38 +00:00
|
|
|
if (x50_loadedFrame != nullptr) {
|
2016-12-19 19:20:30 +00:00
|
|
|
return true;
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
|
|
|
if (!x14_txtrSaveBanner.IsLoaded()) {
|
2018-12-08 05:30:43 +00:00
|
|
|
return false;
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
|
|
|
if (!x20_txtrSaveIcon0.IsLoaded()) {
|
2018-12-08 05:30:43 +00:00
|
|
|
return false;
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
|
|
|
if (!x2c_txtrSaveIcon1.IsLoaded()) {
|
2018-12-08 05:30:43 +00:00
|
|
|
return false;
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
|
|
|
if (!x38_strgMemoryCard.IsLoaded()) {
|
2018-12-08 05:30:43 +00:00
|
|
|
return false;
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
|
|
|
for (TLockedToken<CSaveWorld>& savw : x70_saveWorlds) {
|
|
|
|
if (!savw.IsLoaded()) {
|
2018-12-08 05:30:43 +00:00
|
|
|
return false;
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!x44_frmeGenericMenu.IsLoaded()) {
|
2018-12-08 05:30:43 +00:00
|
|
|
return false;
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
2018-12-08 05:30:43 +00:00
|
|
|
|
|
|
|
x50_loadedFrame = x44_frmeGenericMenu.GetObj();
|
|
|
|
x50_loadedFrame->SetAspectConstraint(1.78f);
|
|
|
|
x54_textpane_message = static_cast<CGuiTextPane*>(x50_loadedFrame->FindWidget("textpane_message"));
|
|
|
|
x58_tablegroup_choices = static_cast<CGuiTableGroup*>(x50_loadedFrame->FindWidget("tablegroup_choices"));
|
|
|
|
x5c_textpane_choice0 = static_cast<CGuiTextPane*>(x50_loadedFrame->FindWidget("textpane_choice0"));
|
|
|
|
x60_textpane_choice1 = static_cast<CGuiTextPane*>(x50_loadedFrame->FindWidget("textpane_choice1"));
|
|
|
|
x64_textpane_choice2 = static_cast<CGuiTextPane*>(x50_loadedFrame->FindWidget("textpane_choice2"));
|
|
|
|
x68_textpane_choice3 = static_cast<CGuiTextPane*>(x50_loadedFrame->FindWidget("textpane_choice3"));
|
|
|
|
|
2019-08-14 07:45:28 +00:00
|
|
|
x58_tablegroup_choices->SetMenuAdvanceCallback([this](CGuiTableGroup* caller) { DoAdvance(caller); });
|
2018-12-08 05:30:43 +00:00
|
|
|
x58_tablegroup_choices->SetMenuSelectionChangeCallback(
|
2019-08-14 07:45:28 +00:00
|
|
|
[this](CGuiTableGroup* caller, int oldSel) { DoSelectionChange(caller, oldSel); });
|
2018-12-08 05:30:43 +00:00
|
|
|
|
2020-09-13 01:13:38 +00:00
|
|
|
if (x0_saveCtx == ESaveContext::InGame) {
|
2018-12-08 05:30:43 +00:00
|
|
|
x6c_cardDriver->StartCardProbe();
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
2018-12-08 05:30:43 +00:00
|
|
|
|
|
|
|
x10_uiType = SelectUIType();
|
|
|
|
SetUIText();
|
|
|
|
return true;
|
2016-12-19 19:20:30 +00:00
|
|
|
}
|
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
CSaveGameScreen::EUIType CSaveGameScreen::SelectUIType() const {
|
2020-09-13 01:13:38 +00:00
|
|
|
if (x6c_cardDriver->x10_state == EState::NoCard) {
|
2018-12-08 05:30:43 +00:00
|
|
|
return EUIType::NoCardFound;
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
2016-12-19 19:20:30 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
switch (x10_uiType) {
|
|
|
|
case EUIType::ProgressWillBeLost:
|
|
|
|
case EUIType::NotOriginalCard:
|
|
|
|
case EUIType::AllDataWillBeLost:
|
|
|
|
return x10_uiType;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2016-12-19 19:20:30 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
if (CMemoryCardDriver::IsCardBusy(x6c_cardDriver->x10_state)) {
|
2020-09-13 01:13:38 +00:00
|
|
|
if (CMemoryCardDriver::IsCardWriting(x6c_cardDriver->x10_state)) {
|
2018-12-08 05:30:43 +00:00
|
|
|
return EUIType::BusyWriting;
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
2018-12-08 05:30:43 +00:00
|
|
|
return EUIType::BusyReading;
|
|
|
|
}
|
2016-12-19 19:20:30 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
if (x6c_cardDriver->x10_state == EState::Ready) {
|
2020-09-13 01:13:38 +00:00
|
|
|
if (x6c_cardDriver->x14_error == CMemoryCardDriver::EError::CardStillFull) {
|
2018-12-08 05:30:43 +00:00
|
|
|
return EUIType::StillInsufficientSpace;
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
2018-12-08 05:30:43 +00:00
|
|
|
return EUIType::SaveReady;
|
|
|
|
}
|
2016-12-19 19:20:30 +00:00
|
|
|
|
2020-09-13 01:13:38 +00:00
|
|
|
if (x6c_cardDriver->x14_error == CMemoryCardDriver::EError::CardBroken) {
|
2018-12-08 05:30:43 +00:00
|
|
|
return EUIType::NeedsFormatBroken;
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
2016-12-19 19:20:30 +00:00
|
|
|
|
2020-09-13 01:13:38 +00:00
|
|
|
if (x6c_cardDriver->x14_error == CMemoryCardDriver::EError::CardWrongCharacterSet) {
|
2018-12-08 05:30:43 +00:00
|
|
|
return EUIType::NeedsFormatEncoding;
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
2016-12-19 19:20:30 +00:00
|
|
|
|
2020-09-13 01:13:38 +00:00
|
|
|
if (x6c_cardDriver->x14_error == CMemoryCardDriver::EError::CardWrongDevice) {
|
2018-12-08 05:30:43 +00:00
|
|
|
return EUIType::WrongDevice;
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
2018-12-08 05:30:43 +00:00
|
|
|
|
|
|
|
if (x6c_cardDriver->x14_error == CMemoryCardDriver::EError::CardFull) {
|
2020-09-13 01:13:38 +00:00
|
|
|
if (x6c_cardDriver->x10_state == EState::CardCheckFailed) {
|
2018-12-08 05:30:43 +00:00
|
|
|
return EUIType::InsufficientSpaceBadCheck;
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
2018-12-08 05:30:43 +00:00
|
|
|
return EUIType::InsufficientSpaceOKCheck;
|
|
|
|
}
|
2016-12-19 19:20:30 +00:00
|
|
|
|
2020-09-13 01:13:38 +00:00
|
|
|
if (x6c_cardDriver->x14_error == CMemoryCardDriver::EError::CardNon8KSectors) {
|
2018-12-08 05:30:43 +00:00
|
|
|
return EUIType::IncompatibleCard;
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
2016-12-19 19:20:30 +00:00
|
|
|
|
2020-09-13 01:13:38 +00:00
|
|
|
if (x6c_cardDriver->x14_error == CMemoryCardDriver::EError::FileCorrupted) {
|
2018-12-08 05:30:43 +00:00
|
|
|
return EUIType::SaveCorrupt;
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
2016-12-19 19:20:30 +00:00
|
|
|
|
2020-09-13 01:13:38 +00:00
|
|
|
if (x6c_cardDriver->x14_error == CMemoryCardDriver::EError::CardIOError) {
|
2018-12-08 05:30:43 +00:00
|
|
|
return EUIType::CardDamaged;
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
2016-12-19 19:20:30 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
return EUIType::Empty;
|
2016-12-19 19:20:30 +00:00
|
|
|
}
|
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
void CSaveGameScreen::SetUIText() {
|
|
|
|
x91_uiTextDirty = false;
|
|
|
|
|
|
|
|
s32 msgA = -1;
|
|
|
|
s32 msgB = -1;
|
|
|
|
s32 opt0 = -1;
|
|
|
|
s32 opt1 = -1;
|
|
|
|
s32 opt2 = -1;
|
|
|
|
|
|
|
|
std::u16string msgAStr;
|
|
|
|
std::u16string msgBStr;
|
|
|
|
std::u16string opt0Str;
|
|
|
|
std::u16string opt1Str;
|
|
|
|
std::u16string opt2Str;
|
|
|
|
std::u16string opt3Str;
|
|
|
|
|
|
|
|
switch (x10_uiType) {
|
|
|
|
case EUIType::BusyReading:
|
|
|
|
msgB = 24; // Reading
|
|
|
|
break;
|
|
|
|
case EUIType::BusyWriting:
|
|
|
|
msgB = 25; // Writing
|
|
|
|
break;
|
|
|
|
case EUIType::NoCardFound:
|
2020-04-17 00:19:55 +00:00
|
|
|
if (g_Main->IsUSA() && !g_Main->IsTrilogy()) {
|
|
|
|
msgB = 0; // No card found
|
|
|
|
opt0 = 17; // Continue without saving
|
|
|
|
opt1 = 18; // Retry
|
|
|
|
opt2 = -2;
|
|
|
|
opt2Str = u"Create Dolphin Card";
|
|
|
|
} else {
|
|
|
|
msgAStr = u"This version of Metroid Prime\nhas a currently unsupported save format.\n";
|
|
|
|
msgBStr = u"&push;&main-color=$ff0000ff;Saving has been disabled.&pop;\n";
|
|
|
|
opt0 = -2;
|
|
|
|
opt0Str = u"Press &image=SI,1.0,0.68,05AF9CAA; to proceed.\n";
|
|
|
|
}
|
2018-12-08 05:30:43 +00:00
|
|
|
break;
|
|
|
|
case EUIType::NeedsFormatBroken:
|
|
|
|
msgB = 1; // Needs format (card broken)
|
|
|
|
opt0 = 17; // Continue without saving
|
|
|
|
opt1 = 18; // Retry
|
|
|
|
opt2 = 20; // Format
|
|
|
|
break;
|
|
|
|
case EUIType::NeedsFormatEncoding:
|
|
|
|
msgB = 2; // Needs format (wrong char set)
|
|
|
|
opt0 = 17; // Continue without saving
|
|
|
|
opt1 = 18; // Retry
|
|
|
|
opt2 = 20; // Format
|
|
|
|
break;
|
|
|
|
case EUIType::CardDamaged:
|
|
|
|
msgB = 3; // Damaged
|
|
|
|
opt0 = 17; // Continue without saving
|
|
|
|
opt1 = 18; // Retry
|
|
|
|
break;
|
|
|
|
case EUIType::WrongDevice:
|
|
|
|
msgB = 5; // Invalid device
|
|
|
|
opt0 = 17; // Continue without saving
|
|
|
|
opt1 = 18; // Retry
|
|
|
|
break;
|
|
|
|
case EUIType::InsufficientSpaceOKCheck:
|
|
|
|
msgB = 6; // Insufficient space (completely filled)
|
|
|
|
opt0 = 17; // Continue without saving
|
|
|
|
opt1 = 18; // Retry
|
|
|
|
opt2 = 19; // Manage memory card
|
|
|
|
break;
|
|
|
|
case EUIType::InsufficientSpaceBadCheck:
|
2020-09-13 01:13:38 +00:00
|
|
|
msgB = static_cast<int>(bool(x0_saveCtx)) + 9; // Insufficient space A or B
|
|
|
|
opt0 = 17; // Continue without saving
|
|
|
|
opt1 = 18; // Retry
|
|
|
|
opt2 = 19; // Manage memory card
|
2018-12-08 05:30:43 +00:00
|
|
|
break;
|
|
|
|
case EUIType::IncompatibleCard:
|
|
|
|
msgB = 7; // Incompatible card
|
|
|
|
opt0 = 17; // Continue without saving
|
|
|
|
opt1 = 18; // Retry
|
|
|
|
break;
|
|
|
|
case EUIType::SaveCorrupt:
|
|
|
|
msgB = 4; // Save corrupt
|
|
|
|
opt0 = 22; // Delete corrupt file
|
|
|
|
opt1 = 17; // Continue without saving
|
|
|
|
opt2 = 18; // Retry
|
|
|
|
break;
|
|
|
|
case EUIType::StillInsufficientSpace:
|
|
|
|
if (x0_saveCtx == ESaveContext::InGame) {
|
|
|
|
msgB = 10; // Insufficient space B
|
|
|
|
opt0 = 17; // Continue without saving
|
|
|
|
opt1 = 18; // Retry
|
|
|
|
opt2 = 19; // Manage memory card
|
|
|
|
} else {
|
|
|
|
msgB = 9; // Insufficient space A
|
|
|
|
opt0 = 17; // Continue without saving
|
|
|
|
opt1 = 18; // Retry
|
|
|
|
opt2 = 19; // Manage memory card
|
2016-12-29 05:53:00 +00:00
|
|
|
}
|
2018-12-08 05:30:43 +00:00
|
|
|
break;
|
|
|
|
case EUIType::ProgressWillBeLost:
|
|
|
|
msgA = 28; // Warning
|
|
|
|
msgB = 11; // Progress will be lost
|
|
|
|
opt0 = 21; // Cancel
|
|
|
|
opt1 = 16; // Continue
|
|
|
|
break;
|
|
|
|
case EUIType::NotOriginalCard:
|
|
|
|
msgA = 28; // Warning
|
|
|
|
msgB = 12; // Not the original card
|
|
|
|
opt0 = x0_saveCtx == ESaveContext::InGame ? 21 : 17; // Cancel : continue without saving
|
|
|
|
opt1 = 16; // Continue
|
|
|
|
break;
|
|
|
|
case EUIType::AllDataWillBeLost:
|
|
|
|
msgA = 28; // Warning
|
|
|
|
msgB = 13; // All card data will be erased
|
|
|
|
opt0 = 16; // Continue
|
|
|
|
opt1 = 21; // Cancel
|
|
|
|
break;
|
|
|
|
case EUIType::SaveReady:
|
|
|
|
if (x0_saveCtx == ESaveContext::InGame) {
|
|
|
|
msgB = 8; // Save progress?
|
|
|
|
opt0 = 14; // Yes
|
|
|
|
opt1 = 15; // No
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2016-12-29 05:53:00 +00:00
|
|
|
|
2020-09-13 01:13:38 +00:00
|
|
|
if (msgA > -1) {
|
2018-12-08 05:30:43 +00:00
|
|
|
msgAStr = x38_strgMemoryCard->GetString(msgA);
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
|
|
|
if (msgB > -1) {
|
2018-12-08 05:30:43 +00:00
|
|
|
msgBStr = x38_strgMemoryCard->GetString(msgB);
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
2018-12-08 05:30:43 +00:00
|
|
|
x54_textpane_message->TextSupport().SetText(msgAStr + msgBStr);
|
2016-12-29 05:53:00 +00:00
|
|
|
|
2020-09-13 01:13:38 +00:00
|
|
|
if (opt0 > -1) {
|
2018-12-08 05:30:43 +00:00
|
|
|
opt0Str = x38_strgMemoryCard->GetString(opt0);
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
2018-12-08 05:30:43 +00:00
|
|
|
x5c_textpane_choice0->TextSupport().SetText(opt0Str);
|
2016-12-29 05:53:00 +00:00
|
|
|
|
2020-09-13 01:13:38 +00:00
|
|
|
if (opt1 > -1) {
|
2018-12-08 05:30:43 +00:00
|
|
|
opt1Str = x38_strgMemoryCard->GetString(opt1);
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
2018-12-08 05:30:43 +00:00
|
|
|
x60_textpane_choice1->TextSupport().SetText(opt1Str);
|
2016-12-29 05:53:00 +00:00
|
|
|
|
2020-09-13 01:13:38 +00:00
|
|
|
if (opt2 > -1) {
|
2018-12-08 05:30:43 +00:00
|
|
|
opt2Str = x38_strgMemoryCard->GetString(opt2);
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
2018-12-08 05:30:43 +00:00
|
|
|
x64_textpane_choice2->TextSupport().SetText(opt2Str);
|
2016-12-29 05:53:00 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
x68_textpane_choice3->TextSupport().SetText(opt3Str);
|
2016-12-29 05:53:00 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
m_touchBar->SetUIOpts(opt0Str, opt1Str, opt2Str);
|
2017-02-10 23:58:05 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
x5c_textpane_choice0->SetIsSelectable(opt0 != -1);
|
|
|
|
x60_textpane_choice1->SetIsSelectable(opt1 != -1);
|
|
|
|
x64_textpane_choice2->SetIsSelectable(opt2 != -1);
|
|
|
|
x68_textpane_choice3->SetIsSelectable(false);
|
2016-12-29 05:53:00 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
x58_tablegroup_choices->SetIsActive(opt0 != -1 || opt1 != -1 || opt2 != -1);
|
|
|
|
x58_tablegroup_choices->SetUserSelection(0);
|
|
|
|
SetUIColors();
|
2016-12-29 05:53:00 +00:00
|
|
|
}
|
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
void CSaveGameScreen::SetUIColors() {
|
2019-02-24 07:15:54 +00:00
|
|
|
x58_tablegroup_choices->SetColors(zeus::skWhite, zeus::CColor{0.627450f, 0.627450f, 0.627450f, 0.784313f});
|
2016-12-19 19:20:30 +00:00
|
|
|
}
|
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
void CSaveGameScreen::Draw() const {
|
2019-07-21 08:42:52 +00:00
|
|
|
SCOPED_GRAPHICS_DEBUG_GROUP("CSaveGameScreen::Draw", zeus::skPurple);
|
2020-09-13 01:13:38 +00:00
|
|
|
if (x50_loadedFrame != nullptr) {
|
2020-04-26 05:15:02 +00:00
|
|
|
x50_loadedFrame->Draw(CGuiWidgetDrawParms::Default());
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
2016-12-29 05:53:00 +00:00
|
|
|
}
|
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
void CSaveGameScreen::ContinueWithoutSaving() {
|
|
|
|
x80_iowRet = CIOWin::EMessageReturn::RemoveIOWin;
|
|
|
|
g_GameState->SetCardSerial(0);
|
2016-12-19 19:20:30 +00:00
|
|
|
}
|
|
|
|
|
2020-09-13 01:13:38 +00:00
|
|
|
void CSaveGameScreen::DoAdvance([[maybe_unused]] CGuiTableGroup* caller) {
|
2018-12-08 05:30:43 +00:00
|
|
|
int userSel = x58_tablegroup_choices->GetUserSelection();
|
|
|
|
int sfx = -1;
|
|
|
|
|
|
|
|
switch (x10_uiType) {
|
|
|
|
case EUIType::NoCardFound:
|
|
|
|
case EUIType::CardDamaged:
|
|
|
|
case EUIType::WrongDevice:
|
|
|
|
case EUIType::IncompatibleCard:
|
|
|
|
if (userSel == 0) {
|
|
|
|
/* Continue without saving */
|
2020-09-13 01:13:38 +00:00
|
|
|
if (x0_saveCtx == ESaveContext::InGame) {
|
2018-12-08 05:30:43 +00:00
|
|
|
x80_iowRet = CIOWin::EMessageReturn::RemoveIOWinAndExit;
|
2020-09-13 01:13:38 +00:00
|
|
|
} else {
|
2018-12-08 05:30:43 +00:00
|
|
|
ContinueWithoutSaving();
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
2018-12-08 05:30:43 +00:00
|
|
|
sfx = x8c_navBackSfx;
|
|
|
|
} else if (userSel == 1) {
|
|
|
|
/* Retry */
|
|
|
|
ResetCardDriver();
|
|
|
|
sfx = x84_navConfirmSfx;
|
|
|
|
} else if (userSel == 2 && x10_uiType == EUIType::NoCardFound) {
|
|
|
|
/* Create Dolphin Card */
|
|
|
|
CMemoryCardSys::CreateDolphinCard(kabufuda::ECardSlot::SlotA);
|
|
|
|
ResetCardDriver();
|
|
|
|
sfx = x84_navConfirmSfx;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EUIType::NeedsFormatBroken:
|
|
|
|
case EUIType::NeedsFormatEncoding:
|
|
|
|
if (userSel == 0) {
|
|
|
|
/* Continue without saving */
|
2020-09-13 01:13:38 +00:00
|
|
|
if (x0_saveCtx == ESaveContext::InGame) {
|
2018-12-08 05:30:43 +00:00
|
|
|
x80_iowRet = CIOWin::EMessageReturn::RemoveIOWinAndExit;
|
2020-09-13 01:13:38 +00:00
|
|
|
} else {
|
2018-12-08 05:30:43 +00:00
|
|
|
ContinueWithoutSaving();
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
2018-12-08 05:30:43 +00:00
|
|
|
sfx = x8c_navBackSfx;
|
|
|
|
} else if (userSel == 1) {
|
|
|
|
/* Retry */
|
|
|
|
ResetCardDriver();
|
|
|
|
sfx = x84_navConfirmSfx;
|
|
|
|
} else if (userSel == 2) {
|
|
|
|
/* Format */
|
|
|
|
x10_uiType = EUIType::AllDataWillBeLost;
|
|
|
|
x91_uiTextDirty = true;
|
|
|
|
sfx = x84_navConfirmSfx;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EUIType::InsufficientSpaceBadCheck:
|
|
|
|
case EUIType::InsufficientSpaceOKCheck:
|
|
|
|
if (userSel == 0) {
|
|
|
|
/* Continue without saving */
|
2020-09-13 01:13:38 +00:00
|
|
|
if (x0_saveCtx == ESaveContext::InGame) {
|
2018-12-08 05:30:43 +00:00
|
|
|
x80_iowRet = CIOWin::EMessageReturn::RemoveIOWinAndExit;
|
2020-09-13 01:13:38 +00:00
|
|
|
} else {
|
2018-12-08 05:30:43 +00:00
|
|
|
ContinueWithoutSaving();
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
2018-12-08 05:30:43 +00:00
|
|
|
sfx = x8c_navBackSfx;
|
|
|
|
} else if (userSel == 1) {
|
|
|
|
/* Retry */
|
|
|
|
ResetCardDriver();
|
|
|
|
sfx = x84_navConfirmSfx;
|
|
|
|
} else if (userSel == 2) {
|
|
|
|
/* Manage memory card */
|
|
|
|
if (x0_saveCtx == ESaveContext::InGame) {
|
|
|
|
x10_uiType = EUIType::ProgressWillBeLost;
|
|
|
|
x91_uiTextDirty = true;
|
|
|
|
sfx = x84_navConfirmSfx;
|
2020-09-13 01:13:38 +00:00
|
|
|
} else {
|
2018-12-08 05:30:43 +00:00
|
|
|
static_cast<MP1::CMain*>(g_Main)->SetManageCard(true);
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
2018-12-08 05:30:43 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EUIType::SaveCorrupt:
|
|
|
|
if (userSel == 0) {
|
|
|
|
/* Delete corrupt file */
|
|
|
|
x6c_cardDriver->StartFileDeleteBad();
|
|
|
|
sfx = x84_navConfirmSfx;
|
|
|
|
} else if (userSel == 1) {
|
|
|
|
/* Continue without saving */
|
2020-09-13 01:13:38 +00:00
|
|
|
if (x0_saveCtx == ESaveContext::InGame) {
|
2018-12-08 05:30:43 +00:00
|
|
|
x80_iowRet = CIOWin::EMessageReturn::RemoveIOWinAndExit;
|
2020-09-13 01:13:38 +00:00
|
|
|
} else {
|
2018-12-08 05:30:43 +00:00
|
|
|
ContinueWithoutSaving();
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
2018-12-08 05:30:43 +00:00
|
|
|
sfx = x8c_navBackSfx;
|
|
|
|
} else if (userSel == 2) {
|
|
|
|
/* Retry */
|
|
|
|
ResetCardDriver();
|
|
|
|
sfx = x84_navConfirmSfx;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EUIType::StillInsufficientSpace:
|
|
|
|
if (x0_saveCtx == ESaveContext::InGame) {
|
|
|
|
if (userSel == 0) {
|
|
|
|
/* Continue without saving */
|
|
|
|
x80_iowRet = CIOWin::EMessageReturn::RemoveIOWinAndExit;
|
|
|
|
sfx = x8c_navBackSfx;
|
|
|
|
} else if (userSel == 1) {
|
|
|
|
/* Retry */
|
|
|
|
ResetCardDriver();
|
|
|
|
sfx = x84_navConfirmSfx;
|
|
|
|
} else if (userSel == 2) {
|
|
|
|
/* Manage memory card */
|
|
|
|
x10_uiType = EUIType::ProgressWillBeLost;
|
|
|
|
x91_uiTextDirty = true;
|
|
|
|
sfx = x84_navConfirmSfx;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (userSel == 0) {
|
|
|
|
/* Continue without saving */
|
|
|
|
if (x93_inGame) {
|
|
|
|
x80_iowRet = CIOWin::EMessageReturn::RemoveIOWinAndExit;
|
|
|
|
sfx = x8c_navBackSfx;
|
|
|
|
} else {
|
|
|
|
x6c_cardDriver->ClearError();
|
|
|
|
x92_savingDisabled = true;
|
|
|
|
sfx = x84_navConfirmSfx;
|
2016-12-30 06:37:01 +00:00
|
|
|
}
|
2018-12-08 05:30:43 +00:00
|
|
|
} else if (userSel == 1) {
|
|
|
|
/* Retry */
|
|
|
|
ResetCardDriver();
|
|
|
|
sfx = x84_navConfirmSfx;
|
|
|
|
} else if (userSel == 2) {
|
|
|
|
/* Manage memory card */
|
|
|
|
static_cast<MP1::CMain*>(g_Main)->SetManageCard(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EUIType::ProgressWillBeLost:
|
|
|
|
if (userSel == 1) {
|
|
|
|
/* Continue */
|
|
|
|
static_cast<MP1::CMain*>(g_Main)->SetManageCard(true);
|
|
|
|
} else if (userSel == 0) {
|
|
|
|
/* Cancel */
|
|
|
|
x80_iowRet = CIOWin::EMessageReturn::RemoveIOWinAndExit;
|
|
|
|
sfx = x8c_navBackSfx;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EUIType::NotOriginalCard:
|
|
|
|
if (userSel == 1) {
|
|
|
|
/* Continue */
|
|
|
|
x8_serial = x6c_cardDriver->x28_cardSerial;
|
|
|
|
x10_uiType = EUIType::Empty;
|
|
|
|
x6c_cardDriver->IndexFiles();
|
|
|
|
sfx = x84_navConfirmSfx;
|
|
|
|
} else if (userSel == 0) {
|
|
|
|
/* Cancel */
|
|
|
|
x80_iowRet = CIOWin::EMessageReturn::RemoveIOWinAndExit;
|
|
|
|
sfx = x8c_navBackSfx;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EUIType::AllDataWillBeLost:
|
|
|
|
if (userSel == 0) {
|
|
|
|
/* Continue */
|
|
|
|
x6c_cardDriver->StartCardFormat();
|
|
|
|
x10_uiType = EUIType::Empty;
|
|
|
|
sfx = x84_navConfirmSfx;
|
|
|
|
} else if (userSel == 1) {
|
|
|
|
/* Cancel */
|
|
|
|
ResetCardDriver();
|
|
|
|
sfx = x8c_navBackSfx;
|
|
|
|
}
|
|
|
|
break;
|
2016-12-29 05:53:00 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
case EUIType::SaveReady:
|
|
|
|
if (x0_saveCtx == ESaveContext::InGame) {
|
|
|
|
if (userSel == 0) {
|
|
|
|
/* Yes */
|
|
|
|
x6c_cardDriver->BuildExistingFileSlot(g_GameState->GetFileIdx());
|
|
|
|
x6c_cardDriver->StartFileCreateTransactional();
|
|
|
|
sfx = x84_navConfirmSfx;
|
|
|
|
} else if (userSel == 1) {
|
|
|
|
/* No */
|
|
|
|
x80_iowRet = CIOWin::EMessageReturn::RemoveIOWinAndExit;
|
|
|
|
sfx = x8c_navBackSfx;
|
|
|
|
}
|
2016-12-29 05:53:00 +00:00
|
|
|
}
|
2019-02-18 05:47:46 +00:00
|
|
|
break;
|
2016-12-19 19:20:30 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2016-12-19 19:20:30 +00:00
|
|
|
|
2020-09-13 01:13:38 +00:00
|
|
|
if (sfx >= 0) {
|
2018-12-08 05:30:43 +00:00
|
|
|
CSfxManager::SfxStart(sfx, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
2016-12-19 19:20:30 +00:00
|
|
|
}
|
|
|
|
|
2020-09-13 01:13:38 +00:00
|
|
|
void CSaveGameScreen::DoSelectionChange([[maybe_unused]] CGuiTableGroup* caller, [[maybe_unused]] int oldSel) {
|
2018-12-08 05:30:43 +00:00
|
|
|
SetUIColors();
|
|
|
|
CSfxManager::SfxStart(x88_navMoveSfx, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
|
2016-12-19 19:20:30 +00:00
|
|
|
}
|
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
void CSaveGameScreen::ProcessUserInput(const CFinalInput& input) {
|
2020-09-13 01:13:38 +00:00
|
|
|
if (x50_loadedFrame != nullptr) {
|
2018-12-08 05:30:43 +00:00
|
|
|
x50_loadedFrame->ProcessUserInput(input);
|
2016-12-19 19:20:30 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
int tbOpt = m_touchBar->PopOption();
|
|
|
|
if (tbOpt != -1) {
|
|
|
|
x58_tablegroup_choices->SetUserSelection(tbOpt);
|
|
|
|
SetUIColors();
|
|
|
|
DoAdvance(x58_tablegroup_choices);
|
2016-12-30 06:37:01 +00:00
|
|
|
}
|
2018-12-08 05:30:43 +00:00
|
|
|
}
|
2016-12-19 19:20:30 +00:00
|
|
|
}
|
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
void CSaveGameScreen::StartGame(int idx) {
|
|
|
|
const CGameState::GameFileStateInfo* info = x6c_cardDriver->GetGameFileStateInfo(idx);
|
|
|
|
x6c_cardDriver->ExportPersistentOptions();
|
|
|
|
x6c_cardDriver->BuildNewFileSlot(idx);
|
2020-09-13 01:13:38 +00:00
|
|
|
if (info == nullptr) {
|
2016-12-31 00:51:51 +00:00
|
|
|
x6c_cardDriver->StartFileCreateTransactional();
|
2020-09-13 01:13:38 +00:00
|
|
|
} else {
|
2018-12-08 05:30:43 +00:00
|
|
|
x80_iowRet = CIOWin::EMessageReturn::Exit;
|
2020-09-13 01:13:38 +00:00
|
|
|
}
|
2016-12-31 00:51:51 +00:00
|
|
|
}
|
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
void CSaveGameScreen::SaveNESState() {
|
|
|
|
if (!x92_savingDisabled) {
|
|
|
|
x90_needsDriverReset = true;
|
|
|
|
x8_serial = x6c_cardDriver->x28_cardSerial;
|
|
|
|
x6c_cardDriver->StartFileCreateTransactional();
|
|
|
|
}
|
2016-12-19 19:20:30 +00:00
|
|
|
}
|
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
void CSaveGameScreen::EraseGame(int idx) {
|
|
|
|
x6c_cardDriver->EraseFileSlot(idx);
|
|
|
|
x90_needsDriverReset = true;
|
|
|
|
x6c_cardDriver->StartFileCreateTransactional();
|
|
|
|
}
|
2016-12-19 19:20:30 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
const CGameState::GameFileStateInfo* CSaveGameScreen::GetGameData(int idx) const {
|
|
|
|
return x6c_cardDriver->GetGameFileStateInfo(idx);
|
2016-12-19 19:20:30 +00:00
|
|
|
}
|
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
CSaveGameScreen::CSaveGameScreen(ESaveContext saveCtx, u64 serial)
|
|
|
|
: x0_saveCtx(saveCtx), x8_serial(serial), m_touchBar(NewSaveUITouchBar()) {
|
|
|
|
x14_txtrSaveBanner = g_SimplePool->GetObj("TXTR_SaveBanner");
|
|
|
|
x20_txtrSaveIcon0 = g_SimplePool->GetObj("TXTR_SaveIcon0");
|
|
|
|
x2c_txtrSaveIcon1 = g_SimplePool->GetObj("TXTR_SaveIcon1");
|
|
|
|
x38_strgMemoryCard = g_SimplePool->GetObj("STRG_MemoryCard");
|
|
|
|
x44_frmeGenericMenu = g_SimplePool->GetObj("FRME_GenericMenu");
|
|
|
|
|
|
|
|
x6c_cardDriver = ConstructCardDriver(x0_saveCtx == ESaveContext::FrontEnd);
|
|
|
|
|
|
|
|
if (saveCtx == ESaveContext::InGame) {
|
|
|
|
x84_navConfirmSfx = SFXui_advance;
|
|
|
|
x88_navMoveSfx = SFXui_table_selection_change;
|
|
|
|
x8c_navBackSfx = SFXui_table_change_mode;
|
|
|
|
}
|
|
|
|
x93_inGame = bool(saveCtx);
|
|
|
|
|
|
|
|
x70_saveWorlds.reserve(g_MemoryCardSys->GetMemoryWorlds().size());
|
|
|
|
for (const std::pair<CAssetId, CSaveWorldMemory>& wld : g_MemoryCardSys->GetMemoryWorlds()) {
|
2020-09-13 01:13:38 +00:00
|
|
|
x70_saveWorlds.emplace_back(g_SimplePool->GetObj(SObjectTag{FOURCC('SAVW'), wld.second.GetSaveWorldAssetId()}));
|
2018-12-08 05:30:43 +00:00
|
|
|
}
|
2016-12-19 19:20:30 +00:00
|
|
|
}
|
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
std::unique_ptr<CMemoryCardDriver> CSaveGameScreen::ConstructCardDriver(bool importPersistent) {
|
|
|
|
return std::make_unique<CMemoryCardDriver>(kabufuda::ECardSlot::SlotA,
|
|
|
|
g_ResFactory->GetResourceIdByName("TXTR_SaveBanner")->id,
|
|
|
|
g_ResFactory->GetResourceIdByName("TXTR_SaveIcon0")->id,
|
|
|
|
g_ResFactory->GetResourceIdByName("TXTR_SaveIcon1")->id, importPersistent);
|
2016-12-19 19:20:30 +00:00
|
|
|
}
|
2018-12-08 05:30:43 +00:00
|
|
|
|
2021-04-10 08:42:06 +00:00
|
|
|
} // namespace metaforce::MP1
|