From 4c09493a3f305684858b98f319f9e1fa0d09e830 Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Sun, 8 Jan 2017 17:44:00 -1000 Subject: [PATCH] CFrontEndUI work --- Runtime/CMemoryCardSys.cpp | 21 +- Runtime/CMemoryCardSys.hpp | 10 + Runtime/Graphics/CMoviePlayer.hpp | 1 + Runtime/GuiSys/CGuiCompoundWidget.cpp | 2 +- Runtime/GuiSys/CGuiCompoundWidget.hpp | 2 +- Runtime/GuiSys/CGuiObject.hpp | 6 +- Runtime/GuiSys/CGuiTableGroup.cpp | 229 ++++++++ Runtime/GuiSys/CGuiTableGroup.hpp | 62 +- Runtime/GuiSys/CGuiTextSupport.cpp | 8 + Runtime/GuiSys/CGuiTextSupport.hpp | 1 + Runtime/GuiSys/CGuiWidget.cpp | 2 +- Runtime/GuiSys/CGuiWidget.hpp | 6 +- Runtime/MP1/CFrontEndUI.cpp | 794 ++++++++++++++++++-------- Runtime/MP1/CFrontEndUI.hpp | 134 ++--- Runtime/MP1/CQuitScreen.cpp | 4 +- Runtime/MP1/CQuitScreen.hpp | 2 +- Runtime/MP1/CSaveUI.cpp | 18 +- Runtime/MP1/CSaveUI.hpp | 10 +- Runtime/MP1/MP1.hpp | 2 +- 19 files changed, 938 insertions(+), 376 deletions(-) diff --git a/Runtime/CMemoryCardSys.cpp b/Runtime/CMemoryCardSys.cpp index c8fdd042f..f2a5096fb 100644 --- a/Runtime/CMemoryCardSys.cpp +++ b/Runtime/CMemoryCardSys.cpp @@ -61,6 +61,22 @@ bool CSaveWorldIntermediate::InitializePump() return false; } +bool CMemoryCardSys::HasSaveWorldMemory(ResId wldId) const +{ + auto existingSearch = + std::find_if(xc_memoryWorlds.cbegin(), xc_memoryWorlds.cend(), [&](const auto& wld) + { return wld.first == wldId; }); + return existingSearch != xc_memoryWorlds.cend(); +} + +const CSaveWorldMemory& CMemoryCardSys::GetSaveWorldMemory(ResId wldId) const +{ + auto existingSearch = + std::find_if(xc_memoryWorlds.cbegin(), xc_memoryWorlds.cend(), [&](const auto& wld) + { return wld.first == wldId; }); + return existingSearch->second; +} + CMemoryCardSys::CMemoryCardSys() { g_CardImagePaths[0] = ResolveDolphinCardPath(kabufuda::ECardSlot::SlotA); @@ -74,10 +90,7 @@ CMemoryCardSys::CMemoryCardSys() { if (tag.type == FOURCC('MLVL')) { - auto existingSearch = - std::find_if(xc_memoryWorlds.cbegin(), xc_memoryWorlds.cend(), [&](const auto& wld) - { return wld.first == tag.id; }); - if (existingSearch == xc_memoryWorlds.cend()) + if (!HasSaveWorldMemory(tag.id)) { xc_memoryWorlds.emplace_back(tag.id, CSaveWorldMemory{}); x1c_worldInter->emplace_back(tag.id, -1); diff --git a/Runtime/CMemoryCardSys.hpp b/Runtime/CMemoryCardSys.hpp index 250df948d..3399e093d 100644 --- a/Runtime/CMemoryCardSys.hpp +++ b/Runtime/CMemoryCardSys.hpp @@ -32,6 +32,12 @@ public: const TLockedToken& GetWorldName() const { return x2c_worldName; } const TLockedToken& GetSaveWorld() const { return x3c_saveWorld; } + std::wstring GetFrontEndName() const + { + if (!x2c_worldName) + return {}; + return x2c_worldName->GetString(0); + } }; class CSaveWorldIntermediate @@ -83,6 +89,10 @@ public: const std::vector& GetHints() const { return x0_hints->GetHints(); } const std::vector>& GetMemoryWorlds() const { return xc_memoryWorlds; } const std::vector>& GetScanStates() const { return x20_scanStates; } + + bool HasSaveWorldMemory(ResId wldId) const; + const CSaveWorldMemory& GetSaveWorldMemory(ResId wldId) const; + CMemoryCardSys(); bool InitializePump(); diff --git a/Runtime/Graphics/CMoviePlayer.hpp b/Runtime/Graphics/CMoviePlayer.hpp index c01a12afe..c8074202d 100644 --- a/Runtime/Graphics/CMoviePlayer.hpp +++ b/Runtime/Graphics/CMoviePlayer.hpp @@ -156,6 +156,7 @@ public: return false; return xc8_curFrame == x28_thpHead.numFrames; } + bool IsLooping() const { return xf4_24_loop; } bool GetIsFullyCached() const {return xa0_bufferQueue.size() >= xf0_preLoadFrames;} float GetPlayedSeconds() const {return xdc_frameRem + xe8_curSeconds;} float GetTotalSeconds() const {return xe4_totalSeconds;} diff --git a/Runtime/GuiSys/CGuiCompoundWidget.cpp b/Runtime/GuiSys/CGuiCompoundWidget.cpp index 2c0946ef1..991621e58 100644 --- a/Runtime/GuiSys/CGuiCompoundWidget.cpp +++ b/Runtime/GuiSys/CGuiCompoundWidget.cpp @@ -30,7 +30,7 @@ void CGuiCompoundWidget::OnActiveChange() CGuiWidget::OnActiveChange(); } -CGuiWidget* CGuiCompoundWidget::GetWorkerWidget(int id) +CGuiWidget* CGuiCompoundWidget::GetWorkerWidget(int id) const { CGuiWidget* child = static_cast(GetChildObject()); while (child) diff --git a/Runtime/GuiSys/CGuiCompoundWidget.hpp b/Runtime/GuiSys/CGuiCompoundWidget.hpp index 85bd6c9b1..803305c92 100644 --- a/Runtime/GuiSys/CGuiCompoundWidget.hpp +++ b/Runtime/GuiSys/CGuiCompoundWidget.hpp @@ -14,7 +14,7 @@ public: void OnVisibleChange(); void OnActiveChange(); - virtual CGuiWidget* GetWorkerWidget(int id); + virtual CGuiWidget* GetWorkerWidget(int id) const; }; } diff --git a/Runtime/GuiSys/CGuiObject.hpp b/Runtime/GuiSys/CGuiObject.hpp index 960913205..cc754b3d5 100644 --- a/Runtime/GuiSys/CGuiObject.hpp +++ b/Runtime/GuiSys/CGuiObject.hpp @@ -37,9 +37,9 @@ public: void MultiplyO2P(const zeus::CTransform& xf); void AddChildObject(CGuiObject* obj, bool makeWorldLocal, bool atEnd); CGuiObject* RemoveChildObject(CGuiObject* obj, bool makeWorldLocal); - CGuiObject* GetParent() {return x70_parent;} - CGuiObject* GetChildObject() {return x74_child;} - CGuiObject* GetNextSibling() {return x78_nextSibling;} + CGuiObject* GetParent() const {return x70_parent;} + CGuiObject* GetChildObject() const {return x74_child;} + CGuiObject* GetNextSibling() const {return x78_nextSibling;} void RecalculateTransforms(); void Reorthogonalize(); void SetO2WTransform(const zeus::CTransform& xf); diff --git a/Runtime/GuiSys/CGuiTableGroup.cpp b/Runtime/GuiSys/CGuiTableGroup.cpp index 3307b631c..74c6579bb 100644 --- a/Runtime/GuiSys/CGuiTableGroup.cpp +++ b/Runtime/GuiSys/CGuiTableGroup.cpp @@ -1,8 +1,38 @@ #include "CGuiTableGroup.hpp" +#include "Input/CFinalInput.hpp" namespace urde { +bool CGuiTableGroup::CRepeatState::Update(float dt, bool state) +{ + if (x0_timer == 0.f) + { + if (state) + { + x0_timer = 0.6f; + return true; + } + } + else + { + if (state) + { + x0_timer -= dt; + if (x0_timer <= 0.f) + { + x0_timer = 0.05f; + return true; + } + } + else + { + x0_timer = 0.f; + } + } + return false; +} + CGuiTableGroup::CGuiTableGroup(const CGuiWidgetParms& parms, int elementCount, int defaultSel, bool selectWraparound) : CGuiCompoundWidget(parms), @@ -11,6 +41,205 @@ CGuiTableGroup::CGuiTableGroup(const CGuiWidgetParms& parms, int elementCount, xd0_selectWraparound(selectWraparound) {} +void CGuiTableGroup::ProcessUserInput(const CFinalInput& input) +{ + if (input.PA()) + { + DoAdvance(); + } + else if (input.PB()) + { + DoCancel(); + } + else + { + bool decrement; + if (xd1_vertical) + decrement = (input.DLAUp() || input.DDPUp()); + else + decrement = (input.DLALeft() || input.DDPLeft()); + + bool increment; + if (xd1_vertical) + increment = (input.DLADown() || input.DDPDown()); + else + increment = (input.DLARight() || input.DDPRight()); + + if (xb8_decRepeat.Update(input.DeltaTime(), decrement) && decrement) + { + DoDecrement(); + return; + } + + if (xbc_incRepeat.Update(input.DeltaTime(), increment) && increment) + { + DoIncrement(); + return; + } + } +} + +bool CGuiTableGroup::IsWorkerSelectable(int idx) const +{ + CGuiWidget* widget = GetWorkerWidget(idx); + if (widget) + return widget->GetIsSelectable(); + return false; +} + +void CGuiTableGroup::SelectWorker(int idx) +{ + idx = zeus::clamp(0, idx, xc0_elementCount - 1); + if (idx < xc4_userSelection) + { + while (idx != xc4_userSelection) + DoSelectPrevRow(); + } + else + { + while (idx != xc4_userSelection) + DoSelectNextRow(); + } +} + +void CGuiTableGroup::DeactivateWorker(CGuiWidget* widget) +{ + widget->SetIsActive(false); +} + +void CGuiTableGroup::ActivateWorker(CGuiWidget* widget) +{ + widget->SetIsActive(true); +} + +CGuiTableGroup::TableSelectReturn CGuiTableGroup::DecrementSelectedRow() +{ + xc8_prevUserSelection = xc4_userSelection; + --xc4_userSelection; + if (xc4_userSelection < 0) + { + xc4_userSelection = xd0_selectWraparound ? xc0_elementCount - 1 : 0; + return xd0_selectWraparound ? TableSelectReturn::WrappedAround : TableSelectReturn::Unchanged; + } + return TableSelectReturn::Changed; +} + +CGuiTableGroup::TableSelectReturn CGuiTableGroup::IncrementSelectedRow() +{ + xc8_prevUserSelection = xc4_userSelection; + ++xc4_userSelection; + if (xc4_userSelection >= xc0_elementCount) + { + xc4_userSelection = xd0_selectWraparound ? 0 : xc0_elementCount - 1; + return xd0_selectWraparound ? TableSelectReturn::WrappedAround : TableSelectReturn::Unchanged; + } + return TableSelectReturn::Changed; +} + +void CGuiTableGroup::DoSelectPrevRow() +{ + DecrementSelectedRow(); + DeactivateWorker(GetWorkerWidget(xc8_prevUserSelection)); + ActivateWorker(GetWorkerWidget(xc4_userSelection)); +} + +void CGuiTableGroup::DoSelectNextRow() +{ + IncrementSelectedRow(); + DeactivateWorker(GetWorkerWidget(xc8_prevUserSelection)); + ActivateWorker(GetWorkerWidget(xc4_userSelection)); +} + +void CGuiTableGroup::DoCancel() +{ + if (xec_doMenuCancel) + xec_doMenuCancel(this); +} + +void CGuiTableGroup::DoAdvance() +{ + if (xd4_doMenuAdvance) + xd4_doMenuAdvance(this); +} + +bool CGuiTableGroup::PreDecrement() +{ + if (xd0_selectWraparound) + { + for (int sel = (xc4_userSelection + xc0_elementCount - 1) % xc0_elementCount; + sel != xc4_userSelection; + sel = (sel + xc0_elementCount - 1) % xc0_elementCount) + { + if (IsWorkerSelectable(sel)) + { + SelectWorker(sel); + return true; + } + } + + } + else + { + for (int sel = std::max(-1, xc4_userSelection - 1) ; sel >= 0 ; --sel) + { + if (IsWorkerSelectable(sel)) + { + SelectWorker(sel); + return true; + } + } + } + + return false; +} + +void CGuiTableGroup::DoDecrement() +{ + if (!PreDecrement()) + return; + if (x104_doMenuSelChange) + x104_doMenuSelChange(this, xc4_userSelection); +} + +bool CGuiTableGroup::PreIncrement() +{ + if (xd0_selectWraparound) + { + for (int sel = (xc4_userSelection + 1) % xc0_elementCount; + sel != xc4_userSelection; + sel = (sel + 1) % xc0_elementCount) + { + if (IsWorkerSelectable(sel)) + { + SelectWorker(sel); + return true; + } + } + + } + else + { + for (int sel = std::min(xc0_elementCount, xc4_userSelection + 1) ; sel < xc0_elementCount ; ++sel) + { + if (IsWorkerSelectable(sel)) + { + SelectWorker(sel); + return true; + } + } + } + + return false; +} + +void CGuiTableGroup::DoIncrement() +{ + if (!PreIncrement()) + return; + if (x104_doMenuSelChange) + x104_doMenuSelChange(this, xc4_userSelection); +} + CGuiTableGroup* CGuiTableGroup::Create(CGuiFrame* frame, CInputStream& in, bool flag) { CGuiWidgetParms parms = ReadWidgetHeader(frame, in, flag); diff --git a/Runtime/GuiSys/CGuiTableGroup.hpp b/Runtime/GuiSys/CGuiTableGroup.hpp index 524099e7c..aaf0defeb 100644 --- a/Runtime/GuiSys/CGuiTableGroup.hpp +++ b/Runtime/GuiSys/CGuiTableGroup.hpp @@ -9,10 +9,13 @@ namespace urde class CGuiTableGroup : public CGuiCompoundWidget { public: - struct SomeState + class CRepeatState { - float x0_ = 0.f; + float x0_timer = 0.f; + public: + bool Update(float dt, bool state); }; + enum class TableSelectReturn { Changed, @@ -21,17 +24,34 @@ public: }; private: - SomeState xb8_; - SomeState xbc_; + CRepeatState xb8_decRepeat; + CRepeatState xbc_incRepeat; int xc0_elementCount; int xc4_userSelection; int xc8_prevUserSelection; int xcc_defaultUserSelection; bool xd0_selectWraparound; - bool xd1_ = true; + bool xd1_vertical = true; std::function xd4_doMenuAdvance; std::function xec_doMenuCancel; - std::function x104_doMenuSelChange; + std::function x104_doMenuSelChange; + + bool IsWorkerSelectable(int) const; + void SelectWorker(int); + void DeactivateWorker(CGuiWidget* widget); + void ActivateWorker(CGuiWidget* widget); + + TableSelectReturn DecrementSelectedRow(); + TableSelectReturn IncrementSelectedRow(); + void DoSelectPrevRow(); + void DoSelectNextRow(); + + void DoCancel(); + void DoAdvance(); + bool PreDecrement(); + void DoDecrement(); + bool PreIncrement(); + void DoIncrement(); public: CGuiTableGroup(const CGuiWidgetParms& parms, int, int, bool); @@ -47,7 +67,7 @@ public: xec_doMenuCancel = std::move(cb); } - void SetMenuSelectionChangeCallback(std::function&& cb) + void SetMenuSelectionChangeCallback(std::function&& cb) { x104_doMenuSelChange = std::move(cb); } @@ -64,7 +84,7 @@ public: } } - void SetD1(bool v) { xd1_ = v; } + void SetVertical(bool v) { xd1_vertical = v; } void SetUserSelection(int sel) { @@ -72,32 +92,10 @@ public: xc4_userSelection = sel; } - TableSelectReturn DecrementSelectedRow() - { - xc8_prevUserSelection = xc4_userSelection; - --xc4_userSelection; - if (xc4_userSelection < 0) - { - xc4_userSelection = xd0_selectWraparound ? xc0_elementCount - 1 : 0; - return xd0_selectWraparound ? TableSelectReturn::WrappedAround : TableSelectReturn::Unchanged; - } - return TableSelectReturn::Changed; - } - - TableSelectReturn IncrementSelectedRow() - { - xc8_prevUserSelection = xc4_userSelection; - ++xc4_userSelection; - if (xc4_userSelection >= xc0_elementCount) - { - xc4_userSelection = xd0_selectWraparound ? 0 : xc0_elementCount - 1; - return xd0_selectWraparound ? TableSelectReturn::WrappedAround : TableSelectReturn::Unchanged; - } - return TableSelectReturn::Changed; - } - int GetUserSelection() const { return xc4_userSelection; } + void ProcessUserInput(const CFinalInput& input); + static CGuiTableGroup* Create(CGuiFrame* frame, CInputStream& in, bool); }; diff --git a/Runtime/GuiSys/CGuiTextSupport.cpp b/Runtime/GuiSys/CGuiTextSupport.cpp index d9dba02e4..d61c8bc4d 100644 --- a/Runtime/GuiSys/CGuiTextSupport.cpp +++ b/Runtime/GuiSys/CGuiTextSupport.cpp @@ -54,6 +54,14 @@ float CGuiTextSupport::GetCurrentAnimationOverAge() const return ret; } +float CGuiTextSupport::GetNumCharsTotal() const +{ + if (CTextRenderBuffer* buf = GetCurrentPageRenderBuffer()) + if (x50_typeEnable) + return buf->GetPrimitiveCount(); + return 0.f; +} + float CGuiTextSupport::GetNumCharsPrinted() const { if (CTextRenderBuffer* buf = GetCurrentPageRenderBuffer()) diff --git a/Runtime/GuiSys/CGuiTextSupport.hpp b/Runtime/GuiSys/CGuiTextSupport.hpp index bbe60c475..874ad89c5 100644 --- a/Runtime/GuiSys/CGuiTextSupport.hpp +++ b/Runtime/GuiSys/CGuiTextSupport.hpp @@ -109,6 +109,7 @@ public: const zeus::CColor& fontCol, const zeus::CColor& outlineCol, const zeus::CColor& geomCol, s32 extX, s32 extY, CSimplePool* store); float GetCurrentAnimationOverAge() const; + float GetNumCharsTotal() const; float GetNumCharsPrinted() const; float GetTotalAnimationTime() const; bool IsAnimationDone() const; diff --git a/Runtime/GuiSys/CGuiWidget.cpp b/Runtime/GuiSys/CGuiWidget.cpp index 704a9a9e3..2c4132e55 100644 --- a/Runtime/GuiSys/CGuiWidget.cpp +++ b/Runtime/GuiSys/CGuiWidget.cpp @@ -11,7 +11,7 @@ CGuiWidget::CGuiWidget(const CGuiWidgetParms& parms) xac_drawFlags(parms.x14_drawFlags), xb0_frame(parms.x0_frame), xb6_24_pg(parms.xd_g), xb6_25_isVisible(parms.xa_defaultVisible), xb6_26_isActive(parms.xb_defaultActive), - xb6_27_(true), xb6_28_eventLock(false), + xb6_27_isSelectable(true), xb6_28_eventLock(false), xb6_29_cullFaces(parms.xc_cullFaces), xb6_30_(false), xb6_31_depthTest(true), xb7_24_depthWrite(false), xb7_25_(true) { diff --git a/Runtime/GuiSys/CGuiWidget.hpp b/Runtime/GuiSys/CGuiWidget.hpp index 3733363b9..3a10d70ab 100644 --- a/Runtime/GuiSys/CGuiWidget.hpp +++ b/Runtime/GuiSys/CGuiWidget.hpp @@ -79,7 +79,7 @@ protected: bool xb6_24_pg : 1; bool xb6_25_isVisible : 1; bool xb6_26_isActive : 1; - bool xb6_27_ : 1; + bool xb6_27_isSelectable : 1; bool xb6_28_eventLock : 1; bool xb6_29_cullFaces : 1; bool xb6_30_ : 1; @@ -116,8 +116,8 @@ public: void ReapplyXform(); void SetIsVisible(bool); void SetIsActive(bool); - - void SetB627(bool v) { xb6_27_ = v; } + bool GetIsSelectable() const { return xb6_27_isSelectable; } + void SetIsSelectable(bool v) { xb6_27_isSelectable = v; } void ParseBaseInfo(CGuiFrame* frame, CInputStream& in, const CGuiWidgetParms& parms); void AddChildWidget(CGuiWidget* widget, bool makeWorldLocal, bool atEnd); diff --git a/Runtime/MP1/CFrontEndUI.cpp b/Runtime/MP1/CFrontEndUI.cpp index dac81bf9d..67afe9f0c 100644 --- a/Runtime/MP1/CFrontEndUI.cpp +++ b/Runtime/MP1/CFrontEndUI.cpp @@ -27,8 +27,8 @@ namespace MP1 { /* Music volume constants */ -#define FE1_VOL 0.7421875f -#define FE2_VOL 0.7421875f +static const float FE1_VOL = 0.7421875f; +static const float FE2_VOL = 0.7421875f; /* L/R Stereo transition cues */ static const u16 FETransitionBackSFX[3][2] = @@ -98,22 +98,22 @@ void CFrontEndUI::SNewFileSelectFrame::FinishedLoading() proceed->TextSupport()->SetText(g_MainStringTable->GetString(85)); x40_tablegroup_popup->SetIsVisible(false); x40_tablegroup_popup->SetIsActive(false); - x40_tablegroup_popup->SetD1(false); + x40_tablegroup_popup->SetVertical(false); CGuiWidget* worker = x40_tablegroup_popup->GetWorkerWidget(2); - worker->SetB627(false); + worker->SetIsSelectable(false); worker->SetVisibility(false, ETraversalMode::Children); x20_tablegroup_fileselect->SetMenuAdvanceCallback( std::bind(&SNewFileSelectFrame::DoFileMenuAdvance, this, std::placeholders::_1)); x20_tablegroup_fileselect->SetMenuSelectionChangeCallback( - std::bind(&SNewFileSelectFrame::DoSelectionChange, this, std::placeholders::_1)); + std::bind(&SNewFileSelectFrame::DoSelectionChange, this, std::placeholders::_1, std::placeholders::_2)); x20_tablegroup_fileselect->SetMenuCancelCallback( std::bind(&SNewFileSelectFrame::DoFileMenuCancel, this, std::placeholders::_1)); x40_tablegroup_popup->SetMenuAdvanceCallback( std::bind(&SNewFileSelectFrame::DoPopupAdvance, this, std::placeholders::_1)); x40_tablegroup_popup->SetMenuSelectionChangeCallback( - std::bind(&SNewFileSelectFrame::DoSelectionChange, this, std::placeholders::_1)); + std::bind(&SNewFileSelectFrame::DoSelectionChange, this, std::placeholders::_1, std::placeholders::_2)); x40_tablegroup_popup->SetMenuCancelCallback( std::bind(&SNewFileSelectFrame::DoPopupCancel, this, std::placeholders::_1)); @@ -142,21 +142,26 @@ bool CFrontEndUI::SNewFileSelectFrame::PumpLoad() bool CFrontEndUI::SNewFileSelectFrame::IsTextDoneAnimating() const { - if (x64_fileSelections[0].x28_ != 4) + if (x64_fileSelections[0].x28_curField != 4) return false; - if (x64_fileSelections[1].x28_ != 4) + if (x64_fileSelections[1].x28_curField != 4) return false; - if (x64_fileSelections[2].x28_ != 4) + if (x64_fileSelections[2].x28_curField != 4) return false; if (!x28_textpane_erase.x0_panes[0]->GetTextSupport()->IsAnimationDone()) return false; return x38_textpane_gba.x0_panes[0]->GetTextSupport()->IsAnimationDone(); } +void CFrontEndUI::SNewFileSelectFrame::Update(float dt) +{ + +} + CFrontEndUI::SNewFileSelectFrame::EAction CFrontEndUI::SNewFileSelectFrame::ProcessUserInput(const CFinalInput& input) { - if (x8_subMenu != ESubMenu::Two) + if (x8_subMenu != ESubMenu::ExistingGamePopup) x4_saveUI->ProcessUserInput(input); if (IsTextDoneAnimating()) @@ -207,7 +212,7 @@ void CFrontEndUI::SNewFileSelectFrame::HandleActiveChange(CGuiTableGroup* active x24_model_erase->SetLocalTransform(zeus::CTransform::Translate( zeus::CVector3f{0.f, 0.f, active->GetUserSelection() * x104_rowPitch} + xf8_model_erase_position)); - if (x8_subMenu == ESubMenu::Zero || x8_subMenu == ESubMenu::Three) + if (x8_subMenu == ESubMenu::Root || x8_subMenu == ESubMenu::NewGamePopup) x24_model_erase->SetIsVisible(false); else x24_model_erase->SetIsVisible(true); @@ -234,7 +239,7 @@ void CFrontEndUI::SNewFileSelectFrame::ActivateExistingGamePopup() x40_tablegroup_popup->GetTransform()); x20_tablegroup_fileselect->SetIsActive(false); - x8_subMenu = ESubMenu::Two; + x8_subMenu = ESubMenu::ExistingGamePopup; HandleActiveChange(x40_tablegroup_popup); x48_textpane_popupadvance.SetPairText(g_MainStringTable->GetString(95)); @@ -252,7 +257,7 @@ void CFrontEndUI::SNewFileSelectFrame::DeactivateNewGamePopup() x20_tablegroup_fileselect->SetIsActive(true); CGuiWidget* worker = x40_tablegroup_popup->GetWorkerWidget(2); - worker->SetB627(false); + worker->SetIsSelectable(false); worker->SetVisibility(false, ETraversalMode::Children); x44_model_dash7->SetVisibility(false, ETraversalMode::Children); @@ -274,7 +279,7 @@ void CFrontEndUI::SNewFileSelectFrame::ActivateNewGamePopup() x40_tablegroup_popup->GetTransform()); x20_tablegroup_fileselect->SetIsActive(false); - x8_subMenu = ESubMenu::Three; + x8_subMenu = ESubMenu::NewGamePopup; HandleActiveChange(x40_tablegroup_popup); x64_fileSelections[x20_tablegroup_fileselect->GetUserSelection()]. x0_base->SetColor(zeus::CColor{1.f, 1.f, 1.f, 0.f}); @@ -287,7 +292,7 @@ void CFrontEndUI::SNewFileSelectFrame::ActivateNewGamePopup() x50_textpane_popupcancel.SetPairText(g_MainStringTable->GetString(94)); x58_textpane_popupextra.SetPairText(g_MainStringTable->GetString(101)); CGuiWidget* worker = x40_tablegroup_popup->GetWorkerWidget(2); - worker->SetB627(true); + worker->SetIsSelectable(true); worker->SetVisibility(true, ETraversalMode::Children); x44_model_dash7->SetVisibility(true, ETraversalMode::Children); } @@ -302,21 +307,50 @@ void CFrontEndUI::SNewFileSelectFrame::ActivateNewGamePopup() void CFrontEndUI::SNewFileSelectFrame::ResetFrame() { - x8_subMenu = ESubMenu::Zero; + x8_subMenu = ESubMenu::Root; - x38_textpane_gba.x0_panes[0]->SetB627(true); + x38_textpane_gba.x0_panes[0]->SetIsSelectable(true); x38_textpane_gba.x0_panes[0]->TextSupport()->SetFontColor(zeus::CColor::skWhite); - x30_textpane_cheats.x0_panes[0]->SetB627(true); + x30_textpane_cheats.x0_panes[0]->SetIsSelectable(true); x30_textpane_cheats.x0_panes[0]->TextSupport()->SetFontColor(zeus::CColor::skWhite); ClearFrameContents(); for (int i=2 ; i>=0 ; --i) - x20_tablegroup_fileselect->GetWorkerWidget(i)->SetB627(true); + x20_tablegroup_fileselect->GetWorkerWidget(i)->SetIsSelectable(true); x60_textpane_cancel->TextSupport()->SetText(""); } +void CFrontEndUI::SNewFileSelectFrame::ActivateErase() +{ + x8_subMenu = ESubMenu::EraseGame; + x28_textpane_erase.x0_panes[0]->SetIsSelectable(false); + zeus::CColor color = zeus::CColor::skGrey; + color.a = 0.5f; + x28_textpane_erase.x0_panes[0]->TextSupport()->SetFontColor(color); + x38_textpane_gba.x0_panes[0]->TextSupport()->SetFontColor(color); + x30_textpane_cheats.x0_panes[0]->TextSupport()->SetFontColor(color); + + for (int i=2 ; i>=0 ; --i) + { + SFileMenuOption& fileOpt = x64_fileSelections[i]; + const CGameState::GameFileStateInfo* data = x4_saveUI->GetGameData(i); + if (data) + { + fileOpt.x4_textpanes[0].x0_panes[0]->SetIsSelectable(true); + x20_tablegroup_fileselect->SetUserSelection(i); + } + else + { + fileOpt.x4_textpanes[0].x0_panes[0]->SetIsSelectable(false); + } + } + + x60_textpane_cancel->TextSupport()->SetText(g_MainStringTable->GetString(82)); + HandleActiveChange(x20_tablegroup_fileselect); +} + void CFrontEndUI::SNewFileSelectFrame::ClearFrameContents() { x108_curTime = 0.f; @@ -326,8 +360,8 @@ void CFrontEndUI::SNewFileSelectFrame::ClearFrameContents() if (x4_saveUI->GetGameData(i)) hasSave = true; SFileMenuOption& option = x64_fileSelections[i]; - option.x2c_ = SFileMenuOption::ComputeRandom(); - option.x28_ = -1; + option.x2c_chRate = SFileMenuOption::ComputeRandom(); + option.x28_curField = -1; for (int j=0 ; j<4 ; ++j) option.x4_textpanes[j].SetPairText(L""); } @@ -342,12 +376,12 @@ void CFrontEndUI::SNewFileSelectFrame::ClearFrameContents() if (hasSave) { - x28_textpane_erase.x0_panes[0]->SetB627(true); + x28_textpane_erase.x0_panes[0]->SetIsSelectable(true); x28_textpane_erase.x0_panes[0]->TextSupport()->SetFontColor(zeus::CColor::skWhite); } else { - x28_textpane_erase.x0_panes[0]->SetB627(false); + x28_textpane_erase.x0_panes[0]->SetIsSelectable(false); zeus::CColor color = zeus::CColor::skGrey; color.a = 0.5f; x28_textpane_erase.x0_panes[0]->TextSupport()->SetFontColor(color); @@ -357,12 +391,12 @@ void CFrontEndUI::SNewFileSelectFrame::ClearFrameContents() CGuiTextPane* cheats = static_cast(x20_tablegroup_fileselect->GetWorkerWidget(5)); if (CSlideShow::SlideShowGalleryFlags()) { - cheats->SetB627(true); + cheats->SetIsSelectable(true); x30_textpane_cheats.x0_panes[0]->TextSupport()->SetFontColor(zeus::CColor::skWhite); } else { - cheats->SetB627(false); + cheats->SetIsSelectable(false); zeus::CColor color = zeus::CColor::skGrey; color.a = 0.5f; x30_textpane_cheats.x0_panes[0]->TextSupport()->SetFontColor(color); @@ -376,36 +410,90 @@ void CFrontEndUI::SNewFileSelectFrame::SetupFrameContents() for (int i=0 ; i<3 ; ++i) { SFileMenuOption& option = x64_fileSelections[i]; - if (option.x28_ == 4) + if (option.x28_curField == 4) continue; - SGuiTextPair* pair = (option.x28_ == -1) ? nullptr : &option.x4_textpanes[option.x28_]; - if (pair) + SGuiTextPair* pair = (option.x28_curField == -1) ? nullptr : &option.x4_textpanes[option.x28_curField]; + if (!pair || + pair->x0_panes[0]->GetTextSupport()->GetNumCharsPrinted() >= + pair->x0_panes[0]->GetTextSupport()->GetNumCharsTotal()) { - //pair->x0_panes[0]->GetTextSupport()->GetNumCharsPrinted() - } + if (++option.x28_curField < 4) + { + std::wstring str; + SGuiTextPair& populatePair = option.x4_textpanes[option.x28_curField]; + const CGameState::GameFileStateInfo* data = x4_saveUI->GetGameData(i); + switch (option.x28_curField) + { + case 0: + // Completion percent + if (data) + { + std::wstring fileStr = g_MainStringTable->GetString(data->x20_hardMode ? 106 : 39); + str = fileStr + hecl::WideFormat(L" %02d%%", data->x18_itemPercent); + break; + } + str = g_MainStringTable->GetString(36); + break; + + case 1: + // World name + if (data) + { + if (g_MemoryCardSys->HasSaveWorldMemory(data->x8_mlvlId)) + { + const CSaveWorldMemory& wldMem = g_MemoryCardSys->GetSaveWorldMemory(data->x8_mlvlId); + str = wldMem.GetFrontEndName(); + } + break; + } + str = g_MainStringTable->GetString(51); + break; + + case 2: + // Formatted time + if (data) + { + auto pt = std::div(data->x0_playTime, 3600); + str = hecl::WideFormat(L"%02d:%02d", pt.quot, pt.rem / 60); + } + str = g_MainStringTable->GetString(52); + break; + + case 3: + // "Elapsed" + str = g_MainStringTable->GetString(data ? 54 : 53); + break; + + default: break; + } + + StartTextAnimating(populatePair.x0_panes[0], str, option.x2c_chRate); + StartTextAnimating(populatePair.x0_panes[1], str, option.x2c_chRate); + } + } } } void CFrontEndUI::SNewFileSelectFrame::DoPopupCancel(CGuiTableGroup* caller) { - if (x8_subMenu == ESubMenu::Two) + if (x8_subMenu == ESubMenu::ExistingGamePopup) { CSfxManager::SfxStart(1094, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); - x8_subMenu = ESubMenu::One; + x8_subMenu = ESubMenu::EraseGame; x10d_needsExistingToggle = true; } else { CSfxManager::SfxStart(1094, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); - x8_subMenu = ESubMenu::Zero; + x8_subMenu = ESubMenu::Root; x10e_needsNewToggle = true; } } void CFrontEndUI::SNewFileSelectFrame::DoPopupAdvance(CGuiTableGroup* caller) { - if (x8_subMenu == ESubMenu::Two) + if (x8_subMenu == ESubMenu::ExistingGamePopup) { if (x40_tablegroup_popup->GetUserSelection() == 1) { @@ -413,7 +501,7 @@ void CFrontEndUI::SNewFileSelectFrame::DoPopupAdvance(CGuiTableGroup* caller) ResetFrame(); } else - x8_subMenu = ESubMenu::One; + x8_subMenu = ESubMenu::EraseGame; x10d_needsExistingToggle = true; } else @@ -423,7 +511,7 @@ void CFrontEndUI::SNewFileSelectFrame::DoPopupAdvance(CGuiTableGroup* caller) if (x40_tablegroup_popup->GetUserSelection() == 1) { PlayAdvanceSfx(); - xc_action = EAction::One; + xc_action = EAction::GameOptions; return; } g_GameState->SetHardMode(x20_tablegroup_fileselect->GetUserSelection()); @@ -434,7 +522,7 @@ void CFrontEndUI::SNewFileSelectFrame::DoPopupAdvance(CGuiTableGroup* caller) if (x40_tablegroup_popup->GetUserSelection() == 1) { PlayAdvanceSfx(); - xc_action = EAction::One; + xc_action = EAction::GameOptions; return; } x4_saveUI->StartGame(x40_tablegroup_popup->GetUserSelection()); @@ -444,14 +532,14 @@ void CFrontEndUI::SNewFileSelectFrame::DoPopupAdvance(CGuiTableGroup* caller) void CFrontEndUI::SNewFileSelectFrame::DoFileMenuCancel(CGuiTableGroup* caller) { - if (x8_subMenu == ESubMenu::One) + if (x8_subMenu == ESubMenu::EraseGame) { CSfxManager::SfxStart(1094, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); ResetFrame(); } } -void CFrontEndUI::SNewFileSelectFrame::DoSelectionChange(CGuiTableGroup* caller) +void CFrontEndUI::SNewFileSelectFrame::DoSelectionChange(CGuiTableGroup* caller, int userSel) { HandleActiveChange(caller); CSfxManager::SfxStart(1093, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); @@ -459,7 +547,40 @@ void CFrontEndUI::SNewFileSelectFrame::DoSelectionChange(CGuiTableGroup* caller) void CFrontEndUI::SNewFileSelectFrame::DoFileMenuAdvance(CGuiTableGroup* caller) { - + int userSel = x20_tablegroup_fileselect->GetUserSelection(); + if (userSel < 3) + { + if (x8_subMenu == ESubMenu::EraseGame) + { + const CGameState::GameFileStateInfo* data = x4_saveUI->GetGameData(userSel); + if (data) + { + PlayAdvanceSfx(); + x10d_needsExistingToggle = true; + } + } + else + { + const CGameState::GameFileStateInfo* data = x4_saveUI->GetGameData(userSel); + if (data) + x4_saveUI->StartGame(userSel); + else + x10e_needsNewToggle = true; + } + } + else if (userSel == 3) + { + PlayAdvanceSfx(); + ActivateErase(); + } + else if (userSel == 4) + { + xc_action = EAction::FusionBonus; + } + else if (userSel == 5) + { + xc_action = EAction::SlideShow; + } } CFrontEndUI::SFileMenuOption CFrontEndUI::SNewFileSelectFrame::FindFileSelectOption(CGuiFrame* frame, int idx) @@ -479,14 +600,14 @@ void CFrontEndUI::SNewFileSelectFrame::StartTextAnimating(CGuiTextPane* text, co text->TextSupport()->SetTypeWriteEffectOptions(true, 0.1f, chRate); } -CFrontEndUI::SGBASupportFrame::SGBASupportFrame() +CFrontEndUI::SFusionBonusFrame::SFusionBonusFrame() { x4_gbaSupport = std::make_unique(); xc_gbaScreen = g_SimplePool->GetObj("FRME_GBAScreen"); x18_gbaLink = g_SimplePool->GetObj("FRME_GBALink"); } -void CFrontEndUI::SGBASupportFrame::SGBALinkFrame::SetUIText(EUIType tp) +void CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::SetUIText(EUIType tp) { int instructions = -1; int yes = -1; @@ -597,36 +718,36 @@ void CFrontEndUI::SGBASupportFrame::SGBALinkFrame::SetUIText(EUIType tp) x0_uiType = tp; } -static const CFrontEndUI::SGBASupportFrame::SGBALinkFrame::EUIType NextLinkUI[] = +static const CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::EUIType NextLinkUI[] = { - CFrontEndUI::SGBASupportFrame::SGBALinkFrame::EUIType::ConnectSocket, - CFrontEndUI::SGBASupportFrame::SGBALinkFrame::EUIType::PressStartAndSelect, - CFrontEndUI::SGBASupportFrame::SGBALinkFrame::EUIType::BeginLink, - CFrontEndUI::SGBASupportFrame::SGBALinkFrame::EUIType::Linking, - CFrontEndUI::SGBASupportFrame::SGBALinkFrame::EUIType::Empty, - CFrontEndUI::SGBASupportFrame::SGBALinkFrame::EUIType::TurnOffGBA, - CFrontEndUI::SGBASupportFrame::SGBALinkFrame::EUIType::Complete, - CFrontEndUI::SGBASupportFrame::SGBALinkFrame::EUIType::InsertPak, - CFrontEndUI::SGBASupportFrame::SGBALinkFrame::EUIType::Empty, - CFrontEndUI::SGBASupportFrame::SGBALinkFrame::EUIType::Empty + CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::EUIType::ConnectSocket, + CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::EUIType::PressStartAndSelect, + CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::EUIType::BeginLink, + CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::EUIType::Linking, + CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::EUIType::Empty, + CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::EUIType::TurnOffGBA, + CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::EUIType::Complete, + CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::EUIType::InsertPak, + CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::EUIType::Empty, + CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::EUIType::Empty }; -static const CFrontEndUI::SGBASupportFrame::SGBALinkFrame::EUIType PrevLinkUI[] = +static const CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::EUIType PrevLinkUI[] = { - CFrontEndUI::SGBASupportFrame::SGBALinkFrame::EUIType::Cancelled, - CFrontEndUI::SGBASupportFrame::SGBALinkFrame::EUIType::Cancelled, - CFrontEndUI::SGBASupportFrame::SGBALinkFrame::EUIType::Cancelled, - CFrontEndUI::SGBASupportFrame::SGBALinkFrame::EUIType::Cancelled, - CFrontEndUI::SGBASupportFrame::SGBALinkFrame::EUIType::Empty, - CFrontEndUI::SGBASupportFrame::SGBALinkFrame::EUIType::Cancelled, - CFrontEndUI::SGBASupportFrame::SGBALinkFrame::EUIType::Empty, - CFrontEndUI::SGBASupportFrame::SGBALinkFrame::EUIType::Cancelled, - CFrontEndUI::SGBASupportFrame::SGBALinkFrame::EUIType::Empty, - CFrontEndUI::SGBASupportFrame::SGBALinkFrame::EUIType::Empty + CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::EUIType::Cancelled, + CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::EUIType::Cancelled, + CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::EUIType::Cancelled, + CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::EUIType::Cancelled, + CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::EUIType::Empty, + CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::EUIType::Cancelled, + CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::EUIType::Empty, + CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::EUIType::Cancelled, + CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::EUIType::Empty, + CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::EUIType::Empty }; -CFrontEndUI::SGBASupportFrame::SGBALinkFrame::EAction -CFrontEndUI::SGBASupportFrame::SGBALinkFrame::ProcessUserInput(const CFinalInput &input, bool linkInProgress) +CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::EAction +CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::ProcessUserInput(const CFinalInput &input, bool linkInProgress) { if (linkInProgress != x40_linkInProgress) { @@ -686,13 +807,13 @@ CFrontEndUI::SGBASupportFrame::SGBALinkFrame::ProcessUserInput(const CFinalInput return EAction::None; } -void CFrontEndUI::SGBASupportFrame::SGBALinkFrame::Update(float dt) +void CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::Update(float dt) { x4_gbaSupport->Update(dt); x8_frme->Update(dt); } -void CFrontEndUI::SGBASupportFrame::SGBALinkFrame::FinishedLoading() +void CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::FinishedLoading() { xc_textpane_instructions = FindTextPanePair(x8_frme, "textpane_instructions"); x14_textpane_yes = static_cast(x8_frme->FindWidget("textpane_yes")); @@ -709,12 +830,12 @@ void CFrontEndUI::SGBASupportFrame::SGBALinkFrame::FinishedLoading() SetUIText(EUIType::InsertPak); } -void CFrontEndUI::SGBASupportFrame::SGBALinkFrame::Draw() +void CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::Draw() { x8_frme->Draw(CGuiWidgetDrawParms::Default); } -CFrontEndUI::SGBASupportFrame::SGBALinkFrame::SGBALinkFrame(CGuiFrame* linkFrame, +CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::SGBALinkFrame(CGuiFrame* linkFrame, CGBASupport* support, bool linkInProgress) : x4_gbaSupport(support), x8_frme(linkFrame), x40_linkInProgress(linkInProgress) @@ -723,7 +844,7 @@ CFrontEndUI::SGBASupportFrame::SGBALinkFrame::SGBALinkFrame(CGuiFrame* linkFrame FinishedLoading(); } -void CFrontEndUI::SGBASupportFrame::FinishedLoading() +void CFrontEndUI::SFusionBonusFrame::FinishedLoading() { x28_tablegroup_options = static_cast(x24_loadedFrame->FindWidget("tablegroup_options")); x2c_tablegroup_fusionsuit = static_cast(x24_loadedFrame->FindWidget("tablegroup_fusionsuit")); @@ -742,23 +863,23 @@ void CFrontEndUI::SGBASupportFrame::FinishedLoading() x2c_tablegroup_fusionsuit->SetIsActive(false); x2c_tablegroup_fusionsuit->SetIsVisible(false); - x2c_tablegroup_fusionsuit->SetD1(false); + x2c_tablegroup_fusionsuit->SetVertical(false); x2c_tablegroup_fusionsuit->SetUserSelection(g_GameState->SystemOptions().GetPlayerFusionSuitActive()); SetTableColors(x28_tablegroup_options); SetTableColors(x2c_tablegroup_fusionsuit); x28_tablegroup_options->SetMenuAdvanceCallback( - std::bind(&SGBASupportFrame::DoAdvance, this, std::placeholders::_1)); + std::bind(&SFusionBonusFrame::DoAdvance, this, std::placeholders::_1)); x28_tablegroup_options->SetMenuSelectionChangeCallback( - std::bind(&SGBASupportFrame::DoSelectionChange, this, std::placeholders::_1)); + std::bind(&SFusionBonusFrame::DoSelectionChange, this, std::placeholders::_1, std::placeholders::_2)); x28_tablegroup_options->SetMenuCancelCallback( - std::bind(&SGBASupportFrame::DoCancel, this, std::placeholders::_1)); + std::bind(&SFusionBonusFrame::DoCancel, this, std::placeholders::_1)); x2c_tablegroup_fusionsuit->SetMenuSelectionChangeCallback( - std::bind(&SGBASupportFrame::DoSelectionChange, this, std::placeholders::_1)); + std::bind(&SFusionBonusFrame::DoSelectionChange, this, std::placeholders::_1, std::placeholders::_2)); } -bool CFrontEndUI::SGBASupportFrame::PumpLoad() +bool CFrontEndUI::SFusionBonusFrame::PumpLoad() { if (x24_loadedFrame) return true; @@ -775,17 +896,17 @@ bool CFrontEndUI::SGBASupportFrame::PumpLoad() return true; } -void CFrontEndUI::SGBASupportFrame::SetTableColors(CGuiTableGroup* tbgp) const +void CFrontEndUI::SFusionBonusFrame::SetTableColors(CGuiTableGroup* tbgp) const { tbgp->SetColors(zeus::CColor::skWhite, zeus::CColor{0.627450f, 0.627450f, 0.627450f, 0.784313f}); } -void CFrontEndUI::SGBASupportFrame::Update(float dt, CSaveUI* saveUI) +void CFrontEndUI::SFusionBonusFrame::Update(float dt, CSaveUI* saveUI) { bool doUpdate = false; if (saveUI) - if (saveUI->GetUIType() == CSaveUI::EUIType::SaveProgress) + if (saveUI->GetUIType() == CSaveUI::EUIType::SaveReady) doUpdate = true; if (doUpdate != x38_lastDoUpdate) @@ -827,8 +948,8 @@ void CFrontEndUI::SGBASupportFrame::Update(float dt, CSaveUI* saveUI) x30_textpane_instructions.SetPairText(instructionStr); } -CFrontEndUI::SGBASupportFrame::EAction -CFrontEndUI::SGBASupportFrame::ProcessUserInput(const CFinalInput& input, CSaveUI* sui) +CFrontEndUI::SFusionBonusFrame::EAction +CFrontEndUI::SFusionBonusFrame::ProcessUserInput(const CFinalInput& input, CSaveUI* sui) { x8_action = EAction::None; @@ -860,7 +981,7 @@ CFrontEndUI::SGBASupportFrame::ProcessUserInput(const CFinalInput& input, CSaveU return x8_action; } -void CFrontEndUI::SGBASupportFrame::Draw() const +void CFrontEndUI::SFusionBonusFrame::Draw() const { if (!x38_lastDoUpdate) return; @@ -870,7 +991,7 @@ void CFrontEndUI::SGBASupportFrame::Draw() const x24_loadedFrame->Draw(CGuiWidgetDrawParms::Default); } -void CFrontEndUI::SGBASupportFrame::DoCancel(CGuiTableGroup* caller) +void CFrontEndUI::SFusionBonusFrame::DoCancel(CGuiTableGroup* caller) { if (x39_fusionNotComplete || x3a_mpNotComplete) { @@ -886,7 +1007,7 @@ void CFrontEndUI::SGBASupportFrame::DoCancel(CGuiTableGroup* caller) } } -void CFrontEndUI::SGBASupportFrame::DoSelectionChange(CGuiTableGroup* caller) +void CFrontEndUI::SFusionBonusFrame::DoSelectionChange(CGuiTableGroup* caller, int userSel) { if (caller == x28_tablegroup_options) { @@ -904,7 +1025,7 @@ void CFrontEndUI::SGBASupportFrame::DoSelectionChange(CGuiTableGroup* caller) SetTableColors(caller); } -void CFrontEndUI::SGBASupportFrame::DoAdvance(CGuiTableGroup* caller) +void CFrontEndUI::SFusionBonusFrame::DoAdvance(CGuiTableGroup* caller) { switch (x28_tablegroup_options->GetUserSelection()) { @@ -990,7 +1111,7 @@ void CFrontEndUI::SFrontEndFrame::FinishedLoading() x18_tablegroup_mainmenu->SetMenuAdvanceCallback( std::bind(&SFrontEndFrame::DoAdvance, this, std::placeholders::_1)); x18_tablegroup_mainmenu->SetMenuSelectionChangeCallback( - std::bind(&SFrontEndFrame::DoSelectionChange, this, std::placeholders::_1)); + std::bind(&SFrontEndFrame::DoSelectionChange, this, std::placeholders::_1, std::placeholders::_2)); x18_tablegroup_mainmenu->SetMenuCancelCallback( std::bind(&SFrontEndFrame::DoCancel, this, std::placeholders::_1)); } @@ -1014,10 +1135,15 @@ bool CFrontEndUI::SFrontEndFrame::PumpLoad() return false; } +void CFrontEndUI::SFrontEndFrame::Update(float dt) +{ + +} + CFrontEndUI::SFrontEndFrame::EAction CFrontEndUI::SFrontEndFrame::ProcessUserInput(const CFinalInput& input) { - x4_action = EAction::Zero; + x4_action = EAction::None; x14_loadedFrme->ProcessUserInput(input); return x4_action; } @@ -1032,7 +1158,7 @@ void CFrontEndUI::SFrontEndFrame::DoCancel(CGuiTableGroup* caller) } -void CFrontEndUI::SFrontEndFrame::DoSelectionChange(CGuiTableGroup* caller) +void CFrontEndUI::SFrontEndFrame::DoSelectionChange(CGuiTableGroup* caller, int userSel) { } @@ -1085,7 +1211,7 @@ void CFrontEndUI::SNesEmulatorFrame::SetMode(EMode mode) void CFrontEndUI::SNesEmulatorFrame::ProcessUserInput(const CFinalInput& input, CSaveUI* sui) { bool processInput = true; - if (sui && sui->GetUIType() != CSaveUI::EUIType::SaveProgress) + if (sui && sui->GetUIType() != CSaveUI::EUIType::SaveReady) processInput = false; if (sui) sui->ProcessUserInput(input); @@ -1110,7 +1236,7 @@ void CFrontEndUI::SNesEmulatorFrame::ProcessUserInput(const CFinalInput& input, bool CFrontEndUI::SNesEmulatorFrame::Update(float dt, CSaveUI* saveUi) { - bool doUpdate = (saveUi && saveUi->GetUIType() != CSaveUI::EUIType::SaveProgress) ? false : true; + bool doUpdate = (saveUi && saveUi->GetUIType() != CSaveUI::EUIType::SaveReady) ? false : true; x10_remTime = std::max(x10_remTime - dt, 0.f); zeus::CColor geomCol(zeus::CColor::skWhite); @@ -1196,7 +1322,7 @@ bool CFrontEndUI::SNesEmulatorFrame::Update(float dt, CSaveUI* saveUi) void CFrontEndUI::SNesEmulatorFrame::Draw(CSaveUI* saveUi) const { zeus::CColor mulColor = zeus::CColor::skWhite; - bool doDraw = (saveUi && saveUi->GetUIType() != CSaveUI::EUIType::SaveProgress) ? false : true; + bool doDraw = (saveUi && saveUi->GetUIType() != CSaveUI::EUIType::SaveReady) ? false : true; if (doDraw) mulColor = zeus::CColor::skBlack; @@ -1229,6 +1355,11 @@ bool CFrontEndUI::SOptionsFrontEndFrame::ProcessUserInput(const CFinalInput& inp return true; } +void CFrontEndUI::SOptionsFrontEndFrame::Update(float dt, CSaveUI* saveUi) +{ + +} + void CFrontEndUI::SOptionsFrontEndFrame::Draw() const { @@ -1251,41 +1382,9 @@ CFrontEndUI::CFrontEndUI(CArchitectureQueue& queue) ++xc0_attractCount; } -void CFrontEndUI::OnSliderSelectionChange(CGuiSliderGroup* grp, float) -{} - -void CFrontEndUI::OnCheckBoxSelectionChange(CGuiTableGroup* grp) -{} - -void CFrontEndUI::OnOptionSubMenuCancel(CGuiTableGroup* grp) -{} - -void CFrontEndUI::OnOptionsMenuCancel(CGuiTableGroup* grp) -{} - -void CFrontEndUI::OnNewGameMenuCancel(CGuiTableGroup* grp) -{} - -void CFrontEndUI::OnFileMenuCancel(CGuiTableGroup* grp) -{} - -void CFrontEndUI::OnGenericMenuSelectionChange(CGuiTableGroup* grp, int, int) -{} - -void CFrontEndUI::OnOptionsMenuAdvance(CGuiTableGroup* grp) -{} - -void CFrontEndUI::OnNewGameMenuAdvance(CGuiTableGroup* grp) -{} - -void CFrontEndUI::OnFileMenuAdvance(CGuiTableGroup* grp) -{} - -void CFrontEndUI::OnMainMenuAdvance(CGuiTableGroup* grp) -{} - void CFrontEndUI::StartSlideShow(CArchitectureQueue& queue) { + xf4_curAudio->StopMixing(); queue.Push(MakeMsg::CreateCreateIOWin(EArchMsgTarget::IOWinManager, 12, 11, new CSlideShow())); } @@ -1341,51 +1440,40 @@ void CFrontEndUI::StartAttractMovie() xcc_curMoviePtr = xc4_attractMovie.get(); } -void CFrontEndUI::UpdateMenuHighlights(CGuiTableGroup* grp) -{} - -void CFrontEndUI::CompleteStateTransition() -{} - -bool CFrontEndUI::CanBuild(const SObjectTag& tag) -{ - return false; -} - void CFrontEndUI::StartStateTransition(EScreen screen) { switch (x50_curScreen) { - case EScreen::One: - if (screen != EScreen::Three) + case EScreen::Title: + if (screen != EScreen::FileSelect) break; SetCurrentMovie(EMenuMovie::StartFileSelectA); - SetMovieSeconds(xcc_curMoviePtr->GetTotalSeconds()); + SetFadeBlackTimer(xcc_curMoviePtr->GetTotalSeconds()); break; - case EScreen::Three: - if (screen == EScreen::Five) + case EScreen::FileSelect: + if (screen == EScreen::ToPlayGame) { SetCurrentMovie(EMenuMovie::FileSelectPlayGameA); - SetMovieSeconds(xcc_curMoviePtr->GetTotalSeconds()); + SetFadeBlackTimer(xcc_curMoviePtr->GetTotalSeconds()); } - else if (screen == EScreen::Four) + else if (screen == EScreen::FusionBonus) { SetCurrentMovie(EMenuMovie::FileSelectGBA); - SetMovieSeconds(xcc_curMoviePtr->GetTotalSeconds()); + SetFadeBlackTimer(xcc_curMoviePtr->GetTotalSeconds()); CSfxManager::SfxStart(1108, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); CSfxManager::SfxStart(1109, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); } break; - case EScreen::Four: - if (screen == EScreen::Five) + case EScreen::FusionBonus: + if (screen == EScreen::ToPlayGame) { SetCurrentMovie(EMenuMovie::GBAFileSelectB); - SetMovieSeconds(xcc_curMoviePtr->GetTotalSeconds()); + SetFadeBlackTimer(xcc_curMoviePtr->GetTotalSeconds()); } - else if (screen == EScreen::Three) + else if (screen == EScreen::FileSelect) { SetCurrentMovie(EMenuMovie::GBAFileSelectA); - SetMovieSeconds(xcc_curMoviePtr->GetTotalSeconds()); + SetFadeBlackTimer(xcc_curMoviePtr->GetTotalSeconds()); CSfxManager::SfxStart(1110, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); CSfxManager::SfxStart(1111, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); } @@ -1394,61 +1482,113 @@ void CFrontEndUI::StartStateTransition(EScreen screen) switch (screen) { - case EScreen::Zero: - case EScreen::One: + case EScreen::OpenCredits: + case EScreen::Title: SetCurrentMovie(EMenuMovie::FirstStart); - SetMovieSeconds(xcc_curMoviePtr->GetTotalSeconds()); + SetFadeBlackTimer(xcc_curMoviePtr->GetTotalSeconds()); break; - case EScreen::Two: + case EScreen::AttractMovie: StartAttractMovie(); - SetMovieSecondsDeferred(); + SetFadeBlackWithMovie(); default: break; } x54_nextScreen = screen; } +void CFrontEndUI::CompleteStateTransition() +{ + EScreen oldScreen = x50_curScreen; + x50_curScreen = x54_nextScreen; + + switch (x50_curScreen) + { + case EScreen::AttractMovie: + x54_nextScreen = EScreen::OpenCredits; + x50_curScreen = EScreen::OpenCredits; + xd0_playerSkipToTitle = false; + StartStateTransition(EScreen::Title); + break; + + case EScreen::Title: + SetCurrentMovie(EMenuMovie::StartLoop); + SetFadeBlackTimer(30.f); + break; + + case EScreen::FileSelect: + SetCurrentMovie(EMenuMovie::FileSelectLoop); + if (oldScreen == EScreen::Title) + { + xf4_curAudio->StopMixing(); + xf4_curAudio = xd8_audio2.get(); + xf4_curAudio->StartMixing(); + } + if (xdc_saveUI) + xdc_saveUI->ResetCardDriver(); + break; + + case EScreen::FusionBonus: + SetCurrentMovie(EMenuMovie::GBALoop); + break; + + case EScreen::ToPlayGame: + x14_phase = EPhase::ExitFrontEnd; + break; + + default: break; + } +} + void CFrontEndUI::HandleDebugMenuReturnValue(CGameDebug::EReturnValue val, CArchitectureQueue& queue) {} void CFrontEndUI::Draw() const { - //printf("DRAW\n"); - if (x14_phase < EPhase::Four) + if (x14_phase < EPhase::DisplayFrontEnd) return; if (xec_emuFrme) + { xec_emuFrme->Draw(xdc_saveUI.get()); + } else { //g_Renderer->SetDepthReadWrite(false, false); g_Renderer->SetViewportOrtho(false, -4096.f, 4096.f); + if (xcc_curMoviePtr && xcc_curMoviePtr->GetIsFullyCached()) { + /* Render movie */ auto vidDimensions = xcc_curMoviePtr->GetVideoDimensions(); float aspectRatio = vidDimensions.first / float(vidDimensions.second); float verticalOff = (CGraphics::g_ViewportResolution.x / aspectRatio - CGraphics::g_ViewportResolution.y) * 0.5f; xcc_curMoviePtr->SetFrame(zeus::CVector3f(0.f, -verticalOff, 0.f), zeus::CVector3f(CGraphics::g_ViewportResolution.x, verticalOff, 0.f), zeus::CVector3f(0.f, CGraphics::g_ViewportResolution.y + verticalOff, 0.f), - zeus::CVector3f(CGraphics::g_ViewportResolution.x, CGraphics::g_ViewportResolution.y + verticalOff, 0.f)); + zeus::CVector3f(CGraphics::g_ViewportResolution.x, + CGraphics::g_ViewportResolution.y + verticalOff, 0.f)); xcc_curMoviePtr->DrawFrame(); } - if (x50_curScreen == EScreen::Three && x54_nextScreen == EScreen::Three) + if (x50_curScreen == EScreen::FileSelect && x54_nextScreen == EScreen::FileSelect) { + /* Render active FileSelect UI */ if (xf0_optionsFrme) xf0_optionsFrme->Draw(); - else if (xe0_newFileSel) - xe0_newFileSel->Draw(); + else if (xe0_frontendCardFrme) + xe0_frontendCardFrme->Draw(); else - xe8_frontendFrme->Draw(); + xe8_frontendNoCardFrme->Draw(); + } + else if (x50_curScreen == EScreen::FusionBonus && x54_nextScreen == EScreen::FusionBonus) + { + /* Render Fusion bonus UI */ + xe4_fusionBonusFrme->Draw(); } - else if (x50_curScreen == EScreen::Four && x54_nextScreen == EScreen::Four) - xe4_gbaSupportFrme->Draw(); if (x64_pressStartAlpha > 0.f && x38_pressStart.IsLoaded() && m_pressStartQuad) { + /* Render "Press Start" */ float nativeRatio = CGraphics::g_ViewportResolution.x / 640.f; float hOffset = x38_pressStart->GetWidth() / 2.f * nativeRatio; float vOffset = x38_pressStart->GetHeight() / 2.f * nativeRatio; @@ -1461,36 +1601,42 @@ void CFrontEndUI::Draw() const if (xc0_attractCount > 0) { - if (((x50_curScreen == EScreen::One && x54_nextScreen == EScreen::One) || - x54_nextScreen == EScreen::Two) && x58_movieSeconds < 1.f) + /* Render fade-to-black into attract movie */ + if (((x50_curScreen == EScreen::Title && x54_nextScreen == EScreen::Title) || + x54_nextScreen == EScreen::AttractMovie) && x58_fadeBlackTimer < 1.f) { + /* To black */ zeus::CColor color = zeus::CColor::skBlack; - color.a = 1.f - x58_movieSeconds; + color.a = 1.f - x58_fadeBlackTimer; const_cast(m_fadeToBlack).draw(color); } } - if (xd0_) + if (xd0_playerSkipToTitle) { - if (x54_nextScreen == EScreen::One && x50_curScreen == EScreen::Zero) + /* Render fade-through-black into title if player skips */ + if (x50_curScreen == EScreen::OpenCredits && x54_nextScreen == EScreen::Title) { + /* To black */ zeus::CColor color = zeus::CColor::skBlack; - color.a = zeus::clamp(0.f, 1.f - x58_movieSeconds, 1.f); + color.a = zeus::clamp(0.f, 1.f - x58_fadeBlackTimer, 1.f); const_cast(m_fadeToBlack).draw(color); } - else if (x54_nextScreen == EScreen::One && x50_curScreen == EScreen::One) + else if (x50_curScreen == EScreen::Title && x54_nextScreen == EScreen::Title) { + /* From black with 30-sec skip to title */ zeus::CColor color = zeus::CColor::skBlack; - color.a = 1.f - zeus::clamp(0.f, 30.f - x58_movieSeconds, 1.f); + color.a = 1.f - zeus::clamp(0.f, 30.f - x58_fadeBlackTimer, 1.f); const_cast(m_fadeToBlack).draw(color); } } if (xdc_saveUI) { - if ((IsSaveUIConditional() && !xdc_saveUI->IsDrawConditional()) || - ((x50_curScreen == EScreen::Three && x54_nextScreen == EScreen::Three) || - (x50_curScreen == EScreen::Four && x54_nextScreen == EScreen::Four))) + /* Render memory card feedback strings */ + if ((CanShowSaveUI() && !xdc_saveUI->IsHiddenFromFrontEnd()) || + ((x50_curScreen == EScreen::FileSelect && x54_nextScreen == EScreen::FileSelect) || + (x50_curScreen == EScreen::FusionBonus && x54_nextScreen == EScreen::FusionBonus))) xdc_saveUI->Draw(); } } @@ -1498,31 +1644,39 @@ void CFrontEndUI::Draw() const void CFrontEndUI::UpdateMovies(float dt) { - if (xcc_curMoviePtr && x5c_movieSecondsNeeded) + if (xcc_curMoviePtr && x5c_fadeBlackWithMovie) { - x5c_movieSecondsNeeded = false; - x58_movieSeconds = xcc_curMoviePtr->GetTotalSeconds(); + /* Set fade-to-black timer to match attract movie */ + x5c_fadeBlackWithMovie = false; + x58_fadeBlackTimer = xcc_curMoviePtr->GetTotalSeconds(); } + /* Advance playing menu movies */ for (auto& movie : x70_menuMovies) if (movie) movie->Update(dt); + /* Advance attract movie */ if (xc4_attractMovie) xc4_attractMovie->Update(dt); } void CFrontEndUI::FinishedLoadingDepsGroup() { + /* Transfer DGRP tokens into FrontEnd and lock */ const CDependencyGroup* dgrp = x20_depsGroup.GetObj(); x2c_deps.reserve(dgrp->GetObjectTagVector().size()); for (const SObjectTag& tag : dgrp->GetObjectTagVector()) + { x2c_deps.push_back(g_SimplePool->GetObj(tag)); + x2c_deps.back().Lock(); + } x44_frontendAudioGrp.Lock(); } bool CFrontEndUI::PumpLoad() { + /* Poll all tokens for load completion */ for (CToken& tok : x2c_deps) if (!tok.IsLoaded()) return false; @@ -1537,6 +1691,7 @@ bool CFrontEndUI::PumpLoad() bool CFrontEndUI::PumpMovieLoad() { + /* Prepare all FrontEnd movies and pause each */ if (xd1_moviesLoaded) return true; for (int i=0 ; i<9 ; ++i) @@ -1555,76 +1710,84 @@ bool CFrontEndUI::PumpMovieLoad() void CFrontEndUI::ProcessUserInput(const CFinalInput& input, CArchitectureQueue& queue) { - if (static_cast(g_Main)->GetBardBusy()) + if (static_cast(g_Main)->GetCardBusy()) return; if (input.ControllerIdx() > 1) return; if (xec_emuFrme) { + /* NES emulator pre-empts user input if active */ xec_emuFrme->ProcessUserInput(input, xdc_saveUI.get()); return; } - if (x14_phase != EPhase::Four || input.ControllerIdx() != 0) + /* Controllers other than first shall not pass */ + if (x14_phase != EPhase::DisplayFrontEnd || input.ControllerIdx() != 0) return; if (x50_curScreen != x54_nextScreen) { - if (x54_nextScreen == EScreen::Two && (input.PStart() || input.PA())) + if (x54_nextScreen == EScreen::AttractMovie && (input.PStart() || input.PA())) { - SetMovieSeconds(std::min(1.f, x58_movieSeconds)); + /* Player wants to return to opening credits from attract movie */ + SetFadeBlackTimer(std::min(1.f, x58_fadeBlackTimer)); PlayAdvanceSfx(); return; } if (input.PA() || input.PStart()) { - if (x50_curScreen == EScreen::Zero && x54_nextScreen == EScreen::One && - x58_movieSeconds > 1.f) + if (x50_curScreen == EScreen::OpenCredits && x54_nextScreen == EScreen::Title && + x58_fadeBlackTimer > 1.f) { - xd0_ = true; - SetMovieSeconds(1.f); + /* Player is too impatient to view opening credits */ + xd0_playerSkipToTitle = true; + SetFadeBlackTimer(1.f); return; } } } else { - if (x50_curScreen == EScreen::One) + if (x50_curScreen == EScreen::Title) { if (input.PStart() || input.PA()) { - if (x58_movieSeconds < 30.f - g_tweakGame->GetPressStartDelay()) + if (x58_fadeBlackTimer < 30.f - g_tweakGame->GetPressStartDelay()) { + /* Proceed to file select UI */ CSfxManager::SfxStart(FETransitionBackSFX[x18_rndA][0], 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); CSfxManager::SfxStart(FETransitionBackSFX[x18_rndA][1], 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); - StartStateTransition(EScreen::Three); + StartStateTransition(EScreen::FileSelect); return; } } } - else if (x50_curScreen == EScreen::Three && x54_nextScreen == EScreen::Three) + else if (x50_curScreen == EScreen::FileSelect && x54_nextScreen == EScreen::FileSelect) { if (xf0_optionsFrme) { + /* Control options UI */ if (xf0_optionsFrme->ProcessUserInput(input, xdc_saveUI.get())) return; + /* Exit options UI */ xf0_optionsFrme.reset(); return; } - else if (xe0_newFileSel) + else if (xe0_frontendCardFrme) { - switch (xe0_newFileSel->ProcessUserInput(input)) + /* Control FrontEnd with memory card */ + switch (xe0_frontendCardFrme->ProcessUserInput(input)) { - case SNewFileSelectFrame::EAction::Two: - StartStateTransition(EScreen::Four); + case SNewFileSelectFrame::EAction::FusionBonus: + StartStateTransition(EScreen::FusionBonus); return; - case SNewFileSelectFrame::EAction::One: + case SNewFileSelectFrame::EAction::GameOptions: xf0_optionsFrme = std::make_unique(); return; - case SNewFileSelectFrame::EAction::Three: - xd2_ = true; + case SNewFileSelectFrame::EAction::SlideShow: + xd2_deferSlideShow = true; StartSlideShow(queue); return; default: return; @@ -1632,33 +1795,35 @@ void CFrontEndUI::ProcessUserInput(const CFinalInput& input, CArchitectureQueue& } else { - switch (xe8_frontendFrme->ProcessUserInput(input)) + /* Control FrontEnd without memory card */ + switch (xe8_frontendNoCardFrme->ProcessUserInput(input)) { - case SFrontEndFrame::EAction::Two: - StartStateTransition(EScreen::Four); + case SFrontEndFrame::EAction::FusionBonus: + StartStateTransition(EScreen::FusionBonus); return; - case SFrontEndFrame::EAction::Three: + case SFrontEndFrame::EAction::GameOptions: xf0_optionsFrme = std::make_unique(); return; - case SFrontEndFrame::EAction::One: - TransitionToFive(); + case SFrontEndFrame::EAction::StartGame: + TransitionToGame(); return; - case SFrontEndFrame::EAction::Four: - xd2_ = true; + case SFrontEndFrame::EAction::SlideShow: + xd2_deferSlideShow = true; StartSlideShow(queue); return; default: return; } } } - else if (x50_curScreen == EScreen::Four && x54_nextScreen == EScreen::Four) + else if (x50_curScreen == EScreen::FusionBonus && x54_nextScreen == EScreen::FusionBonus) { - switch (xe4_gbaSupportFrme->ProcessUserInput(input, xdc_saveUI.get())) + /* Control Fusion bonus UI */ + switch (xe4_fusionBonusFrme->ProcessUserInput(input, xdc_saveUI.get())) { - case SGBASupportFrame::EAction::GoBack: - StartStateTransition(EScreen::Three); + case SFusionBonusFrame::EAction::GoBack: + StartStateTransition(EScreen::FileSelect); return; - case SGBASupportFrame::EAction::PlayNESMetroid: + case SFusionBonusFrame::EAction::PlayNESMetroid: xf4_curAudio->StopMixing(); xec_emuFrme = std::make_unique(); if (xdc_saveUI) @@ -1670,17 +1835,17 @@ void CFrontEndUI::ProcessUserInput(const CFinalInput& input, CArchitectureQueue& } } -void CFrontEndUI::TransitionToFive() +void CFrontEndUI::TransitionToGame() { - if (x14_phase >= EPhase::Five) + if (x14_phase >= EPhase::ToPlayGame) return; const u16* sfx = FETransitionForwardSFX[x1c_rndB]; CSfxManager::SfxStart(sfx[0], 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); CSfxManager::SfxStart(sfx[1], 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); - x14_phase = EPhase::Five; - StartStateTransition(EScreen::Five); + x14_phase = EPhase::ToPlayGame; + StartStateTransition(EScreen::ToPlayGame); } void CFrontEndUI::UpdateMusicVolume() @@ -1693,63 +1858,81 @@ void CFrontEndUI::UpdateMusicVolume() } } +static const float AudioFadeTimeA[] = +{ + 0.44f, 5.41f, 3.41f +}; + +static const float AudioFadeTimeB[] = +{ + 4.2f, 6.1f, 6.1f +}; + CIOWin::EMessageReturn CFrontEndUI::Update(float dt, CArchitectureQueue& queue) { - if (xdc_saveUI && x50_curScreen >= EScreen::Three) + if (xdc_saveUI && x50_curScreen >= EScreen::FileSelect) { switch (xdc_saveUI->Update(dt)) { case EMessageReturn::Exit: - TransitionToFive(); + /* Memory card operation complete, transition to game */ + TransitionToGame(); break; case EMessageReturn::RemoveIOWinAndExit: case EMessageReturn::RemoveIOWin: - xe0_newFileSel.reset(); + /* No memory card available, fallback to non-save UI */ + xe0_frontendCardFrme.reset(); xdc_saveUI.reset(); default: break; } } + /* Set music fade volume */ UpdateMusicVolume(); switch (x14_phase) { - case EPhase::Zero: + case EPhase::LoadDepsGroup: + /* Poll DGRP load */ if (!x20_depsGroup.IsLoaded()) return EMessageReturn::Exit; FinishedLoadingDepsGroup(); x20_depsGroup.Unlock(); - x14_phase = EPhase::One; + x14_phase = EPhase::LoadDeps; - case EPhase::One: + case EPhase::LoadDeps: + /* Poll loading DGRP resources */ if (PumpLoad()) { - xe0_newFileSel = std::make_unique(xdc_saveUI.get(), x1c_rndB); - xe4_gbaSupportFrme = std::make_unique(); - xe8_frontendFrme = std::make_unique(x1c_rndB); + xe0_frontendCardFrme = std::make_unique(xdc_saveUI.get(), x1c_rndB); + xe4_fusionBonusFrme = std::make_unique(); + xe8_frontendNoCardFrme = std::make_unique(x1c_rndB); x38_pressStart.GetObj(); CAudioSys::AddAudioGroup(x44_frontendAudioGrp->GetAudioGroupData()); xd4_audio1 = std::make_unique("Audio/frontend_1.rsf", 416480, 1973664); xd8_audio2 = std::make_unique("Audio/frontend_2.rsf", 273556, 1636980); - x14_phase = EPhase::Two; + x14_phase = EPhase::LoadFrames; } - if (x14_phase == EPhase::One) + if (x14_phase == EPhase::LoadDeps) return EMessageReturn::Exit; - case EPhase::Two: + case EPhase::LoadFrames: + /* Poll loading music and FRME resources */ if (!xd4_audio1->IsReady() || !xd8_audio2->IsReady() || - !xe0_newFileSel->PumpLoad() || !xe4_gbaSupportFrme->PumpLoad() || - !xe8_frontendFrme->PumpLoad() || !xdc_saveUI->PumpLoad()) + !xe0_frontendCardFrme->PumpLoad() || !xe4_fusionBonusFrme->PumpLoad() || + !xe8_frontendNoCardFrme->PumpLoad() || !xdc_saveUI->PumpLoad()) return EMessageReturn::Exit; xf4_curAudio = xd4_audio1.get(); xf4_curAudio->StartMixing(); - x14_phase = EPhase::Three; + x14_phase = EPhase::LoadMovies; - case EPhase::Three: + case EPhase::LoadMovies: { + /* Poll loading movies */ bool moviesReady = true; if (PumpMovieLoad()) { + /* Prime first frame of movies */ UpdateMovies(dt); for (int i=0 ; i<9 ; ++i) { @@ -1765,24 +1948,158 @@ CIOWin::EMessageReturn CFrontEndUI::Update(float dt, CArchitectureQueue& queue) if (moviesReady) { - x14_phase = EPhase::Four; - StartStateTransition(EScreen::One); + /* Ready to display FrontEnd */ + x14_phase = EPhase::DisplayFrontEnd; + StartStateTransition(EScreen::Title); } else return EMessageReturn::Exit; } - case EPhase::Four: - case EPhase::Five: + case EPhase::DisplayFrontEnd: + case EPhase::ToPlayGame: + /* Displaying frontend to user */ if (xec_emuFrme) { + /* Update just the emulator if active */ if (xec_emuFrme->Update(dt, xdc_saveUI.get())) { + /* Exit emulator */ xec_emuFrme.reset(); + if (xdc_saveUI) + xdc_saveUI->SetInGame(false); xf4_curAudio->StartMixing(); } break; } + + if (xd2_deferSlideShow) + { + /* Start mixing slideshow music */ + xd2_deferSlideShow = false; + xf4_curAudio->StartMixing(); + if (xdc_saveUI) + xdc_saveUI->ResetCardDriver(); + } + + if (x50_curScreen == EScreen::FileSelect && x54_nextScreen == EScreen::FileSelect) + { + /* Main FrontEnd UI tree active */ + if (xf0_optionsFrme) + { + bool optionsActive = true; + if (xdc_saveUI && xdc_saveUI->GetUIType() != CSaveUI::EUIType::SaveReady) + optionsActive = false; + + if (optionsActive) + { + /* Update options UI */ + xf0_optionsFrme->Update(dt, xdc_saveUI.get()); + } + else + { + /* Save triggered; exit options UI here */ + xf0_optionsFrme.reset(); + } + } + else if (xe0_frontendCardFrme) + { + /* Update FrontEnd with memory card UI */ + xe0_frontendCardFrme->Update(dt); + } + else + { + /* Update FrontEnd without memory card UI */ + xe8_frontendNoCardFrme->Update(dt); + } + } + else if (x50_curScreen == EScreen::FusionBonus && x54_nextScreen == EScreen::FusionBonus) + { + /* Update Fusion bonus UI */ + xe4_fusionBonusFrme->Update(dt, xdc_saveUI.get()); + } + + if (x50_curScreen != x54_nextScreen && xcc_curMoviePtr && + (xcc_curMoviePtr->GetIsMovieFinishedPlaying() || xcc_curMoviePtr->IsLooping())) + { + /* Movie-based transition complete */ + CompleteStateTransition(); + } + + if (x58_fadeBlackTimer > 0.f && !x5c_fadeBlackWithMovie) + { + SetFadeBlackTimer(std::max(0.f, x58_fadeBlackTimer - dt)); + if (x58_fadeBlackTimer == 0.f) + { + if (x50_curScreen == EScreen::Title && x54_nextScreen == EScreen::Title) + { + if (xc0_attractCount > 0) + { + /* Screen black, start attract movie */ + StartStateTransition(EScreen::AttractMovie); + } + } + else if (x54_nextScreen == EScreen::AttractMovie) + { + /* Attract movie done, play open credits again */ + CompleteStateTransition(); + } + else if (x50_curScreen != x54_nextScreen) + { + /* Fade-based transition complete */ + CompleteStateTransition(); + } + } + } + + /* Advance active movies */ + UpdateMovies(dt); + + if (x50_curScreen == EScreen::Title && x54_nextScreen == EScreen::Title) + { + /* Update press-start pulsing */ + if (x58_fadeBlackTimer < 30.f - g_tweakGame->GetPressStartDelay()) + { + x60_pressStartTime = std::fmod(x60_pressStartTime + dt, 1.f); + if (x60_pressStartTime < 0.5f) + x64_pressStartAlpha = x60_pressStartTime / 0.5f; + else + x64_pressStartAlpha = (1.f - x60_pressStartTime) / 0.5f; + } + } + else + { + /* Clear press-start pulsing */ + x60_pressStartTime = 0.f; + x64_pressStartAlpha = 0.f; + } + + if (x50_curScreen == EScreen::Title && x54_nextScreen == EScreen::FileSelect) + { + /* Fade out title music */ + x68_musicVol = 1.f - zeus::clamp(0.f, (xcc_curMoviePtr->GetPlayedSeconds() - + AudioFadeTimeA[x18_rndA]) / 2.5f, 1.f); + } + else if (x54_nextScreen == EScreen::ToPlayGame) + { + /* Fade out menu music */ + float delay = AudioFadeTimeB[x1c_rndB]; + x68_musicVol = 1.f - zeus::clamp(0.f, (xcc_curMoviePtr->GetPlayedSeconds() - delay) / + (xcc_curMoviePtr->GetTotalSeconds() - delay), 1.f); + } + else + { + /* Full music volume */ + x68_musicVol = 1.f; + } + + return EMessageReturn::Exit; + + case EPhase::ExitFrontEnd: + /* Remove FrontEnd IOWin and begin updating next IOWin */ + return EMessageReturn::RemoveIOWin; + + default: break; } return EMessageReturn::Exit; @@ -1794,18 +2111,21 @@ CIOWin::EMessageReturn CFrontEndUI::OnMessage(const CArchitectureMessage& msg, C { case EArchMsgType::UserInput: { + /* Forward user events */ const CArchMsgParmUserInput& input = MakeMsg::GetParmUserInput(msg); ProcessUserInput(input.x4_parm, queue); break; } case EArchMsgType::TimerTick: { + /* Forward frame events */ float dt = MakeMsg::GetParmTimerTick(msg).x4_parm; return Update(dt, queue); } case EArchMsgType::QuitGameplay: { - x14_phase = EPhase::Six; + /* Immediately exit FrontEnd */ + x14_phase = EPhase::ExitFrontEnd; break; } default: break; @@ -1813,11 +2133,5 @@ CIOWin::EMessageReturn CFrontEndUI::OnMessage(const CArchitectureMessage& msg, C return EMessageReturn::Normal; } -void CFrontEndUI::StartGame() -{} - -void CFrontEndUI::InitializeFrame() -{} - } } diff --git a/Runtime/MP1/CFrontEndUI.hpp b/Runtime/MP1/CFrontEndUI.hpp index 3bd407571..a3d39ba9b 100644 --- a/Runtime/MP1/CFrontEndUI.hpp +++ b/Runtime/MP1/CFrontEndUI.hpp @@ -41,23 +41,22 @@ class CFrontEndUI : public CIOWin public: enum class EPhase { - Zero, - One, - Two, - Three, - Four, - Five, - Six + LoadDepsGroup, + LoadDeps, + LoadFrames, + LoadMovies, + DisplayFrontEnd, + ToPlayGame, + ExitFrontEnd }; enum class EScreen { - Zero, - One, - Two, - Three, - Four, - Five, - Six + OpenCredits, + Title, + AttractMovie, + FileSelect, + FusionBonus, + ToPlayGame }; enum class EMenuMovie { @@ -90,8 +89,8 @@ public: /* filename, world, playtime, date */ SGuiTextPair x4_textpanes[4]; - u32 x28_ = 0; - float x2c_ = ComputeRandom(); + u32 x28_curField = 0; + float x2c_chRate = ComputeRandom(); static float ComputeRandom() { @@ -103,24 +102,24 @@ public: { enum class ESubMenu { - Zero, - One, - Two, - Three + Root, + EraseGame, + ExistingGamePopup, + NewGamePopup }; enum class EAction { - Zero, - One, - Two, - Three + None, + GameOptions, + FusionBonus, + SlideShow }; u32 x0_rnd; CSaveUI* x4_saveUI; - ESubMenu x8_subMenu = ESubMenu::Zero; - EAction xc_action = EAction::Zero; + ESubMenu x8_subMenu = ESubMenu::Root; + EAction xc_action = EAction::None; TLockedToken x10_frme; CGuiFrame* x1c_loadedFrame = nullptr; CGuiTableGroup* x20_tablegroup_fileselect = nullptr; @@ -146,6 +145,7 @@ public: void FinishedLoading(); bool PumpLoad(); bool IsTextDoneAnimating() const; + void Update(float dt); EAction ProcessUserInput(const CFinalInput& input); void Draw() const; @@ -156,20 +156,21 @@ public: void ActivateNewGamePopup(); void ResetFrame(); + void ActivateErase(); void ClearFrameContents(); void SetupFrameContents(); void DoPopupCancel(CGuiTableGroup* caller); void DoPopupAdvance(CGuiTableGroup* caller); void DoFileMenuCancel(CGuiTableGroup* caller); - void DoSelectionChange(CGuiTableGroup* caller); + void DoSelectionChange(CGuiTableGroup* caller, int userSel); void DoFileMenuAdvance(CGuiTableGroup* caller); static SFileMenuOption FindFileSelectOption(CGuiFrame* frame, int idx); static void StartTextAnimating(CGuiTextPane* text, const std::wstring& str, float chRate); }; - struct SGBASupportFrame + struct SFusionBonusFrame { struct SGBALinkFrame { @@ -240,7 +241,7 @@ public: bool x39_fusionNotComplete = false; bool x3a_mpNotComplete = false; - SGBASupportFrame(); + SFusionBonusFrame(); void FinishedLoading(); bool PumpLoad(); void SetTableColors(CGuiTableGroup* tbgp) const; @@ -255,7 +256,7 @@ public: } void DoCancel(CGuiTableGroup* caller); - void DoSelectionChange(CGuiTableGroup* caller); + void DoSelectionChange(CGuiTableGroup* caller, int userSel); void DoAdvance(CGuiTableGroup* caller); }; @@ -263,11 +264,11 @@ public: { enum class EAction { - Zero, - One, - Two, - Three, - Four + None, + StartGame, + FusionBonus, + GameOptions, + SlideShow }; u32 x0_rnd; @@ -280,11 +281,12 @@ public: SFrontEndFrame(u32 rnd); void FinishedLoading(); bool PumpLoad(); + void Update(float dt); EAction ProcessUserInput(const CFinalInput& input); void Draw() const; void DoCancel(CGuiTableGroup* caller); - void DoSelectionChange(CGuiTableGroup* caller); + void DoSelectionChange(CGuiTableGroup* caller, int userSel); void DoAdvance(CGuiTableGroup* caller); }; @@ -339,31 +341,32 @@ public: }; SOptionsFrontEndFrame(); bool ProcessUserInput(const CFinalInput& input, CSaveUI* sui); + void Update(float dt, CSaveUI* saveUi); void Draw() const; }; - bool IsSaveUIConditional() const + bool CanShowSaveUI() const { - if (x50_curScreen != EScreen::Three && x50_curScreen != EScreen::Four) + if (x50_curScreen != EScreen::FileSelect && x50_curScreen != EScreen::FusionBonus) return false; - if (x54_nextScreen != EScreen::Three && x54_nextScreen != EScreen::Four) + if (x54_nextScreen != EScreen::FileSelect && x54_nextScreen != EScreen::FusionBonus) return false; return true; } private: - EPhase x14_phase = EPhase::Zero; + EPhase x14_phase = EPhase::LoadDepsGroup; u32 x18_rndA; u32 x1c_rndB; TLockedToken x20_depsGroup; std::vector x2c_deps; TLockedToken x38_pressStart; TLockedToken x44_frontendAudioGrp; - EScreen x50_curScreen = EScreen::Zero; - EScreen x54_nextScreen = EScreen::Zero; - float x58_movieSeconds = 0.f; - bool x5c_movieSecondsNeeded = false; - float x60_ = 0.f; + EScreen x50_curScreen = EScreen::OpenCredits; + EScreen x54_nextScreen = EScreen::OpenCredits; + float x58_fadeBlackTimer = 0.f; + bool x5c_fadeBlackWithMovie = false; + float x60_pressStartTime = 0.f; float x64_pressStartAlpha = 0.f; float x68_musicVol = 1.f; u32 x6c_; @@ -373,15 +376,15 @@ private: int xc0_attractCount = 0; std::unique_ptr xc4_attractMovie; CMoviePlayer* xcc_curMoviePtr = nullptr; - bool xd0_ = false; + bool xd0_playerSkipToTitle = false; bool xd1_moviesLoaded = false; - bool xd2_ = false; + bool xd2_deferSlideShow = false; std::unique_ptr xd4_audio1; std::unique_ptr xd8_audio2; std::unique_ptr xdc_saveUI; - std::unique_ptr xe0_newFileSel; - std::unique_ptr xe4_gbaSupportFrme; - std::unique_ptr xe8_frontendFrme; + std::unique_ptr xe0_frontendCardFrme; + std::unique_ptr xe4_fusionBonusFrme; + std::unique_ptr xe8_frontendNoCardFrme; std::unique_ptr xec_emuFrme; std::unique_ptr xf0_optionsFrme; CStaticAudioPlayer* xf4_curAudio = nullptr; @@ -389,46 +392,33 @@ private: CColoredQuadFilter m_fadeToBlack = {CCameraFilterPass::EFilterType::Blend}; std::experimental::optional m_pressStartQuad; - void SetMovieSecondsDeferred() + void SetFadeBlackWithMovie() { - x58_movieSeconds = 1000000.f; - x5c_movieSecondsNeeded = true; + x58_fadeBlackTimer = 1000000.f; + x5c_fadeBlackWithMovie = true; } - void SetMovieSeconds(float seconds) + void SetFadeBlackTimer(float seconds) { - x58_movieSeconds = seconds; - x5c_movieSecondsNeeded = false; + x58_fadeBlackTimer = seconds; + x5c_fadeBlackWithMovie = false; } - void TransitionToFive(); + void TransitionToGame(); void UpdateMusicVolume(); void FinishedLoadingDepsGroup(); bool PumpLoad(); public: CFrontEndUI(CArchitectureQueue& queue); - void OnSliderSelectionChange(CGuiSliderGroup* grp, float); - void OnCheckBoxSelectionChange(CGuiTableGroup* grp); - void OnOptionSubMenuCancel(CGuiTableGroup* grp); - void OnOptionsMenuCancel(CGuiTableGroup* grp); - void OnNewGameMenuCancel(CGuiTableGroup* grp); - void OnFileMenuCancel(CGuiTableGroup* grp); - void OnGenericMenuSelectionChange(CGuiTableGroup* grp, int, int); - void OnOptionsMenuAdvance(CGuiTableGroup* grp); - void OnNewGameMenuAdvance(CGuiTableGroup* grp); - void OnFileMenuAdvance(CGuiTableGroup* grp); - void OnMainMenuAdvance(CGuiTableGroup* grp); void StartSlideShow(CArchitectureQueue& queue); std::string GetAttractMovieFileName(int idx); std::string GetNextAttractMovieFileName(); void SetCurrentMovie(EMenuMovie movie); void StopAttractMovie(); void StartAttractMovie(); - void UpdateMenuHighlights(CGuiTableGroup* grp); - void CompleteStateTransition(); - bool CanBuild(const SObjectTag& tag); void StartStateTransition(EScreen screen); + void CompleteStateTransition(); void HandleDebugMenuReturnValue(CGameDebug::EReturnValue val, CArchitectureQueue& queue); void Draw() const; void UpdateMovies(float dt); @@ -436,8 +426,6 @@ public: void ProcessUserInput(const CFinalInput& input, CArchitectureQueue& queue); EMessageReturn Update(float dt, CArchitectureQueue& queue); EMessageReturn OnMessage(const CArchitectureMessage& msg, CArchitectureQueue& queue); - void StartGame(); - void InitializeFrame(); }; } diff --git a/Runtime/MP1/CQuitScreen.cpp b/Runtime/MP1/CQuitScreen.cpp index 52a9b7c96..25f296e05 100644 --- a/Runtime/MP1/CQuitScreen.cpp +++ b/Runtime/MP1/CQuitScreen.cpp @@ -44,7 +44,7 @@ void CQuitScreen::FinishedLoading() x14_tablegroup_quitgame->SetMenuAdvanceCallback( std::bind(&CQuitScreen::DoAdvance, this, std::placeholders::_1)); x14_tablegroup_quitgame->SetMenuSelectionChangeCallback( - std::bind(&CQuitScreen::DoSelectionChange, this, std::placeholders::_1)); + std::bind(&CQuitScreen::DoSelectionChange, this, std::placeholders::_1, std::placeholders::_2)); static_cast(x10_loadedFrame->FindWidget("textpane_title"))->TextSupport()-> SetText(g_MainStringTable->GetString(Titles[int(x0_type)])); @@ -58,7 +58,7 @@ void CQuitScreen::FinishedLoading() SetColors(); } -void CQuitScreen::DoSelectionChange(CGuiTableGroup* caller) +void CQuitScreen::DoSelectionChange(CGuiTableGroup* caller, int userSel) { SetColors(); CSfxManager::SfxStart(1424, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); diff --git a/Runtime/MP1/CQuitScreen.hpp b/Runtime/MP1/CQuitScreen.hpp index d5c6b929d..879679b74 100644 --- a/Runtime/MP1/CQuitScreen.hpp +++ b/Runtime/MP1/CQuitScreen.hpp @@ -42,7 +42,7 @@ class CQuitScreen void SetColors(); public: void FinishedLoading(); - void DoSelectionChange(CGuiTableGroup* caller); + void DoSelectionChange(CGuiTableGroup* caller, int userSel); void DoAdvance(CGuiTableGroup* caller); EQuitAction Update(float dt); void Draw(); diff --git a/Runtime/MP1/CSaveUI.cpp b/Runtime/MP1/CSaveUI.cpp index 3888ebdac..4d81d9868 100644 --- a/Runtime/MP1/CSaveUI.cpp +++ b/Runtime/MP1/CSaveUI.cpp @@ -125,7 +125,7 @@ bool CSaveUI::PumpLoad() x58_tablegroup_choices->SetMenuAdvanceCallback( std::bind(&CSaveUI::DoAdvance, this, std::placeholders::_1)); x58_tablegroup_choices->SetMenuSelectionChangeCallback( - std::bind(&CSaveUI::DoSelectionChange, this, std::placeholders::_1)); + std::bind(&CSaveUI::DoSelectionChange, this, std::placeholders::_1, std::placeholders::_2)); if (x0_saveCtx == ESaveContext::InGame) x6c_cardDriver->StartCardProbe(); @@ -160,7 +160,7 @@ CSaveUI::EUIType CSaveUI::SelectUIType() const { if (x6c_cardDriver->x14_error == CMemoryCardDriver::EError::CardStillFull) return EUIType::StillInsufficientSpace; - return EUIType::SaveProgress; + return EUIType::SaveReady; } if (x6c_cardDriver->x14_error == CMemoryCardDriver::EError::CardBroken) @@ -293,7 +293,7 @@ void CSaveUI::SetUIText() opt0 = 16; // Continue opt1 = 21; // Cancel break; - case EUIType::SaveProgress: + case EUIType::SaveReady: if (x0_saveCtx == ESaveContext::InGame) { msgB = 8; // Save progress? @@ -330,10 +330,10 @@ void CSaveUI::SetUIText() std::wstring opt3Str; x68_textpane_choice3->TextSupport()->SetText(opt3Str); - x5c_textpane_choice0->SetB627(opt0 != -1); - x60_textpane_choice1->SetB627(opt1 != -1); - x64_textpane_choice2->SetB627(opt2 != -1); - x68_textpane_choice3->SetB627(false); + x5c_textpane_choice0->SetIsSelectable(opt0 != -1); + x60_textpane_choice1->SetIsSelectable(opt1 != -1); + x64_textpane_choice2->SetIsSelectable(opt2 != -1); + x68_textpane_choice3->SetIsSelectable(false); x58_tablegroup_choices->SetIsActive(opt0 != -1 || opt1 != -1 || opt2 != -1); SetUIColors(); @@ -567,7 +567,7 @@ void CSaveUI::DoAdvance(CGuiTableGroup* caller) } break; - case EUIType::SaveProgress: + case EUIType::SaveReady: if (x0_saveCtx == ESaveContext::InGame) { if (userSel == 0) @@ -592,7 +592,7 @@ void CSaveUI::DoAdvance(CGuiTableGroup* caller) CSfxManager::SfxStart(sfx, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); } -void CSaveUI::DoSelectionChange(CGuiTableGroup* caller) +void CSaveUI::DoSelectionChange(CGuiTableGroup* caller, int userSel) { SetUIColors(); CSfxManager::SfxStart(x88_navMoveSfx, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); diff --git a/Runtime/MP1/CSaveUI.hpp b/Runtime/MP1/CSaveUI.hpp index bad39a10f..795e44b28 100644 --- a/Runtime/MP1/CSaveUI.hpp +++ b/Runtime/MP1/CSaveUI.hpp @@ -46,14 +46,14 @@ public: ProgressWillBeLost = 13, NotOriginalCard = 14, AllDataWillBeLost = 15, - SaveProgress = 16 + SaveReady = 16 }; - bool IsDrawConditional() + bool IsHiddenFromFrontEnd() { switch (x10_uiType) { - case EUIType::SaveProgress: + case EUIType::SaveReady: case EUIType::Empty: case EUIType::BusyReading: case EUIType::BusyWriting: @@ -90,11 +90,11 @@ private: bool x92_savingDisabled = false; bool x93_inGame; - void ResetCardDriver(); void ContinueWithoutSaving(); public: static std::unique_ptr ConstructCardDriver(bool inGame); + void ResetCardDriver(); CIOWin::EMessageReturn Update(float dt); void SetInGame(bool v) { x93_inGame = v; } bool PumpLoad(); @@ -104,7 +104,7 @@ public: void Draw() const; void DoAdvance(CGuiTableGroup* caller); - void DoSelectionChange(CGuiTableGroup* caller); + void DoSelectionChange(CGuiTableGroup* caller, int userSel); void ProcessUserInput(const CFinalInput& input); void StartGame(int idx); diff --git a/Runtime/MP1/MP1.hpp b/Runtime/MP1/MP1.hpp index feb9fb0a0..61739c35b 100644 --- a/Runtime/MP1/MP1.hpp +++ b/Runtime/MP1/MP1.hpp @@ -261,7 +261,7 @@ public: EGameplayResult GetGameplayResult() const { return xe4_gameplayResult; } void SetGameplayResult(EGameplayResult wl) { xe4_gameplayResult = wl; } void SetManageCard(bool v) { x160_28_manageCard = v; } - bool GetBardBusy() const { return x160_31_cardBusy; } + bool GetCardBusy() const { return x160_31_cardBusy; } void SetCardBusy(bool v) { x160_31_cardBusy = v; } EFlowState GetFlowState() const { return x12c_flowState; }