metaforce/Runtime/MP1/CFrontEndUI.hpp

469 lines
14 KiB
C++
Raw Normal View History

2016-04-13 06:07:23 +00:00
#ifndef __URDE_CFRONTENDUI_HPP__
#define __URDE_CFRONTENDUI_HPP__
2015-08-27 00:23:46 +00:00
#include "CIOWin.hpp"
#include "CGameDebug.hpp"
2016-09-16 20:18:03 +00:00
#include "RetroTypes.hpp"
#include "CToken.hpp"
2016-12-14 22:56:59 +00:00
#include "Audio/CStaticAudioPlayer.hpp"
#include "Audio/CSfxManager.hpp"
2016-12-14 22:56:59 +00:00
#include "CGBASupport.hpp"
#include "zeus/CVector3f.hpp"
#include "Input/CRumbleGenerator.hpp"
#include "GuiSys/CGuiTextSupport.hpp"
2016-12-18 04:16:04 +00:00
#include "Graphics/Shaders/CTexturedQuadFilter.hpp"
#include "Graphics/Shaders/CColoredQuadFilter.hpp"
#include "CFrontEndUITouchBar.hpp"
2017-02-10 09:00:57 +00:00
#include "CGameOptionsTouchBar.hpp"
2015-08-27 00:23:46 +00:00
2016-03-04 23:04:53 +00:00
namespace urde
2015-08-27 00:23:46 +00:00
{
class CGuiSliderGroup;
class CGuiTableGroup;
2016-08-05 23:48:53 +00:00
class CMoviePlayer;
2015-08-31 03:44:42 +00:00
struct SObjectTag;
2016-09-16 20:18:03 +00:00
class CDependencyGroup;
class CTexture;
class CAudioGroupSet;
2016-12-13 05:22:30 +00:00
class CSaveWorld;
class CStringTable;
class CGuiFrame;
2016-12-14 22:56:59 +00:00
class CGuiTextPane;
class CGuiWidget;
class CGuiTableGroup;
class CGuiModel;
2015-08-27 00:23:46 +00:00
namespace MP1
{
2016-12-14 22:56:59 +00:00
class CNESEmulator;
2017-02-12 03:17:18 +00:00
class CSaveGameScreen;
class CQuitGameScreen;
2015-08-27 00:23:46 +00:00
class CFrontEndUI : public CIOWin
{
2016-09-16 20:18:03 +00:00
public:
enum class EPhase
{
2017-01-09 03:44:00 +00:00
LoadDepsGroup,
LoadDeps,
LoadFrames,
LoadMovies,
DisplayFrontEnd,
ToPlayGame,
ExitFrontEnd
};
2016-12-13 05:22:30 +00:00
enum class EScreen
2016-09-16 20:18:03 +00:00
{
2017-01-09 03:44:00 +00:00
OpenCredits,
Title,
AttractMovie,
FileSelect,
FusionBonus,
ToPlayGame
2016-09-16 20:18:03 +00:00
};
2016-12-13 05:22:30 +00:00
enum class EMenuMovie
{
Stopped = -1,
FirstStart = 0,
StartLoop,
StartFileSelectA,
FileSelectLoop,
FileSelectPlayGameA,
FileSelectGBA,
GBALoop,
GBAFileSelectA,
GBAFileSelectB
};
2016-12-16 23:05:29 +00:00
static void PlayAdvanceSfx();
2016-12-14 22:56:59 +00:00
struct SGuiTextPair
{
CGuiTextPane* x0_panes[2] = {};
2017-01-24 07:41:33 +00:00
void SetPairText(const std::u16string& str);
2016-12-14 22:56:59 +00:00
};
static SGuiTextPair FindTextPanePair(CGuiFrame* frame, const char* name);
2017-01-24 07:41:33 +00:00
static void FindAndSetPairText(CGuiFrame* frame, const char* name, const std::u16string& str);
2016-12-18 04:16:04 +00:00
struct SFileMenuOption
{
CGuiWidget* x0_base;
/* filename, world, playtime, date */
SGuiTextPair x4_textpanes[4];
2016-12-16 04:35:49 +00:00
2017-01-09 03:44:00 +00:00
u32 x28_curField = 0;
float x2c_chRate = ComputeRandom();
2016-12-16 04:35:49 +00:00
static float ComputeRandom()
{
return rand() / float(RAND_MAX) * 30.f + 30.f;
}
};
2016-12-14 22:56:59 +00:00
struct SNewFileSelectFrame
{
2016-12-18 04:16:04 +00:00
enum class ESubMenu
{
2017-01-09 03:44:00 +00:00
Root,
EraseGame,
2017-02-10 09:00:57 +00:00
EraseGamePopup,
2017-01-09 03:44:00 +00:00
NewGamePopup
2016-12-18 04:16:04 +00:00
};
2016-12-30 06:37:01 +00:00
enum class EAction
2016-12-16 04:35:49 +00:00
{
2017-01-09 03:44:00 +00:00
None,
GameOptions,
FusionBonus,
SlideShow
2016-12-16 04:35:49 +00:00
};
2016-12-14 22:56:59 +00:00
u32 x0_rnd;
2017-02-12 03:17:18 +00:00
CSaveGameScreen* x4_saveUI;
2017-01-09 03:44:00 +00:00
ESubMenu x8_subMenu = ESubMenu::Root;
EAction xc_action = EAction::None;
2016-12-14 22:56:59 +00:00
TLockedToken<CGuiFrame> x10_frme;
CGuiFrame* x1c_loadedFrame = nullptr;
CGuiTableGroup* x20_tablegroup_fileselect = nullptr;
CGuiModel* x24_model_erase = nullptr;
SGuiTextPair x28_textpane_erase;
2016-12-16 23:05:29 +00:00
SGuiTextPair x30_textpane_cheats;
SGuiTextPair x38_textpane_gba;
CGuiTableGroup* x40_tablegroup_popup = nullptr;
CGuiModel* x44_model_dash7 = nullptr;
2016-12-16 23:05:29 +00:00
SGuiTextPair x48_textpane_popupadvance;
SGuiTextPair x50_textpane_popupcancel;
SGuiTextPair x58_textpane_popupextra;
CGuiTextPane* x60_textpane_cancel = nullptr;
2016-12-18 04:16:04 +00:00
SFileMenuOption x64_fileSelections[3];
zeus::CVector3f xf8_model_erase_position;
float x104_rowPitch = 0.f;
2016-12-16 04:35:49 +00:00
float x108_curTime = 0.f;
2017-01-10 07:15:49 +00:00
bool x10c_saveReady = false;
2017-02-10 09:00:57 +00:00
bool x10d_needsEraseToggle = false;
2016-12-16 23:05:29 +00:00
bool x10e_needsNewToggle = false;
2016-12-16 04:35:49 +00:00
CFrontEndUITouchBar& m_touchBar;
2017-02-12 03:17:18 +00:00
SNewFileSelectFrame(CSaveGameScreen* sui, u32 rnd, CFrontEndUITouchBar& touchBar);
void FinishedLoading();
bool PumpLoad();
2016-12-16 04:35:49 +00:00
bool IsTextDoneAnimating() const;
2017-01-09 03:44:00 +00:00
void Update(float dt);
EAction ProcessUserInput(const CFinalInput& input, CFrontEndUITouchBar::EAction tbAction);
2016-12-18 04:16:04 +00:00
void Draw() const;
2016-12-16 04:35:49 +00:00
void HandleActiveChange(CGuiTableGroup* active);
2017-02-10 09:00:57 +00:00
void DeactivateEraseGamePopup();
void ActivateEraseGamePopup();
2016-12-16 23:05:29 +00:00
void DeactivateNewGamePopup();
void ActivateNewGamePopup();
void ResetFrame();
2017-01-09 03:44:00 +00:00
void ActivateErase();
2016-12-16 23:05:29 +00:00
void ClearFrameContents();
void SetupFrameContents();
void DoPopupCancel(CGuiTableGroup* caller);
void DoPopupAdvance(CGuiTableGroup* caller);
2016-12-18 04:16:04 +00:00
void DoFileMenuCancel(CGuiTableGroup* caller);
2017-01-09 03:44:00 +00:00
void DoSelectionChange(CGuiTableGroup* caller, int userSel);
2016-12-18 04:16:04 +00:00
void DoFileMenuAdvance(CGuiTableGroup* caller);
2016-12-16 23:05:29 +00:00
2016-12-18 04:16:04 +00:00
static SFileMenuOption FindFileSelectOption(CGuiFrame* frame, int idx);
2017-01-24 07:41:33 +00:00
static void StartTextAnimating(CGuiTextPane* text, const std::u16string& str, float chRate);
};
2017-01-09 03:44:00 +00:00
struct SFusionBonusFrame
{
2016-12-31 00:51:51 +00:00
struct SGBALinkFrame
{
enum class EUIType
{
2017-01-01 06:46:52 +00:00
Empty = -1,
InsertPak = 0,
ConnectSocket = 1,
PressStartAndSelect = 2,
BeginLink = 3,
Linking = 4,
LinkFailed = 5,
LinkCompleteOrLinking = 6,
TurnOffGBA = 7,
Complete = 8,
Cancelled = 9
2016-12-31 00:51:51 +00:00
};
2017-01-01 06:46:52 +00:00
enum class EAction
{
None = 0,
Complete = 1,
Cancelled = 2
};
EUIType x0_uiType;
CGBASupport* x4_gbaSupport;
CGuiFrame* x8_frme;
SGuiTextPair xc_textpane_instructions;
CGuiTextPane* x14_textpane_yes = nullptr;
CGuiTextPane* x18_textpane_no = nullptr;
CGuiModel* x1c_model_gc = nullptr;
CGuiModel* x20_model_gba = nullptr;
CGuiModel* x24_model_cable = nullptr;
CGuiModel* x28_model_circlegcport = nullptr;
CGuiModel* x2c_model_circlegbaport = nullptr;
CGuiModel* x30_model_circlestartselect = nullptr;
CGuiModel* x34_model_pakout = nullptr;
CGuiModel* x38_model_gbascreen = nullptr;
CGuiModel* x3c_model_connect = nullptr;
bool x40_linkInProgress;
2016-12-31 00:51:51 +00:00
void SetUIText(EUIType tp);
2017-02-10 09:00:57 +00:00
EAction ProcessUserInput(const CFinalInput &input, bool linkInProgress,
CFrontEndUITouchBar::EAction tbAction);
2016-12-31 00:51:51 +00:00
void Update(float dt);
void FinishedLoading();
void Draw();
2017-01-01 06:46:52 +00:00
SGBALinkFrame(CGuiFrame* linkFrame, CGBASupport* support, bool linkInProgress);
2016-12-31 00:51:51 +00:00
};
2016-12-30 06:37:01 +00:00
enum class EAction
{
2017-01-01 06:46:52 +00:00
None,
GoBack,
PlayNESMetroid
2016-12-30 06:37:01 +00:00
};
2016-12-31 00:51:51 +00:00
std::unique_ptr<SGBALinkFrame> x0_gbaLinkFrame;
std::unique_ptr<CGBASupport> x4_gbaSupport;
2017-01-01 06:46:52 +00:00
EAction x8_action = EAction::None;
TLockedToken<CGuiFrame> xc_gbaScreen;
TLockedToken<CGuiFrame> x18_gbaLink;
CGuiFrame* x24_loadedFrame = nullptr;
2016-12-16 04:35:49 +00:00
CGuiTableGroup* x28_tablegroup_options = nullptr;
CGuiTableGroup* x2c_tablegroup_fusionsuit = nullptr;
SGuiTextPair x30_textpane_instructions;
bool x38_lastDoDraw = false;
2017-01-01 06:46:52 +00:00
bool x39_fusionNotComplete = false;
bool x3a_mpNotComplete = false;
2017-02-10 09:00:57 +00:00
CFrontEndUITouchBar& m_touchBar;
SFusionBonusFrame(CFrontEndUITouchBar& touchBar);
void FinishedLoading();
2016-12-14 22:56:59 +00:00
bool PumpLoad();
2016-12-16 04:35:49 +00:00
void SetTableColors(CGuiTableGroup* tbgp) const;
2017-02-12 03:17:18 +00:00
void Update(float dt, CSaveGameScreen* saveUI);
EAction ProcessUserInput(const CFinalInput& input, CSaveGameScreen* sui,
2017-02-10 09:00:57 +00:00
CFrontEndUITouchBar::EAction tbAction);
2016-12-18 04:16:04 +00:00
void Draw() const;
2016-12-16 04:35:49 +00:00
2017-01-01 06:46:52 +00:00
void ResetCompletionFlags()
{
x39_fusionNotComplete = false;
x3a_mpNotComplete = false;
}
void DoCancel(CGuiTableGroup* caller);
2017-01-09 03:44:00 +00:00
void DoSelectionChange(CGuiTableGroup* caller, int userSel);
2017-01-01 06:46:52 +00:00
void DoAdvance(CGuiTableGroup* caller);
2016-12-14 22:56:59 +00:00
};
struct SFrontEndFrame
{
2016-12-30 06:37:01 +00:00
enum class EAction
{
2017-01-09 03:44:00 +00:00
None,
StartGame,
FusionBonus,
GameOptions,
SlideShow
2016-12-30 06:37:01 +00:00
};
2016-12-14 22:56:59 +00:00
u32 x0_rnd;
2016-12-30 06:37:01 +00:00
EAction x4_action;
2016-12-14 22:56:59 +00:00
TLockedToken<CGuiFrame> x8_frme;
CGuiFrame* x14_loadedFrme = nullptr;
CGuiTableGroup* x18_tablegroup_mainmenu = nullptr;
SGuiTextPair x1c_gbaPair;
SGuiTextPair x24_cheatPair;
2017-02-10 09:00:57 +00:00
CFrontEndUITouchBar& m_touchBar;
SFrontEndFrame(u32 rnd, CFrontEndUITouchBar& touchBar);
2016-12-14 22:56:59 +00:00
void FinishedLoading();
bool PumpLoad();
2017-01-09 03:44:00 +00:00
void Update(float dt);
2017-02-10 09:00:57 +00:00
EAction ProcessUserInput(const CFinalInput& input, CFrontEndUITouchBar::EAction tbAction);
2016-12-18 04:16:04 +00:00
void Draw() const;
2017-01-10 07:15:49 +00:00
void HandleActiveChange(CGuiTableGroup* active);
2016-12-14 22:56:59 +00:00
2016-12-16 23:05:29 +00:00
void DoCancel(CGuiTableGroup* caller);
2017-01-09 03:44:00 +00:00
void DoSelectionChange(CGuiTableGroup* caller, int userSel);
2016-12-16 23:05:29 +00:00
void DoAdvance(CGuiTableGroup* caller);
2016-12-14 22:56:59 +00:00
};
2016-12-30 06:37:01 +00:00
struct SNesEmulatorFrame
2016-12-14 22:56:59 +00:00
{
2016-12-30 06:37:01 +00:00
enum class EMode
{
Emulator,
2016-12-31 00:51:51 +00:00
SaveProgress,
2016-12-30 06:37:01 +00:00
ContinuePlaying,
2016-12-31 00:51:51 +00:00
QuitNESMetroid
2016-12-30 06:37:01 +00:00
};
EMode x0_mode = EMode::Emulator;
2016-12-14 22:56:59 +00:00
std::unique_ptr<CNESEmulator> x4_nesEmu;
2017-02-12 03:17:18 +00:00
std::unique_ptr<CQuitGameScreen> x8_quitScreen;
2016-12-14 22:56:59 +00:00
std::unique_ptr<CGuiTextSupport> xc_textSupport;
float x10_remTime = 8.f;
2016-12-31 00:51:51 +00:00
bool x14_emulationSuspended = false;
bool x15_enableFiltering = true;
2016-12-14 22:56:59 +00:00
2016-12-30 06:37:01 +00:00
SNesEmulatorFrame();
void SetMode(EMode mode);
2017-02-12 03:17:18 +00:00
void ProcessUserInput(const CFinalInput& input, CSaveGameScreen* sui);
bool Update(float dt, CSaveGameScreen* saveUi);
void Draw(CSaveGameScreen* saveUi) const;
2016-12-14 22:56:59 +00:00
};
struct SOptionsFrontEndFrame
{
2017-01-10 07:15:49 +00:00
float x0_uiAlpha = 0.f;
2016-12-14 22:56:59 +00:00
TLockedToken<CGuiFrame> x4_frme;
TLockedToken<CStringTable> x10_pauseScreen;
2017-01-10 07:15:49 +00:00
CGuiFrame* x1c_loadedFrame = nullptr;
CStringTable* x20_loadedPauseStrg = nullptr;
CGuiTableGroup* x24_tablegroup_leftmenu = nullptr;
CGuiTableGroup* x28_tablegroup_rightmenu = nullptr;
CGuiTableGroup* x2c_tablegroup_double = nullptr;
CGuiTableGroup* x30_tablegroup_triple = nullptr;
CGuiSliderGroup* x34_slidergroup_slider = nullptr;
float x38_rowPitch = 0.f;
CSfxHandle x3c_sliderSfx;
2016-12-14 22:56:59 +00:00
CRumbleGenerator x40_rumbleGen;
union
{
u8 _dummy = 0;
struct
{
2017-01-10 07:15:49 +00:00
bool x134_24_visible : 1;
bool x134_25_exitOptions : 1;
2016-12-14 22:56:59 +00:00
};
};
2017-02-10 09:00:57 +00:00
std::unique_ptr<CGameOptionsTouchBar> m_touchBar;
bool m_touchBarInValue = false;
bool m_touchBarValueDirty = false;
2016-12-14 22:56:59 +00:00
SOptionsFrontEndFrame();
2017-01-10 07:15:49 +00:00
void DoSliderChange(CGuiSliderGroup* caller, float value);
void DoMenuCancel(CGuiTableGroup* caller);
void DoMenuSelectionChange(CGuiTableGroup* caller, int sel);
void DoLeftMenuAdvance(CGuiTableGroup* caller);
void DeactivateRightMenu();
void HandleRightSelectionChange();
2017-01-10 07:15:49 +00:00
void SetRightUIText();
void SetTableColors(CGuiTableGroup* tbgp) const;
void FinishedLoading();
bool PumpLoad();
2017-02-12 03:17:18 +00:00
bool ProcessUserInput(const CFinalInput& input, CSaveGameScreen* sui);
void Update(float dt, CSaveGameScreen* saveUi);
2016-12-18 04:16:04 +00:00
void Draw() const;
2016-12-14 22:56:59 +00:00
};
2017-01-09 03:44:00 +00:00
bool CanShowSaveUI() const
2016-12-18 04:16:04 +00:00
{
2017-01-09 03:44:00 +00:00
if (x50_curScreen != EScreen::FileSelect && x50_curScreen != EScreen::FusionBonus)
2016-12-18 04:16:04 +00:00
return false;
2017-01-09 03:44:00 +00:00
if (x54_nextScreen != EScreen::FileSelect && x54_nextScreen != EScreen::FusionBonus)
2016-12-18 04:16:04 +00:00
return false;
return true;
}
2016-09-16 20:18:03 +00:00
private:
2017-01-09 03:44:00 +00:00
EPhase x14_phase = EPhase::LoadDepsGroup;
2016-09-16 20:18:03 +00:00
u32 x18_rndA;
u32 x1c_rndB;
TLockedToken<CDependencyGroup> x20_depsGroup;
2016-12-18 04:16:04 +00:00
std::vector<CToken> x2c_deps;
2016-09-16 20:18:03 +00:00
TLockedToken<CTexture> x38_pressStart;
TLockedToken<CAudioGroupSet> x44_frontendAudioGrp;
2017-01-09 03:44:00 +00:00
EScreen x50_curScreen = EScreen::OpenCredits;
EScreen x54_nextScreen = EScreen::OpenCredits;
float x58_fadeBlackTimer = 0.f;
bool x5c_fadeBlackWithMovie = false;
float x60_pressStartTime = 0.f;
2016-12-18 04:16:04 +00:00
float x64_pressStartAlpha = 0.f;
2016-12-14 22:56:59 +00:00
float x68_musicVol = 1.f;
2016-12-13 05:22:30 +00:00
u32 x6c_;
std::unique_ptr<CMoviePlayer> x70_menuMovies[9];
EMenuMovie xb8_curMovie = EMenuMovie::Stopped;
2016-09-16 20:18:03 +00:00
int xbc_nextAttract = 0;
int xc0_attractCount = 0;
2016-12-13 05:22:30 +00:00
std::unique_ptr<CMoviePlayer> xc4_attractMovie;
CMoviePlayer* xcc_curMoviePtr = nullptr;
2017-01-09 03:44:00 +00:00
bool xd0_playerSkipToTitle = false;
2016-12-13 05:22:30 +00:00
bool xd1_moviesLoaded = false;
2017-01-09 03:44:00 +00:00
bool xd2_deferSlideShow = false;
2016-12-14 22:56:59 +00:00
std::unique_ptr<CStaticAudioPlayer> xd4_audio1;
std::unique_ptr<CStaticAudioPlayer> xd8_audio2;
2017-02-12 03:17:18 +00:00
std::unique_ptr<CSaveGameScreen> xdc_saveUI;
2017-01-09 03:44:00 +00:00
std::unique_ptr<SNewFileSelectFrame> xe0_frontendCardFrme;
std::unique_ptr<SFusionBonusFrame> xe4_fusionBonusFrme;
std::unique_ptr<SFrontEndFrame> xe8_frontendNoCardFrme;
2016-12-30 06:37:01 +00:00
std::unique_ptr<SNesEmulatorFrame> xec_emuFrme;
std::unique_ptr<SOptionsFrontEndFrame> xf0_optionsFrme;
2016-12-14 22:56:59 +00:00
CStaticAudioPlayer* xf4_curAudio = nullptr;
2016-12-13 05:22:30 +00:00
2016-12-18 04:16:04 +00:00
CColoredQuadFilter m_fadeToBlack = {CCameraFilterPass::EFilterType::Blend};
std::experimental::optional<CTexturedQuadFilterAlpha> m_pressStartQuad;
std::unique_ptr<CFrontEndUITouchBar> m_touchBar;
2017-01-09 03:44:00 +00:00
void SetFadeBlackWithMovie()
2015-08-27 00:23:46 +00:00
{
2017-01-09 03:44:00 +00:00
x58_fadeBlackTimer = 1000000.f;
x5c_fadeBlackWithMovie = true;
2016-12-13 05:22:30 +00:00
}
2017-01-09 03:44:00 +00:00
void SetFadeBlackTimer(float seconds)
2015-08-27 00:23:46 +00:00
{
2017-01-09 03:44:00 +00:00
x58_fadeBlackTimer = seconds;
x5c_fadeBlackWithMovie = false;
2016-12-13 05:22:30 +00:00
}
2017-01-09 03:44:00 +00:00
void TransitionToGame();
2016-12-14 22:56:59 +00:00
void UpdateMusicVolume();
void FinishedLoadingDepsGroup();
bool PumpLoad();
2016-12-13 05:22:30 +00:00
public:
2015-08-27 00:23:46 +00:00
CFrontEndUI();
2016-09-16 20:18:03 +00:00
void StartSlideShow(CArchitectureQueue& queue);
std::string GetAttractMovieFileName(int idx);
std::string GetNextAttractMovieFileName();
2015-08-27 00:23:46 +00:00
void SetCurrentMovie(EMenuMovie movie);
void StopAttractMovie();
2016-12-13 05:22:30 +00:00
void StartAttractMovie();
2015-08-27 00:23:46 +00:00
void StartStateTransition(EScreen screen);
2017-01-09 03:44:00 +00:00
void CompleteStateTransition();
2015-08-27 00:23:46 +00:00
void HandleDebugMenuReturnValue(CGameDebug::EReturnValue val, CArchitectureQueue& queue);
void Draw() const;
void UpdateMovies(float dt);
2016-12-13 05:22:30 +00:00
bool PumpMovieLoad();
2016-09-16 20:18:03 +00:00
void ProcessUserInput(const CFinalInput& input, CArchitectureQueue& queue);
EMessageReturn Update(float dt, CArchitectureQueue& queue);
2015-08-27 00:23:46 +00:00
EMessageReturn OnMessage(const CArchitectureMessage& msg, CArchitectureQueue& queue);
};
}
}
2016-04-13 06:07:23 +00:00
#endif // __URDE_CFRONTENDUI_HPP__