mirror of https://github.com/AxioDL/metaforce.git
CFrontEndUI: Use std::array where applicable
Makes the array types strongly-typed and also allows us to eliminate a few magic values within the code.
This commit is contained in:
parent
b6ea391755
commit
86218421f5
|
@ -1,5 +1,7 @@
|
|||
#include "Runtime/MP1/CFrontEndUI.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <ctime>
|
||||
|
||||
#include "NESEmulator/CNESEmulator.hpp"
|
||||
|
@ -36,24 +38,24 @@ constexpr float FE1_VOL = 0.7421875f;
|
|||
constexpr float FE2_VOL = 0.7421875f;
|
||||
|
||||
/* L/R Stereo transition cues */
|
||||
constexpr u16 FETransitionBackSFX[3][2] = {
|
||||
constexpr std::array<std::array<u16, 2>, 3> FETransitionBackSFX{{
|
||||
{SFXfnt_transfore_00L, SFXfnt_transfore_00R},
|
||||
{SFXfnt_transfore_01L, SFXfnt_transfore_01R},
|
||||
{SFXfnt_transfore_02L, SFXfnt_transfore_02R},
|
||||
};
|
||||
}};
|
||||
|
||||
constexpr u16 FETransitionForwardSFX[3][2] = {
|
||||
constexpr std::array<std::array<u16, 2>, 3> FETransitionForwardSFX{{
|
||||
{SFXfnt_transback_00L, SFXfnt_transback_00R},
|
||||
{SFXfnt_transback_01L, SFXfnt_transback_01R},
|
||||
{SFXfnt_transback_02L, SFXfnt_transback_02R},
|
||||
};
|
||||
}};
|
||||
|
||||
struct FEMovie {
|
||||
const char* path;
|
||||
bool loop;
|
||||
};
|
||||
|
||||
constexpr FEMovie FEMovies[] = {
|
||||
constexpr std::array<FEMovie, 9> FEMovies{{
|
||||
{"Video/00_first_start.thp", false},
|
||||
{"Video/01_startloop.thp", true},
|
||||
{"Video/02_start_fileselect_A.thp", false},
|
||||
|
@ -63,9 +65,47 @@ constexpr FEMovie FEMovies[] = {
|
|||
{"Video/07_GBAloop.thp", true},
|
||||
{"Video/08_GBA_fileselect.thp", false},
|
||||
{"Video/08_GBA_fileselect.thp", false},
|
||||
};
|
||||
}};
|
||||
|
||||
constexpr SObjectTag g_DefaultWorldTag = {FOURCC('MLVL'), 0x158efe17};
|
||||
|
||||
constexpr std::array<float, 3> AudioFadeTimeA{
|
||||
0.44f,
|
||||
5.41f,
|
||||
3.41f,
|
||||
};
|
||||
|
||||
constexpr std::array<float, 3> AudioFadeTimeB{
|
||||
4.2f,
|
||||
6.1f,
|
||||
6.1f,
|
||||
};
|
||||
|
||||
constexpr std::array<CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::EUIType, 10> NextLinkUI{
|
||||
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,
|
||||
};
|
||||
|
||||
constexpr std::array<CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::EUIType, 10> PrevLinkUI{
|
||||
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,
|
||||
};
|
||||
} // Anonymous namespace
|
||||
|
||||
void CFrontEndUI::PlayAdvanceSfx() {
|
||||
|
@ -115,8 +155,9 @@ void CFrontEndUI::SNewFileSelectFrame::FinishedLoading() {
|
|||
[this](CGuiTableGroup* caller, int oldSel) { DoSelectionChange(caller, oldSel); });
|
||||
x40_tablegroup_popup->SetMenuCancelCallback([this](CGuiTableGroup* caller) { DoPopupCancel(caller); });
|
||||
|
||||
for (int i = 0; i < 3; ++i)
|
||||
x64_fileSelections[i] = FindFileSelectOption(x1c_loadedFrame, i);
|
||||
for (size_t i = 0; i < x64_fileSelections.size(); ++i) {
|
||||
x64_fileSelections[i] = FindFileSelectOption(x1c_loadedFrame, int(i));
|
||||
}
|
||||
|
||||
x104_rowPitch =
|
||||
(x64_fileSelections[1].x0_base->GetLocalPosition() - x64_fileSelections[0].x0_base->GetLocalPosition()).z();
|
||||
|
@ -258,15 +299,15 @@ void CFrontEndUI::SNewFileSelectFrame::HandleActiveChange(CGuiTableGroup* active
|
|||
zeus::CVector3f{0.f, 0.f, active->GetUserSelection() * x104_rowPitch} + xf8_model_erase_position));
|
||||
|
||||
/* Set Touch Bar contents here */
|
||||
CFrontEndUITouchBar::SFileSelectDetail tbDetails[3] = {};
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
if (const CGameState::GameFileStateInfo* data = x4_saveUI->GetGameData(i)) {
|
||||
std::array<CFrontEndUITouchBar::SFileSelectDetail, 3> tbDetails{};
|
||||
for (size_t i = 0; i < tbDetails.size(); ++i) {
|
||||
if (const CGameState::GameFileStateInfo* data = x4_saveUI->GetGameData(int(i))) {
|
||||
tbDetails[i].state =
|
||||
data->x20_hardMode ? CFrontEndUITouchBar::EFileState::Hard : CFrontEndUITouchBar::EFileState::Normal;
|
||||
tbDetails[i].percent = data->x18_itemPercent;
|
||||
}
|
||||
}
|
||||
m_touchBar.SetFileSelectPhase(tbDetails, x8_subMenu == ESubMenu::EraseGame, CSlideShow::SlideShowGalleryFlags());
|
||||
m_touchBar.SetFileSelectPhase(tbDetails.data(), x8_subMenu == ESubMenu::EraseGame, CSlideShow::SlideShowGalleryFlags());
|
||||
} else if (active == x40_tablegroup_popup) {
|
||||
if (x8_subMenu == ESubMenu::EraseGamePopup)
|
||||
m_touchBar.SetPhase(CFrontEndUITouchBar::EPhase::EraseBack);
|
||||
|
@ -402,14 +443,17 @@ void CFrontEndUI::SNewFileSelectFrame::ActivateErase() {
|
|||
void CFrontEndUI::SNewFileSelectFrame::ClearFrameContents() {
|
||||
x108_curTime = 0.f;
|
||||
bool hasSave = false;
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
if (x4_saveUI->GetGameData(i))
|
||||
for (size_t i = 0; i < x64_fileSelections.size(); ++i) {
|
||||
if (x4_saveUI->GetGameData(int(i))) {
|
||||
hasSave = true;
|
||||
}
|
||||
|
||||
SFileMenuOption& option = x64_fileSelections[i];
|
||||
option.x2c_chRate = SFileMenuOption::ComputeRandom();
|
||||
option.x28_curField = -1;
|
||||
for (int j = 0; j < 4; ++j)
|
||||
option.x4_textpanes[j].SetPairText(u"");
|
||||
for (auto& panePair : option.x4_textpanes) {
|
||||
panePair.SetPairText(u"");
|
||||
}
|
||||
}
|
||||
|
||||
StartTextAnimating(x28_textpane_erase.x0_panes[0], g_MainStringTable->GetString(38), 60.f);
|
||||
|
@ -446,23 +490,25 @@ void CFrontEndUI::SNewFileSelectFrame::ClearFrameContents() {
|
|||
}
|
||||
|
||||
void CFrontEndUI::SNewFileSelectFrame::SetupFrameContents() {
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
for (size_t i = 0; i < x64_fileSelections.size(); ++i) {
|
||||
SFileMenuOption& option = x64_fileSelections[i];
|
||||
if (option.x28_curField == 4)
|
||||
if (option.x28_curField == 4) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SGuiTextPair* pair = (option.x28_curField == UINT32_MAX) ? nullptr : &option.x4_textpanes[option.x28_curField];
|
||||
if (!pair || pair->x0_panes[0]->GetTextSupport().GetNumCharsPrinted() >=
|
||||
pair->x0_panes[0]->GetTextSupport().GetNumCharsTotal()) {
|
||||
if (++option.x28_curField < 4) {
|
||||
std::u16string str;
|
||||
SGuiTextPair& populatePair = option.x4_textpanes[option.x28_curField];
|
||||
const CGameState::GameFileStateInfo* data = x4_saveUI->GetGameData(i);
|
||||
const CGameState::GameFileStateInfo* data = x4_saveUI->GetGameData(int(i));
|
||||
|
||||
switch (option.x28_curField) {
|
||||
case 0:
|
||||
// Completion percent
|
||||
if (data) {
|
||||
std::u16string fileStr = g_MainStringTable->GetString((data->x20_hardMode ? 106 : 39) + i);
|
||||
std::u16string fileStr = g_MainStringTable->GetString((data->x20_hardMode ? 106 : 39) + int(i));
|
||||
str = fileStr + fmt::format(fmt(u" {:02d}%"), data->x18_itemPercent);
|
||||
break;
|
||||
}
|
||||
|
@ -729,30 +775,6 @@ void CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::SetUIText(EUIType tp) {
|
|||
x0_uiType = tp;
|
||||
}
|
||||
|
||||
static const CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::EUIType NextLinkUI[] = {
|
||||
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::SFusionBonusFrame::SGBALinkFrame::EUIType PrevLinkUI[] = {
|
||||
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::SFusionBonusFrame::SGBALinkFrame::EAction CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::ProcessUserInput(
|
||||
const CFinalInput& input, bool linkInProgress, CFrontEndUITouchBar::EAction tbAction) {
|
||||
if (linkInProgress != x40_linkInProgress) {
|
||||
|
@ -773,12 +795,13 @@ CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::EAction CFrontEndUI::SFusionBonus
|
|||
input.PMouseButton(boo::EMouseButton::Primary) ||
|
||||
tbAction == CFrontEndUITouchBar::EAction::Confirm) {
|
||||
PlayAdvanceSfx();
|
||||
SetUIText(NextLinkUI[int(x0_uiType)]);
|
||||
SetUIText(NextLinkUI[size_t(x0_uiType)]);
|
||||
} else if (input.PB() || input.PSpecialKey(boo::ESpecialKey::Esc) ||
|
||||
tbAction == CFrontEndUITouchBar::EAction::Back) {
|
||||
EUIType prevUi = PrevLinkUI[int(x0_uiType)];
|
||||
if (prevUi == EUIType::Empty)
|
||||
const EUIType prevUi = PrevLinkUI[size_t(x0_uiType)];
|
||||
if (prevUi == EUIType::Empty) {
|
||||
break;
|
||||
}
|
||||
CSfxManager::SfxStart(SFXfnt_back, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
|
||||
SetUIText(prevUi);
|
||||
}
|
||||
|
@ -1754,8 +1777,10 @@ std::string CFrontEndUI::GetNextAttractMovieFileName() {
|
|||
}
|
||||
|
||||
void CFrontEndUI::SetCurrentMovie(EMenuMovie movie) {
|
||||
if (xb8_curMovie == movie)
|
||||
if (xb8_curMovie == movie) {
|
||||
return;
|
||||
}
|
||||
|
||||
StopAttractMovie();
|
||||
|
||||
if (xb8_curMovie != EMenuMovie::Stopped) {
|
||||
|
@ -1766,10 +1791,11 @@ void CFrontEndUI::SetCurrentMovie(EMenuMovie movie) {
|
|||
xb8_curMovie = movie;
|
||||
|
||||
if (xb8_curMovie != EMenuMovie::Stopped) {
|
||||
xcc_curMoviePtr = x70_menuMovies[int(xb8_curMovie)].get();
|
||||
xcc_curMoviePtr = x70_menuMovies[size_t(xb8_curMovie)].get();
|
||||
xcc_curMoviePtr->SetPlayMode(CMoviePlayer::EPlayMode::Playing);
|
||||
} else
|
||||
} else {
|
||||
xcc_curMoviePtr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void CFrontEndUI::StopAttractMovie() {
|
||||
|
@ -2012,26 +2038,34 @@ bool CFrontEndUI::PumpLoad() {
|
|||
|
||||
bool CFrontEndUI::PumpMovieLoad() {
|
||||
/* Prepare all FrontEnd movies and pause each */
|
||||
if (xd1_moviesLoaded)
|
||||
if (xd1_moviesLoaded) {
|
||||
return true;
|
||||
for (int i = 0; i < 9; ++i) {
|
||||
if (!x70_menuMovies[i]) {
|
||||
const FEMovie& movie = FEMovies[i];
|
||||
std::string path = movie.path;
|
||||
if (i == int(EMenuMovie::StartFileSelectA)) {
|
||||
auto pos = path.find("A.thp");
|
||||
if (pos != std::string::npos)
|
||||
path[pos] = 'A' + x18_rndA;
|
||||
} else if (i == int(EMenuMovie::FileSelectPlayGameA)) {
|
||||
auto pos = path.find("A.thp");
|
||||
if (pos != std::string::npos)
|
||||
path[pos] = 'A' + x1c_rndB;
|
||||
}
|
||||
x70_menuMovies[i] = std::make_unique<CMoviePlayer>(path.c_str(), 0.05f, movie.loop, false);
|
||||
x70_menuMovies[i]->SetPlayMode(CMoviePlayer::EPlayMode::Stopped);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < x70_menuMovies.size(); ++i) {
|
||||
if (x70_menuMovies[i] != nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const FEMovie& movie = FEMovies[i];
|
||||
std::string path = movie.path;
|
||||
if (i == size_t(EMenuMovie::StartFileSelectA)) {
|
||||
const auto pos = path.find("A.thp");
|
||||
if (pos != std::string::npos) {
|
||||
path[pos] = 'A' + x18_rndA;
|
||||
}
|
||||
} else if (i == size_t(EMenuMovie::FileSelectPlayGameA)) {
|
||||
const auto pos = path.find("A.thp");
|
||||
if (pos != std::string::npos) {
|
||||
path[pos] = 'A' + x1c_rndB;
|
||||
}
|
||||
}
|
||||
|
||||
x70_menuMovies[i] = std::make_unique<CMoviePlayer>(path.c_str(), 0.05f, movie.loop, false);
|
||||
x70_menuMovies[i]->SetPlayMode(CMoviePlayer::EPlayMode::Stopped);
|
||||
return false;
|
||||
}
|
||||
|
||||
xd1_moviesLoaded = true;
|
||||
return true;
|
||||
}
|
||||
|
@ -2169,10 +2203,11 @@ void CFrontEndUI::ProcessUserInput(const CFinalInput& input, CArchitectureQueue&
|
|||
}
|
||||
|
||||
void CFrontEndUI::TransitionToGame() {
|
||||
if (x14_phase >= EPhase::ToPlayGame)
|
||||
if (x14_phase >= EPhase::ToPlayGame) {
|
||||
return;
|
||||
}
|
||||
|
||||
const u16* sfx = FETransitionForwardSFX[x1c_rndB];
|
||||
const auto 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);
|
||||
|
||||
|
@ -2189,10 +2224,6 @@ 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::FileSelect) {
|
||||
switch (xdc_saveUI->Update(dt)) {
|
||||
|
@ -2256,14 +2287,12 @@ CIOWin::EMessageReturn CFrontEndUI::Update(float dt, CArchitectureQueue& queue)
|
|||
if (PumpMovieLoad()) {
|
||||
/* Prime first frame of movies */
|
||||
UpdateMovies(dt);
|
||||
for (int i = 0; i < 9; ++i) {
|
||||
if (!x70_menuMovies[i]->GetIsFullyCached()) {
|
||||
moviesReady = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else
|
||||
|
||||
moviesReady = std::all_of(x70_menuMovies.cbegin(), x70_menuMovies.cend(),
|
||||
[](const auto& movie) { return movie->GetIsFullyCached(); });
|
||||
} else {
|
||||
moviesReady = false;
|
||||
}
|
||||
|
||||
if (moviesReady) {
|
||||
/* Ready to display FrontEnd */
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "Runtime/CGameDebug.hpp"
|
||||
#include "Runtime/CGameOptionsTouchBar.hpp"
|
||||
#include "Runtime/CIOWin.hpp"
|
||||
|
@ -57,7 +59,7 @@ public:
|
|||
static void PlayAdvanceSfx();
|
||||
|
||||
struct SGuiTextPair {
|
||||
CGuiTextPane* x0_panes[2] = {};
|
||||
std::array<CGuiTextPane*, 2> x0_panes{};
|
||||
void SetPairText(std::u16string_view str);
|
||||
};
|
||||
static SGuiTextPair FindTextPanePair(CGuiFrame* frame, const char* name);
|
||||
|
@ -67,7 +69,7 @@ public:
|
|||
CGuiWidget* x0_base;
|
||||
|
||||
/* filename, world, playtime, date */
|
||||
SGuiTextPair x4_textpanes[4];
|
||||
std::array<SGuiTextPair, 4> x4_textpanes;
|
||||
|
||||
u32 x28_curField = 0;
|
||||
float x2c_chRate = ComputeRandom();
|
||||
|
@ -97,7 +99,7 @@ public:
|
|||
SGuiTextPair x50_textpane_popupcancel;
|
||||
SGuiTextPair x58_textpane_popupextra;
|
||||
CGuiTextPane* x60_textpane_cancel = nullptr;
|
||||
SFileMenuOption x64_fileSelections[3];
|
||||
std::array<SFileMenuOption, 3> x64_fileSelections;
|
||||
zeus::CVector3f xf8_model_erase_position;
|
||||
float x104_rowPitch = 0.f;
|
||||
float x108_curTime = 0.f;
|
||||
|
@ -330,7 +332,7 @@ private:
|
|||
float x64_pressStartAlpha = 0.f;
|
||||
float x68_musicVol = 1.f;
|
||||
u32 x6c_;
|
||||
std::unique_ptr<CMoviePlayer> x70_menuMovies[9];
|
||||
std::array<std::unique_ptr<CMoviePlayer>, 9> x70_menuMovies;
|
||||
EMenuMovie xb8_curMovie = EMenuMovie::Stopped;
|
||||
int xbc_nextAttract = 0;
|
||||
int xc0_attractCount = 0;
|
||||
|
|
Loading…
Reference in New Issue