From 17d986bb43526aa4b0e2dcb73e2c29e2dc9783de Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Thu, 9 Feb 2017 23:00:57 -1000 Subject: [PATCH] Implement CGameOptionsTouchBar --- Runtime/CGameOptions.cpp | 4 +- Runtime/CGameOptions.hpp | 2 +- Runtime/CGameOptionsTouchBar.cpp | 19 + Runtime/CGameOptionsTouchBar.hpp | 31 + Runtime/CGameOptionsTouchBarMac.mm | 307 +++++++++ Runtime/CMakeLists.txt | 4 +- Runtime/Graphics/CModelBoo.cpp | 1 + Runtime/Graphics/Shaders/CModelShaders.hpp | 1 + .../Graphics/Shaders/CModelShadersGLSL.cpp | 1 + .../Graphics/Shaders/CModelShadersHLSL.cpp | 1 + .../Graphics/Shaders/CModelShadersMetal.cpp | 1 + Runtime/MP1/CFrontEndUI.cpp | 331 ++++++++-- Runtime/MP1/CFrontEndUI.hpp | 31 +- Runtime/MP1/CFrontEndUITouchBar.cpp | 12 +- Runtime/MP1/CFrontEndUITouchBar.hpp | 24 +- Runtime/MP1/CFrontEndUITouchBarMac.mm | 594 +++++++++++++++++- hecl | 2 +- 17 files changed, 1255 insertions(+), 111 deletions(-) create mode 100644 Runtime/CGameOptionsTouchBar.cpp create mode 100644 Runtime/CGameOptionsTouchBar.hpp create mode 100644 Runtime/CGameOptionsTouchBarMac.mm diff --git a/Runtime/CGameOptions.cpp b/Runtime/CGameOptions.cpp index c8af4f62d..f7d1b7730 100644 --- a/Runtime/CGameOptions.cpp +++ b/Runtime/CGameOptions.cpp @@ -382,7 +382,7 @@ void CGameOptions::EnsureSettings() } void CGameOptions::TryRestoreDefaults(const CFinalInput& input, int category, - int option, bool frontend) + int option, bool frontend, bool forceRestore) { const std::pair& options = GameOptionsRegistry[category]; if (!options.first) @@ -391,7 +391,7 @@ void CGameOptions::TryRestoreDefaults(const CFinalInput& input, int category, if (options.second[option].option != EGameOption::RestoreDefaults) return; - if (!input.PA()) + if (!forceRestore && !input.PA()) return; if (frontend) diff --git a/Runtime/CGameOptions.hpp b/Runtime/CGameOptions.hpp index a13b5ec3b..fec3b254a 100644 --- a/Runtime/CGameOptions.hpp +++ b/Runtime/CGameOptions.hpp @@ -173,7 +173,7 @@ public: void ResetControllerAssets(); static void TryRestoreDefaults(const CFinalInput& input, int category, - int option, bool frontend); + int option, bool frontend, bool forceRestore); static void SetOption(EGameOption option, int value); static int GetOption(EGameOption option); }; diff --git a/Runtime/CGameOptionsTouchBar.cpp b/Runtime/CGameOptionsTouchBar.cpp new file mode 100644 index 000000000..49ac1dddc --- /dev/null +++ b/Runtime/CGameOptionsTouchBar.cpp @@ -0,0 +1,19 @@ +#include "CGameOptionsTouchBar.hpp" + +namespace urde +{ + +CGameOptionsTouchBar::EAction CGameOptionsTouchBar::PopAction() +{ return EAction::None; } +void CGameOptionsTouchBar::GetSelection(int& left, int& right, int& value) +{ left = -1, right = -1, value = -1; } +void CGameOptionsTouchBar::SetSelection(int left, int right, int value) {} + +#ifndef __APPLE__ +std::unique_ptr NewGameOptionsTouchBar() +{ + return std::make_unique(); +} +#endif + +} diff --git a/Runtime/CGameOptionsTouchBar.hpp b/Runtime/CGameOptionsTouchBar.hpp new file mode 100644 index 000000000..828638ec7 --- /dev/null +++ b/Runtime/CGameOptionsTouchBar.hpp @@ -0,0 +1,31 @@ +#ifndef __URDE_CGAMEOPTIONSTOUCHBAR_HPP__ +#define __URDE_CGAMEOPTIONSTOUCHBAR_HPP__ + +#include +#include + +namespace urde +{ + +class CGameOptionsTouchBar +{ +public: + enum class EAction + { + None, + Back, + Advance, + ValueChange + }; + + virtual ~CGameOptionsTouchBar() = default; + virtual EAction PopAction(); + virtual void GetSelection(int& left, int& right, int& value); + virtual void SetSelection(int left, int right, int value); +}; + +std::unique_ptr NewGameOptionsTouchBar(); + +} + +#endif // __URDE_CGAMEOPTIONSTOUCHBAR_HPP__ diff --git a/Runtime/CGameOptionsTouchBarMac.mm b/Runtime/CGameOptionsTouchBarMac.mm new file mode 100644 index 000000000..57db0df74 --- /dev/null +++ b/Runtime/CGameOptionsTouchBarMac.mm @@ -0,0 +1,307 @@ +#include +#include "CGameOptionsTouchBar.hpp" +#include "CGameOptions.hpp" +#include "GameGlobalObjects.hpp" +#include "MP1/MP1.hpp" +#include "GuiSys/CStringTable.hpp" + +#if !__has_feature(objc_arc) +#error ARC Required +#endif + +static NSColor* BlueConfirm() +{ + return [NSColor colorWithSRGBRed:0/255.f green:130/255.f blue:215/255.f alpha:1.f]; +} + +@interface GameOptionsTouchBar : NSObject +{ +@public + urde::CStringTable* _pauseScreenStrg; + urde::CGameOptionsTouchBar::EAction _action; + std::pair _selection; + int _value, _pendingValue; +} +-(IBAction)onBack:(id)sender; +-(IBAction)onSlide:(id)sender; +-(IBAction)onSet0:(id)sender; +-(IBAction)onSet1:(id)sender; +-(IBAction)onSet2:(id)sender; +-(IBAction)onLeft:(id)sender; +-(IBAction)onRight:(id)sender; +@end + +@implementation GameOptionsTouchBar +- (NSTouchBar*)makeTouchBar +{ + NSTouchBar* touchBar = [NSTouchBar new]; + touchBar.delegate = self; + id items = @[@"optionsGroup"]; + touchBar.customizationRequiredItemIdentifiers = items; + touchBar.defaultItemIdentifiers = items; + touchBar.principalItemIdentifier = @"optionsGroup"; + return touchBar; +} +-(NSTouchBarItem*)touchBar:(NSTouchBar*)touchBar + makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier +{ + if ([identifier isEqualToString:@"optionsGroup"]) + { + NSGroupTouchBarItem* item = [[NSGroupTouchBarItem alloc] initWithIdentifier:identifier]; + NSTouchBar* touchBar = [NSTouchBar new]; + touchBar.delegate = self; + id items; + if (_selection.first == -1) + { + items = [NSMutableArray arrayWithCapacity:5]; + [items addObject:@"back"]; + for (int i=0 ; i<4 ; ++i) + [items addObject:[NSString stringWithFormat:@"left/%d", i]]; + } + else if (_selection.second == -1) + { + const std::pair& opt = urde::GameOptionsRegistry[_selection.first]; + items = [NSMutableArray arrayWithCapacity:opt.first+1]; + [items addObject:@"back"]; + for (int i=0 ; i& opt = urde::GameOptionsRegistry[_selection.first]; + const urde::SGameOption& subopt = opt.second[_selection.second]; + if (subopt.type == urde::EOptionType::Float) + items = @[@"back", @"value"]; + else if (subopt.type == urde::EOptionType::DoubleEnum) + items = @[@"back", @"label", @"double0", @"double1"]; + else if (subopt.type == urde::EOptionType::TripleEnum) + items = @[@"back", @"label", @"triple0", @"triple1", @"triple2"]; + } + touchBar.customizationRequiredItemIdentifiers = items; + touchBar.defaultItemIdentifiers = items; + item.groupTouchBar = touchBar; + return item; + } + else if ([identifier isEqualToString:@"back"]) + { + NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSButton* button = [NSButton buttonWithImage:[NSImage imageNamed:NSImageNameTouchBarGoBackTemplate] + target:self action:@selector(onBack:)]; + item.view = button; + return item; + } + else if ([identifier isEqualToString:@"label"]) + { + const std::pair& opt = urde::GameOptionsRegistry[_selection.first]; + const urde::SGameOption& subopt = opt.second[_selection.second]; + + const char16_t* cStr = _pauseScreenStrg->GetString(subopt.stringId); + NSString* str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()]; + + NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSTextField* label = [NSTextField labelWithString:[str stringByAppendingString:@":"]]; + item.view = label; + return item; + } + else if ([identifier isEqualToString:@"value"]) + { + const std::pair& opt = urde::GameOptionsRegistry[_selection.first]; + const urde::SGameOption& subopt = opt.second[_selection.second]; + + const char16_t* cStr = _pauseScreenStrg->GetString(subopt.stringId); + NSString* str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()]; + + NSSliderTouchBarItem* item = [[NSSliderTouchBarItem alloc] initWithIdentifier:identifier]; + NSSlider* slider = [NSSlider sliderWithValue:_value minValue:subopt.minVal maxValue:subopt.maxVal + target:nil action:nil]; + item.target = self; + item.action = @selector(onSlide:); + item.slider = slider; + item.label = str; + return item; + } + else if ([identifier isEqualToString:@"double0"]) + { + const char16_t* cStr = _pauseScreenStrg->GetString(95); // Off + NSString* str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()]; + + NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSButton* button = [NSButton buttonWithTitle:str target:self action:@selector(onSet0:)]; + if (_value == 0) + button.bezelColor = BlueConfirm(); + item.view = button; + return item; + } + else if ([identifier isEqualToString:@"double1"]) + { + const char16_t* cStr = _pauseScreenStrg->GetString(94); // On + NSString* str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()]; + + NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSButton* button = [NSButton buttonWithTitle:str target:self action:@selector(onSet1:)]; + if (_value == 1) + button.bezelColor = BlueConfirm(); + item.view = button; + return item; + } + else if ([identifier isEqualToString:@"triple0"]) + { + const char16_t* cStr = _pauseScreenStrg->GetString(96); // Mono + NSString* str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()]; + + NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSButton* button = [NSButton buttonWithTitle:str target:self action:@selector(onSet0:)]; + if (_value == 0) + button.bezelColor = BlueConfirm(); + item.view = button; + return item; + } + else if ([identifier isEqualToString:@"triple1"]) + { + const char16_t* cStr = _pauseScreenStrg->GetString(97); // Stereo + NSString* str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()]; + + NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSButton* button = [NSButton buttonWithTitle:str target:self action:@selector(onSet1:)]; + if (_value == 1) + button.bezelColor = BlueConfirm(); + item.view = button; + return item; + } + else if ([identifier isEqualToString:@"triple2"]) + { + const char16_t* cStr = _pauseScreenStrg->GetString(98); // Dolby + NSString* str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()]; + + NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSButton* button = [NSButton buttonWithTitle:str target:self action:@selector(onSet2:)]; + if (_value == 2) + button.bezelColor = BlueConfirm(); + item.view = button; + return item; + } + else + { + NSArray* pc = [identifier pathComponents]; + if ([pc count] == 2) + { + NSString* first = [pc objectAtIndex:0]; + if ([first isEqualToString:@"left"]) + { + auto idx = strtoul([[pc objectAtIndex:1] UTF8String], nullptr, 10); + const char16_t* cStr = _pauseScreenStrg->GetString(16+idx); + NSString* str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()]; + + NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSButton* button = [NSButton buttonWithTitle:str target:self action:@selector(onLeft:)]; + button.tag = idx; + item.view = button; + return item; + } + else if ([first isEqualToString:@"right"]) + { + const std::pair& opt = urde::GameOptionsRegistry[_selection.first]; + auto idx = strtoul([[pc objectAtIndex:1] UTF8String], nullptr, 10); + const urde::SGameOption& subopt = opt.second[idx]; + const char16_t* cStr = _pauseScreenStrg->GetString(subopt.stringId); + NSString* str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()]; + + NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSButton* button = [NSButton buttonWithTitle:str target:self action:@selector(onRight:)]; + button.tag = idx; + item.view = button; + return item; + } + } + } + return nil; +} +-(IBAction)onBack:(id)sender +{ + _action = urde::CGameOptionsTouchBar::EAction::Back; +} +-(IBAction)onSlide:(id)sender +{ + _pendingValue = [((NSSliderTouchBarItem*)sender).slider intValue]; + _action = urde::CGameOptionsTouchBar::EAction::ValueChange; +} +-(IBAction)onSet0:(id)sender +{ + _pendingValue = 0; + _action = urde::CGameOptionsTouchBar::EAction::ValueChange; +} +-(IBAction)onSet1:(id)sender +{ + _pendingValue = 1; + _action = urde::CGameOptionsTouchBar::EAction::ValueChange; +} +-(IBAction)onSet2:(id)sender +{ + _pendingValue = 2; + _action = urde::CGameOptionsTouchBar::EAction::ValueChange; +} +-(IBAction)onLeft:(id)sender +{ + _selection.first = ((NSButton*)sender).tag; + _action = urde::CGameOptionsTouchBar::EAction::Advance; +} +-(IBAction)onRight:(id)sender +{ + _selection.second = ((NSButton*)sender).tag; + _action = urde::CGameOptionsTouchBar::EAction::Advance; +} +@end + +namespace urde +{ + +class CGameOptionsTouchBarMac : public CGameOptionsTouchBar +{ + TLockedToken m_pauseScreen; + GameOptionsTouchBar* m_touchBar; + bool m_initialized = false; +public: + CGameOptionsTouchBarMac() + { + m_pauseScreen = g_SimplePool->GetObj("STRG_PauseScreen"); + m_touchBar = [GameOptionsTouchBar new]; + m_touchBar->_pauseScreenStrg = m_pauseScreen.GetObj(); + m_touchBar->_selection = std::make_pair(-1, -1); + m_touchBar->_value = -1; + } + EAction PopAction() + { + if (m_touchBar->_action != EAction::None) + { + EAction action = m_touchBar->_action; + m_touchBar->_action = EAction::None; + return action; + } + return EAction::None; + } + void GetSelection(int& left, int& right, int& value) + { + left = m_touchBar->_selection.first; + right = m_touchBar->_selection.second; + value = m_touchBar->_pendingValue; + } + void SetSelection(int left, int right, int value) + { + if (m_initialized && + left == m_touchBar->_selection.first && + right == m_touchBar->_selection.second && + value == m_touchBar->_value) + return; + m_initialized = true; + m_touchBar->_selection = std::make_pair(left, right); + m_touchBar->_value = value; + g_Main->GetMainWindow()->setTouchBarProvider((__bridge_retained void*)m_touchBar); + } +}; + +std::unique_ptr NewGameOptionsTouchBar() +{ + return std::make_unique(); +} + +} diff --git a/Runtime/CMakeLists.txt b/Runtime/CMakeLists.txt index 7a20254c4..7b2dd7fa2 100644 --- a/Runtime/CMakeLists.txt +++ b/Runtime/CMakeLists.txt @@ -41,9 +41,10 @@ add_subdirectory(MP3) if(APPLE) set_source_files_properties(MP1/CFrontEndUITouchBarMac.mm + CGameOptionsTouchBarMac.mm PROPERTIES COMPILE_FLAGS -fobjc-arc) bintoc(startButton.c Resources/startButton@2x.png START_BUTTON_2X) - list(APPEND PLAT_SRCS startButton.c) + list(APPEND PLAT_SRCS startButton.c CGameOptionsTouchBarMac.mm) endif() add_library(RuntimeCommon @@ -85,6 +86,7 @@ add_library(RuntimeCommon IObjectStore.hpp CSimplePool.hpp CSimplePool.cpp CGameOptions.hpp CGameOptions.cpp + CGameOptionsTouchBar.hpp CGameOptionsTouchBar.cpp CStaticInterference.hpp CCRC32.hpp CCRC32.cpp IFactory.hpp diff --git a/Runtime/Graphics/CModelBoo.cpp b/Runtime/Graphics/CModelBoo.cpp index bf6235a0a..0d562fb71 100644 --- a/Runtime/Graphics/CModelBoo.cpp +++ b/Runtime/Graphics/CModelBoo.cpp @@ -610,6 +610,7 @@ void CBooModel::UpdateUniformData(const CModelFlags& flags, lightingOut.colorRegs[0] = flags.regColors[0]; lightingOut.colorRegs[1] = flags.regColors[1]; lightingOut.colorRegs[2] = flags.regColors[2]; + lightingOut.mulColor = flags.color; lightingOut.fog = CGraphics::g_Fog; } diff --git a/Runtime/Graphics/Shaders/CModelShaders.hpp b/Runtime/Graphics/Shaders/CModelShaders.hpp index 7b9f3541c..52cd1c263 100644 --- a/Runtime/Graphics/Shaders/CModelShaders.hpp +++ b/Runtime/Graphics/Shaders/CModelShaders.hpp @@ -37,6 +37,7 @@ public: Light lights[URDE_MAX_LIGHTS]; zeus::CColor ambient; zeus::CColor colorRegs[3]; + zeus::CColor mulColor; CGraphics::CFogState fog; }; diff --git a/Runtime/Graphics/Shaders/CModelShadersGLSL.cpp b/Runtime/Graphics/Shaders/CModelShadersGLSL.cpp index 9f03d7ddc..2c33c7d6a 100644 --- a/Runtime/Graphics/Shaders/CModelShadersGLSL.cpp +++ b/Runtime/Graphics/Shaders/CModelShadersGLSL.cpp @@ -27,6 +27,7 @@ static const char* LightingGLSL = " vec4 colorReg0;\n" " vec4 colorReg1;\n" " vec4 colorReg2;\n" +" vec4 mulColor;\n" " Fog fog;\n" "};\n" "\n" diff --git a/Runtime/Graphics/Shaders/CModelShadersHLSL.cpp b/Runtime/Graphics/Shaders/CModelShadersHLSL.cpp index 67f1ae237..ed03b9d88 100644 --- a/Runtime/Graphics/Shaders/CModelShadersHLSL.cpp +++ b/Runtime/Graphics/Shaders/CModelShadersHLSL.cpp @@ -26,6 +26,7 @@ static const char* LightingHLSL = " float4 colorReg0;\n" " float4 colorReg1;\n" " float4 colorReg2;\n" +" float4 mulColor;\n" " Fog fog;\n" "};\n" "\n" diff --git a/Runtime/Graphics/Shaders/CModelShadersMetal.cpp b/Runtime/Graphics/Shaders/CModelShadersMetal.cpp index 766f874b1..69c06e5e8 100644 --- a/Runtime/Graphics/Shaders/CModelShadersMetal.cpp +++ b/Runtime/Graphics/Shaders/CModelShadersMetal.cpp @@ -26,6 +26,7 @@ static const char* LightingMetal = " float4 colorReg0;\n" " float4 colorReg1;\n" " float4 colorReg2;\n" +" float4 mulColor;\n" " Fog fog;\n" "};\n" "\n" diff --git a/Runtime/MP1/CFrontEndUI.cpp b/Runtime/MP1/CFrontEndUI.cpp index 173b838dc..ec3de2a6d 100644 --- a/Runtime/MP1/CFrontEndUI.cpp +++ b/Runtime/MP1/CFrontEndUI.cpp @@ -169,7 +169,7 @@ void CFrontEndUI::SNewFileSelectFrame::Update(float dt) else if (x8_subMenu != ESubMenu::Root) { ResetFrame(); - DeactivateExistingGamePopup(); + DeactivateEraseGamePopup(); DeactivateNewGamePopup(); x8_subMenu = ESubMenu::Root; } @@ -186,7 +186,7 @@ CFrontEndUI::SNewFileSelectFrame::ProcessUserInput(const CFinalInput& input, CFr { xc_action = EAction::None; - if (x8_subMenu != ESubMenu::ExistingGamePopup) + if (x8_subMenu != ESubMenu::EraseGamePopup) x4_saveUI->ProcessUserInput(input); if (IsTextDoneAnimating()) @@ -198,34 +198,69 @@ CFrontEndUI::SNewFileSelectFrame::ProcessUserInput(const CFinalInput& input, CFr if (x10c_saveReady) { x1c_loadedFrame->ProcessUserInput(input); - if (tbAction >= CFrontEndUITouchBar::EAction::FileA && - tbAction <= CFrontEndUITouchBar::EAction::ImageGallery) + if (x8_subMenu == ESubMenu::Root || x8_subMenu == ESubMenu::EraseGame) { - switch (tbAction) + if (m_touchBar.GetPhase() != CFrontEndUITouchBar::EPhase::FileSelect) + HandleActiveChange(x20_tablegroup_fileselect); + + if (tbAction >= CFrontEndUITouchBar::EAction::FileA && + tbAction <= CFrontEndUITouchBar::EAction::ImageGallery) { - case CFrontEndUITouchBar::EAction::FileA: - case CFrontEndUITouchBar::EAction::FileB: - case CFrontEndUITouchBar::EAction::FileC: x20_tablegroup_fileselect->SetUserSelection(int(tbAction) - int(CFrontEndUITouchBar::EAction::FileA)); - break; - case CFrontEndUITouchBar::EAction::FusionBonus: - case CFrontEndUITouchBar::EAction::ImageGallery: - x20_tablegroup_fileselect->SetUserSelection(int(tbAction) - int(CFrontEndUITouchBar::EAction::FusionBonus) + 4); - break; - default: break; + HandleActiveChange(x20_tablegroup_fileselect); + DoFileMenuAdvance(x20_tablegroup_fileselect); + } + else if (tbAction == CFrontEndUITouchBar::EAction::Back) + { + DoFileMenuCancel(x20_tablegroup_fileselect); + } + } + else if (x8_subMenu == ESubMenu::EraseGamePopup) + { + if (m_touchBar.GetPhase() != CFrontEndUITouchBar::EPhase::EraseBack) + HandleActiveChange(x40_tablegroup_popup); + + if (tbAction != CFrontEndUITouchBar::EAction::None) + { + if (tbAction == CFrontEndUITouchBar::EAction::Confirm) + x40_tablegroup_popup->SetUserSelection(1); + else + x40_tablegroup_popup->SetUserSelection(0); + HandleActiveChange(x40_tablegroup_popup); + DoPopupAdvance(x40_tablegroup_popup); + } + } + else if (x8_subMenu == ESubMenu::NewGamePopup) + { + if (m_touchBar.GetPhase() != CFrontEndUITouchBar::EPhase::StartOptions) + HandleActiveChange(x40_tablegroup_popup); + + if (tbAction == CFrontEndUITouchBar::EAction::Back) + { + DoPopupCancel(x40_tablegroup_popup); + } + else if (tbAction != CFrontEndUITouchBar::EAction::None) + { + if (tbAction == CFrontEndUITouchBar::EAction::Options) + x40_tablegroup_popup->SetUserSelection(1); + else if (tbAction == CFrontEndUITouchBar::EAction::Start || + tbAction == CFrontEndUITouchBar::EAction::Hard) + x40_tablegroup_popup->SetUserSelection(0); + else if (tbAction == CFrontEndUITouchBar::EAction::Normal) + x40_tablegroup_popup->SetUserSelection(2); + HandleActiveChange(x40_tablegroup_popup); + DoPopupAdvance(x40_tablegroup_popup); } - HandleActiveChange(x20_tablegroup_fileselect); - DoFileMenuAdvance(x20_tablegroup_fileselect); } } - if (x10d_needsExistingToggle) + if (x10d_needsEraseToggle) { if (x40_tablegroup_popup->GetIsActive()) - DeactivateExistingGamePopup(); + DeactivateEraseGamePopup(); else - ActivateExistingGamePopup(); - x10d_needsExistingToggle = false; + ActivateEraseGamePopup(); + x10d_needsEraseToggle = false; } if (x10e_needsNewToggle) @@ -273,9 +308,14 @@ void CFrontEndUI::SNewFileSelectFrame::HandleActiveChange(CGuiTableGroup* active m_touchBar.SetFileSelectPhase(tbDetails, x8_subMenu == ESubMenu::EraseGame, CSlideShow::SlideShowGalleryFlags()); } - else + else if (active == x40_tablegroup_popup) { - m_touchBar.SetPhase(CFrontEndUITouchBar::EPhase::None); + if (x8_subMenu == ESubMenu::EraseGamePopup) + m_touchBar.SetPhase(CFrontEndUITouchBar::EPhase::EraseBack); + else if (x8_subMenu == ESubMenu::NewGamePopup) + m_touchBar.SetStartOptionsPhase(g_GameState->SystemOptions().GetPlayerBeatNormalMode()); + else + m_touchBar.SetPhase(CFrontEndUITouchBar::EPhase::None); } if (x8_subMenu == ESubMenu::Root || x8_subMenu == ESubMenu::NewGamePopup) @@ -284,7 +324,7 @@ void CFrontEndUI::SNewFileSelectFrame::HandleActiveChange(CGuiTableGroup* active x24_model_erase->SetIsVisible(true); } -void CFrontEndUI::SNewFileSelectFrame::DeactivateExistingGamePopup() +void CFrontEndUI::SNewFileSelectFrame::DeactivateEraseGamePopup() { x40_tablegroup_popup->SetIsActive(false); x40_tablegroup_popup->SetIsVisible(false); @@ -296,7 +336,7 @@ void CFrontEndUI::SNewFileSelectFrame::DeactivateExistingGamePopup() x0_base->SetColor(zeus::CColor::skWhite); } -void CFrontEndUI::SNewFileSelectFrame::ActivateExistingGamePopup() +void CFrontEndUI::SNewFileSelectFrame::ActivateEraseGamePopup() { x40_tablegroup_popup->SetIsActive(true); x40_tablegroup_popup->SetIsVisible(true); @@ -305,7 +345,7 @@ void CFrontEndUI::SNewFileSelectFrame::ActivateExistingGamePopup() x40_tablegroup_popup->GetTransform()); x20_tablegroup_fileselect->SetIsActive(false); - x8_subMenu = ESubMenu::ExistingGamePopup; + x8_subMenu = ESubMenu::EraseGamePopup; HandleActiveChange(x40_tablegroup_popup); x48_textpane_popupadvance.SetPairText(g_MainStringTable->GetString(95)); @@ -545,11 +585,11 @@ void CFrontEndUI::SNewFileSelectFrame::SetupFrameContents() void CFrontEndUI::SNewFileSelectFrame::DoPopupCancel(CGuiTableGroup* caller) { - if (x8_subMenu == ESubMenu::ExistingGamePopup) + if (x8_subMenu == ESubMenu::EraseGamePopup) { CSfxManager::SfxStart(1094, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); x8_subMenu = ESubMenu::EraseGame; - x10d_needsExistingToggle = true; + x10d_needsEraseToggle = true; } else { @@ -561,7 +601,7 @@ void CFrontEndUI::SNewFileSelectFrame::DoPopupCancel(CGuiTableGroup* caller) void CFrontEndUI::SNewFileSelectFrame::DoPopupAdvance(CGuiTableGroup* caller) { - if (x8_subMenu == ESubMenu::ExistingGamePopup) + if (x8_subMenu == ESubMenu::EraseGamePopup) { if (x40_tablegroup_popup->GetUserSelection() == 1) { @@ -570,7 +610,7 @@ void CFrontEndUI::SNewFileSelectFrame::DoPopupAdvance(CGuiTableGroup* caller) } else x8_subMenu = ESubMenu::EraseGame; - x10d_needsExistingToggle = true; + x10d_needsEraseToggle = true; } else { @@ -582,8 +622,8 @@ void CFrontEndUI::SNewFileSelectFrame::DoPopupAdvance(CGuiTableGroup* caller) xc_action = EAction::GameOptions; return; } - g_GameState->SetHardMode(x20_tablegroup_fileselect->GetUserSelection()); - x4_saveUI->StartGame(x40_tablegroup_popup->GetUserSelection()); + g_GameState->SetHardMode(!x40_tablegroup_popup->GetUserSelection()); + x4_saveUI->StartGame(x20_tablegroup_fileselect->GetUserSelection()); } else { @@ -593,7 +633,7 @@ void CFrontEndUI::SNewFileSelectFrame::DoPopupAdvance(CGuiTableGroup* caller) xc_action = EAction::GameOptions; return; } - x4_saveUI->StartGame(x40_tablegroup_popup->GetUserSelection()); + x4_saveUI->StartGame(x20_tablegroup_fileselect->GetUserSelection()); } } } @@ -623,7 +663,7 @@ void CFrontEndUI::SNewFileSelectFrame::DoFileMenuAdvance(CGuiTableGroup* caller) if (x4_saveUI->GetGameData(userSel)) { PlayAdvanceSfx(); - x10d_needsExistingToggle = true; + x10d_needsEraseToggle = true; } } else @@ -669,7 +709,8 @@ void CFrontEndUI::SNewFileSelectFrame::StartTextAnimating(CGuiTextPane* text, co text->TextSupport()->SetTypeWriteEffectOptions(true, 0.1f, chRate); } -CFrontEndUI::SFusionBonusFrame::SFusionBonusFrame() +CFrontEndUI::SFusionBonusFrame::SFusionBonusFrame(CFrontEndUITouchBar& touchBar) +: m_touchBar(touchBar) { x4_gbaSupport = std::make_unique(); xc_gbaScreen = g_SimplePool->GetObj("FRME_GBAScreen"); @@ -816,7 +857,8 @@ static const CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::EUIType PrevLinkUI[] }; CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::EAction -CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::ProcessUserInput(const CFinalInput &input, bool linkInProgress) +CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::ProcessUserInput(const CFinalInput &input, bool linkInProgress, + CFrontEndUITouchBar::EAction tbAction) { if (linkInProgress != x40_linkInProgress) { @@ -833,12 +875,12 @@ CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::ProcessUserInput(const CFinalInpu case EUIType::LinkFailed: case EUIType::LinkCompleteOrLinking: case EUIType::TurnOffGBA: - if (input.PA()) + if (input.PA() || tbAction == CFrontEndUITouchBar::EAction::Confirm) { PlayAdvanceSfx(); SetUIText(NextLinkUI[int(x0_uiType)]); } - else if (input.PB()) + else if (input.PB() || tbAction == CFrontEndUITouchBar::EAction::Back) { EUIType prevUi = PrevLinkUI[int(x0_uiType)]; if (prevUi == EUIType::Empty) @@ -912,8 +954,8 @@ void CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::Draw() } CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::SGBALinkFrame(CGuiFrame* linkFrame, - CGBASupport* support, - bool linkInProgress) + CGBASupport* support, + bool linkInProgress) : x4_gbaSupport(support), x8_frme(linkFrame), x40_linkInProgress(linkInProgress) { support->InitializeSupport(); @@ -1030,7 +1072,8 @@ void CFrontEndUI::SFusionBonusFrame::Update(float dt, CSaveUI* saveUI) } CFrontEndUI::SFusionBonusFrame::EAction -CFrontEndUI::SFusionBonusFrame::ProcessUserInput(const CFinalInput& input, CSaveUI* sui) +CFrontEndUI::SFusionBonusFrame::ProcessUserInput(const CFinalInput& input, CSaveUI* sui, + CFrontEndUITouchBar::EAction tbAction) { x8_action = EAction::None; @@ -1041,7 +1084,10 @@ CFrontEndUI::SFusionBonusFrame::ProcessUserInput(const CFinalInput& input, CSave { if (x0_gbaLinkFrame) { - SGBALinkFrame::EAction action = x0_gbaLinkFrame->ProcessUserInput(input, sui); + if (m_touchBar.GetPhase() != CFrontEndUITouchBar::EPhase::ProceedBack) + m_touchBar.SetPhase(CFrontEndUITouchBar::EPhase::ProceedBack); + + SGBALinkFrame::EAction action = x0_gbaLinkFrame->ProcessUserInput(input, sui, tbAction); if (action != SGBALinkFrame::EAction::None) { x0_gbaLinkFrame.reset(); @@ -1057,7 +1103,51 @@ CFrontEndUI::SFusionBonusFrame::ProcessUserInput(const CFinalInput& input, CSave } else if (x24_loadedFrame) { + bool showFusionSuit = g_GameState->SystemOptions().GetPlayerLinkedFusion() && + g_GameState->SystemOptions().GetPlayerBeatNormalMode(); + if (m_touchBar.GetPhase() != CFrontEndUITouchBar::EPhase::FusionBonus) + { + m_touchBar.SetFusionBonusPhase(showFusionSuit && + g_GameState->SystemOptions().GetPlayerFusionSuitActive()); + } + x24_loadedFrame->ProcessUserInput(input); + + switch (tbAction) + { + case CFrontEndUITouchBar::EAction::NESMetroid: + x28_tablegroup_options->SetUserSelection(0); + ResetCompletionFlags(); + SetTableColors(x28_tablegroup_options); + DoAdvance(x28_tablegroup_options); + break; + case CFrontEndUITouchBar::EAction::FusionSuit: + x28_tablegroup_options->SetUserSelection(1); + ResetCompletionFlags(); + SetTableColors(x28_tablegroup_options); + if (showFusionSuit) + { + if (x2c_tablegroup_fusionsuit->GetUserSelection() == 1) + { + x2c_tablegroup_fusionsuit->SetUserSelection(0); + DoSelectionChange(x2c_tablegroup_fusionsuit, 0); + } + else + { + x2c_tablegroup_fusionsuit->SetUserSelection(1); + DoSelectionChange(x2c_tablegroup_fusionsuit, 1); + } + } + else + { + DoAdvance(x28_tablegroup_options); + } + break; + case CFrontEndUITouchBar::EAction::Back: + DoCancel(x28_tablegroup_options); + break; + default: break; + } } } @@ -1076,18 +1166,11 @@ void CFrontEndUI::SFusionBonusFrame::Draw() const void CFrontEndUI::SFusionBonusFrame::DoCancel(CGuiTableGroup* caller) { - if (x39_fusionNotComplete || x3a_mpNotComplete) - { - CSfxManager::SfxStart(1094, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); - } - else - { - x8_action = EAction::GoBack; - x28_tablegroup_options->SetUserSelection(0); - x2c_tablegroup_fusionsuit->SetIsActive(false); - x30_textpane_instructions.SetPairText(u""); - SetTableColors(x28_tablegroup_options); - } + x8_action = EAction::GoBack; + x28_tablegroup_options->SetUserSelection(0); + x2c_tablegroup_fusionsuit->SetIsActive(false); + x30_textpane_instructions.SetPairText(u""); + SetTableColors(x28_tablegroup_options); } void CFrontEndUI::SFusionBonusFrame::DoSelectionChange(CGuiTableGroup* caller, int userSel) @@ -1103,6 +1186,7 @@ void CFrontEndUI::SFusionBonusFrame::DoSelectionChange(CGuiTableGroup* caller, i bool fusionActive = x2c_tablegroup_fusionsuit->GetUserSelection() == 1; g_GameState->SystemOptions().SetPlayerFusionSuitActive(fusionActive); g_GameState->GetPlayerState()->SetIsFusionEnabled(fusionActive); + m_touchBar.SetFusionBonusPhase(g_GameState->SystemOptions().GetPlayerFusionSuitActive()); } SetTableColors(caller); } @@ -1244,10 +1328,40 @@ void CFrontEndUI::SFrontEndFrame::Update(float dt) } CFrontEndUI::SFrontEndFrame::EAction -CFrontEndUI::SFrontEndFrame::ProcessUserInput(const CFinalInput& input) +CFrontEndUI::SFrontEndFrame::ProcessUserInput(const CFinalInput& input, + CFrontEndUITouchBar::EAction tbAction) { + if (m_touchBar.GetPhase() != CFrontEndUITouchBar::EPhase::NoCardSelect) + m_touchBar.SetNoCardSelectPhase(CSlideShow::SlideShowGalleryFlags()); + x4_action = EAction::None; x14_loadedFrme->ProcessUserInput(input); + + switch (tbAction) + { + case CFrontEndUITouchBar::EAction::Start: + x18_tablegroup_mainmenu->SetUserSelection(0); + HandleActiveChange(x18_tablegroup_mainmenu); + DoAdvance(x18_tablegroup_mainmenu); + break; + case CFrontEndUITouchBar::EAction::FusionBonus: + x18_tablegroup_mainmenu->SetUserSelection(1); + HandleActiveChange(x18_tablegroup_mainmenu); + DoAdvance(x18_tablegroup_mainmenu); + break; + case CFrontEndUITouchBar::EAction::Options: + x18_tablegroup_mainmenu->SetUserSelection(2); + HandleActiveChange(x18_tablegroup_mainmenu); + DoAdvance(x18_tablegroup_mainmenu); + break; + case CFrontEndUITouchBar::EAction::ImageGallery: + x18_tablegroup_mainmenu->SetUserSelection(3); + HandleActiveChange(x18_tablegroup_mainmenu); + DoAdvance(x18_tablegroup_mainmenu); + break; + default: break; + } + return x4_action; } @@ -1297,8 +1411,8 @@ void CFrontEndUI::SFrontEndFrame::DoAdvance(CGuiTableGroup* caller) } } -CFrontEndUI::SFrontEndFrame::SFrontEndFrame(u32 rnd) -: x0_rnd(rnd) +CFrontEndUI::SFrontEndFrame::SFrontEndFrame(u32 rnd, CFrontEndUITouchBar& touchBar) +: x0_rnd(rnd), m_touchBar(touchBar) { x8_frme = g_SimplePool->GetObj("FRME_FrontEndPL"); } @@ -1488,6 +1602,7 @@ void CFrontEndUI::SOptionsFrontEndFrame::DoSliderChange(CGuiSliderGroup* caller, const auto& optionCategory = GameOptionsRegistry[leftSel]; const SGameOption& option = optionCategory.second[rightSel]; CGameOptions::SetOption(option.option, caller->GetGurVal()); + m_touchBarValueDirty = true; } } @@ -1526,6 +1641,7 @@ void CFrontEndUI::SOptionsFrontEndFrame::DoMenuSelectionChange(CGuiTableGroup* c const auto& optionCategory = GameOptionsRegistry[leftSel]; const SGameOption& option = optionCategory.second[rightSel]; CGameOptions::SetOption(option.option, caller->GetUserSelection()); + m_touchBarValueDirty = true; CSfxManager::SfxStart(1095, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); if (option.option == EGameOption::Rumble && caller->GetUserSelection() > 0) @@ -1720,6 +1836,7 @@ bool CFrontEndUI::SOptionsFrontEndFrame::PumpLoad() return false; x1c_loadedFrame = x4_frme.GetObj(); x20_loadedPauseStrg = x10_pauseScreen.GetObj(); + m_touchBar = NewGameOptionsTouchBar(); FinishedLoading(); return true; } @@ -1739,10 +1856,89 @@ bool CFrontEndUI::SOptionsFrontEndFrame::ProcessUserInput(const CFinalInput& inp else { x1c_loadedFrame->ProcessUserInput(input); - CGameOptions::TryRestoreDefaults(input, - x24_tablegroup_leftmenu->GetUserSelection(), - x28_tablegroup_rightmenu->GetUserSelection(), - true); + int leftSel = x24_tablegroup_leftmenu->GetUserSelection(); + int rightSel = x28_tablegroup_rightmenu->GetUserSelection(); + CGameOptions::TryRestoreDefaults(input, leftSel, rightSel, true, false); + + CGameOptionsTouchBar::EAction tbAction = m_touchBar->PopAction(); + if (x28_tablegroup_rightmenu->GetIsActive()) + { + if (tbAction == CGameOptionsTouchBar::EAction::Advance && !m_touchBarInValue) + { + int value; + m_touchBar->GetSelection(leftSel, rightSel, value); + x28_tablegroup_rightmenu->SetUserSelection(rightSel); + HandleRightSelectionChange(); + const auto& optionCategory = GameOptionsRegistry[leftSel]; + const SGameOption& option = optionCategory.second[rightSel]; + if (option.type != EOptionType::RestoreDefaults) + { + m_touchBarInValue = true; + m_touchBarValueDirty = true; + } + else + { + CGameOptions::TryRestoreDefaults(input, leftSel, rightSel, true, true); + } + } + else if (tbAction == CGameOptionsTouchBar::EAction::Back) + { + if (m_touchBarInValue) + m_touchBarInValue = false; + else + DoMenuCancel(x28_tablegroup_rightmenu); + } + else if (tbAction == CGameOptionsTouchBar::EAction::ValueChange) + { + int value; + m_touchBar->GetSelection(leftSel, rightSel, value); + const auto& optionCategory = GameOptionsRegistry[leftSel]; + const SGameOption& option = optionCategory.second[rightSel]; + CGameOptions::SetOption(option.option, value); + if (option.type != EOptionType::Float) + m_touchBarValueDirty = true; + HandleRightSelectionChange(); + } + else + { + if (m_touchBarInValue) + { + if (m_touchBarValueDirty) + { + const auto& optionCategory = GameOptionsRegistry[leftSel]; + const SGameOption& option = optionCategory.second[rightSel]; + int value = CGameOptions::GetOption(option.option); + m_touchBar->SetSelection(leftSel, rightSel, value); + m_touchBarValueDirty = false; + } + } + else + { + m_touchBar->SetSelection(leftSel, -1, -1); + } + } + } + else + { + if (tbAction == CGameOptionsTouchBar::EAction::Advance) + { + int value; + m_touchBar->GetSelection(leftSel, rightSel, value); + x24_tablegroup_leftmenu->SetUserSelection(leftSel); + SetTableColors(x24_tablegroup_leftmenu); + SetRightUIText(); + DoLeftMenuAdvance(x24_tablegroup_leftmenu); + } + if (tbAction == CGameOptionsTouchBar::EAction::Back) + { + x134_25_exitOptions = true; + CSfxManager::SfxStart(1094, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); + } + else + { + m_touchBar->SetSelection(-1, -1, -1); + } + } } } return !x134_25_exitOptions; @@ -2211,6 +2407,7 @@ void CFrontEndUI::ProcessUserInput(const CFinalInput& input, CArchitectureQueue& if (xf0_optionsFrme->ProcessUserInput(input, xdc_saveUI.get())) return; /* Exit options UI */ + m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None); xf0_optionsFrme.reset(); return; } @@ -2238,18 +2435,21 @@ void CFrontEndUI::ProcessUserInput(const CFinalInput& input, CArchitectureQueue& else { /* Control FrontEnd without memory card */ - switch (xe8_frontendNoCardFrme->ProcessUserInput(input)) + switch (xe8_frontendNoCardFrme->ProcessUserInput(input, touchBarAction)) { case SFrontEndFrame::EAction::FusionBonus: + m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None); StartStateTransition(EScreen::FusionBonus); return; case SFrontEndFrame::EAction::GameOptions: + m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None); xf0_optionsFrme = std::make_unique(); return; case SFrontEndFrame::EAction::StartGame: TransitionToGame(); return; case SFrontEndFrame::EAction::SlideShow: + m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None); xd2_deferSlideShow = true; StartSlideShow(queue); return; @@ -2260,12 +2460,14 @@ void CFrontEndUI::ProcessUserInput(const CFinalInput& input, CArchitectureQueue& else if (x50_curScreen == EScreen::FusionBonus && x54_nextScreen == EScreen::FusionBonus) { /* Control Fusion bonus UI */ - switch (xe4_fusionBonusFrme->ProcessUserInput(input, xdc_saveUI.get())) + switch (xe4_fusionBonusFrme->ProcessUserInput(input, xdc_saveUI.get(), touchBarAction)) { case SFusionBonusFrame::EAction::GoBack: + m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None); StartStateTransition(EScreen::FileSelect); return; case SFusionBonusFrame::EAction::PlayNESMetroid: + m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None); xf4_curAudio->StopMixing(); xec_emuFrme = std::make_unique(); if (xdc_saveUI) @@ -2287,6 +2489,7 @@ void CFrontEndUI::TransitionToGame() CSfxManager::SfxStart(sfx[1], 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); x14_phase = EPhase::ToPlayGame; + m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None); StartStateTransition(EScreen::ToPlayGame); } @@ -2347,8 +2550,8 @@ CIOWin::EMessageReturn CFrontEndUI::Update(float dt, CArchitectureQueue& queue) if (PumpLoad()) { xe0_frontendCardFrme = std::make_unique(xdc_saveUI.get(), x1c_rndB, *m_touchBar); - xe4_fusionBonusFrme = std::make_unique(); - xe8_frontendNoCardFrme = std::make_unique(x1c_rndB); + xe4_fusionBonusFrme = std::make_unique(*m_touchBar); + xe8_frontendNoCardFrme = std::make_unique(x1c_rndB, *m_touchBar); x38_pressStart.GetObj(); CAudioSys::AddAudioGroup(x44_frontendAudioGrp->GetAudioGroupData()); xd4_audio1 = std::make_unique("Audio/frontend_1.rsf", 416480, 1973664); diff --git a/Runtime/MP1/CFrontEndUI.hpp b/Runtime/MP1/CFrontEndUI.hpp index a5b5aee3b..818528dd6 100644 --- a/Runtime/MP1/CFrontEndUI.hpp +++ b/Runtime/MP1/CFrontEndUI.hpp @@ -14,6 +14,7 @@ #include "Graphics/Shaders/CTexturedQuadFilter.hpp" #include "Graphics/Shaders/CColoredQuadFilter.hpp" #include "CFrontEndUITouchBar.hpp" +#include "CGameOptionsTouchBar.hpp" namespace urde { @@ -106,7 +107,7 @@ public: { Root, EraseGame, - ExistingGamePopup, + EraseGamePopup, NewGamePopup }; @@ -140,7 +141,7 @@ public: float x104_rowPitch = 0.f; float x108_curTime = 0.f; bool x10c_saveReady = false; - bool x10d_needsExistingToggle = false; + bool x10d_needsEraseToggle = false; bool x10e_needsNewToggle = false; CFrontEndUITouchBar& m_touchBar; @@ -154,8 +155,8 @@ public: void Draw() const; void HandleActiveChange(CGuiTableGroup* active); - void DeactivateExistingGamePopup(); - void ActivateExistingGamePopup(); + void DeactivateEraseGamePopup(); + void ActivateEraseGamePopup(); void DeactivateNewGamePopup(); void ActivateNewGamePopup(); @@ -218,7 +219,8 @@ public: bool x40_linkInProgress; void SetUIText(EUIType tp); - EAction ProcessUserInput(const CFinalInput &input, bool linkInProgress); + EAction ProcessUserInput(const CFinalInput &input, bool linkInProgress, + CFrontEndUITouchBar::EAction tbAction); void Update(float dt); void FinishedLoading(); void Draw(); @@ -245,12 +247,15 @@ public: bool x39_fusionNotComplete = false; bool x3a_mpNotComplete = false; - SFusionBonusFrame(); + CFrontEndUITouchBar& m_touchBar; + + SFusionBonusFrame(CFrontEndUITouchBar& touchBar); void FinishedLoading(); bool PumpLoad(); void SetTableColors(CGuiTableGroup* tbgp) const; void Update(float dt, CSaveUI* saveUI); - EAction ProcessUserInput(const CFinalInput& input, CSaveUI* sui); + EAction ProcessUserInput(const CFinalInput& input, CSaveUI* sui, + CFrontEndUITouchBar::EAction tbAction); void Draw() const; void ResetCompletionFlags() @@ -282,11 +287,14 @@ public: CGuiTableGroup* x18_tablegroup_mainmenu = nullptr; SGuiTextPair x1c_gbaPair; SGuiTextPair x24_cheatPair; - SFrontEndFrame(u32 rnd); + + CFrontEndUITouchBar& m_touchBar; + + SFrontEndFrame(u32 rnd, CFrontEndUITouchBar& touchBar); void FinishedLoading(); bool PumpLoad(); void Update(float dt); - EAction ProcessUserInput(const CFinalInput& input); + EAction ProcessUserInput(const CFinalInput& input, CFrontEndUITouchBar::EAction tbAction); void Draw() const; void HandleActiveChange(CGuiTableGroup* active); @@ -344,6 +352,11 @@ public: bool x134_25_exitOptions : 1; }; }; + + std::unique_ptr m_touchBar; + bool m_touchBarInValue = false; + bool m_touchBarValueDirty = false; + SOptionsFrontEndFrame(); void DoSliderChange(CGuiSliderGroup* caller, float value); diff --git a/Runtime/MP1/CFrontEndUITouchBar.cpp b/Runtime/MP1/CFrontEndUITouchBar.cpp index 9254eddb1..08a14d685 100644 --- a/Runtime/MP1/CFrontEndUITouchBar.cpp +++ b/Runtime/MP1/CFrontEndUITouchBar.cpp @@ -4,9 +4,17 @@ namespace urde { CFrontEndUITouchBar::~CFrontEndUITouchBar() {} -void CFrontEndUITouchBar::SetPhase(EPhase ph) {} +void CFrontEndUITouchBar::SetPhase(EPhase ph) { m_phase = ph; } +CFrontEndUITouchBar::EPhase CFrontEndUITouchBar::GetPhase() { return m_phase; } void CFrontEndUITouchBar::SetFileSelectPhase(const SFileSelectDetail details[3], - bool eraseGame, bool galleryActive) {} + bool eraseGame, bool galleryActive) +{ m_phase = EPhase::FileSelect; } +void CFrontEndUITouchBar::SetNoCardSelectPhase(bool galleryActive) +{ m_phase = EPhase::NoCardSelect; } +void CFrontEndUITouchBar::SetFusionBonusPhase(bool fusionSuitActive) +{ m_phase = EPhase::FusionBonus; } +void CFrontEndUITouchBar::SetStartOptionsPhase(bool normalBeat) +{ m_phase = EPhase::StartOptions; } CFrontEndUITouchBar::EAction CFrontEndUITouchBar::PopAction() { return EAction::None; } #ifndef __APPLE__ diff --git a/Runtime/MP1/CFrontEndUITouchBar.hpp b/Runtime/MP1/CFrontEndUITouchBar.hpp index e87912ed6..81fde3640 100644 --- a/Runtime/MP1/CFrontEndUITouchBar.hpp +++ b/Runtime/MP1/CFrontEndUITouchBar.hpp @@ -13,20 +13,30 @@ public: { None, PressStart, - BackConfirm, - FileSelect + ProceedBack, + StartOptions, + EraseBack, + FileSelect, + NoCardSelect, + FusionBonus }; enum class EAction { None, Start, + Normal, + Hard, Back, Confirm, + Options, FileA, FileB, FileC, + Erase, FusionBonus, - ImageGallery + ImageGallery, + NESMetroid, + FusionSuit }; enum class EFileState { @@ -40,10 +50,18 @@ public: int percent; }; +protected: + EPhase m_phase = EPhase::None; + +public: virtual ~CFrontEndUITouchBar(); virtual void SetPhase(EPhase ph); + virtual EPhase GetPhase(); virtual void SetFileSelectPhase(const SFileSelectDetail details[3], bool eraseGame, bool galleryActive); + virtual void SetNoCardSelectPhase(bool galleryActive); + virtual void SetFusionBonusPhase(bool fusionSuitActive); + virtual void SetStartOptionsPhase(bool normalBeat); virtual EAction PopAction(); }; diff --git a/Runtime/MP1/CFrontEndUITouchBarMac.mm b/Runtime/MP1/CFrontEndUITouchBarMac.mm index aba0c9edb..211eb95f6 100644 --- a/Runtime/MP1/CFrontEndUITouchBarMac.mm +++ b/Runtime/MP1/CFrontEndUITouchBarMac.mm @@ -10,6 +10,34 @@ extern "C" uint8_t START_BUTTON_2X[]; extern "C" size_t START_BUTTON_2X_SZ; +static NSColor* BlueConfirm() +{ + return [NSColor colorWithSRGBRed:0/255.f green:130/255.f blue:215/255.f alpha:1.f]; +} + +static NSColor* NormalModeColor() +{ + return [NSColor colorWithSRGBRed:0/255.f green:130/255.f blue:0/255.f alpha:1.f]; +} + +static NSColor* HardModeColor() +{ + return [NSColor redColor]; +} + +static NSColor* FileColor(const urde::CFrontEndUITouchBar::SFileSelectDetail& detail) +{ + switch (detail.state) + { + case urde::CFrontEndUITouchBar::EFileState::New: + return [NSColor darkGrayColor]; + case urde::CFrontEndUITouchBar::EFileState::Normal: + return NormalModeColor(); + case urde::CFrontEndUITouchBar::EFileState::Hard: + return HardModeColor(); + } +} + @interface FrontEndUITouchBarPressStart : NSObject { @public @@ -34,24 +62,24 @@ extern "C" size_t START_BUTTON_2X_SZ; { if ([identifier isEqualToString:@"pressStartGroup"]) { - NSGroupTouchBarItem* group = [[NSGroupTouchBarItem alloc] initWithIdentifier:identifier]; + NSGroupTouchBarItem* item = [[NSGroupTouchBarItem alloc] initWithIdentifier:identifier]; NSTouchBar* touchBar = [NSTouchBar new]; touchBar.delegate = self; id items = @[@"pressStart"]; touchBar.customizationRequiredItemIdentifiers = items; touchBar.defaultItemIdentifiers = items; - group.groupTouchBar = touchBar; - return group; + item.groupTouchBar = touchBar; + return item; } else if ([identifier isEqualToString:@"pressStart"]) { NSData* imgData = [NSData dataWithBytesNoCopy:START_BUTTON_2X length:START_BUTTON_2X_SZ freeWhenDone:NO]; NSImage* img = [[NSImage alloc] initWithData:imgData]; - NSCustomTouchBarItem* pressStart = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; NSButton* button = [NSButton buttonWithTitle:@"Start" image:img target:self action:@selector(onPressStart:)]; button.imageHugsTitle = YES; - pressStart.view = button; - return pressStart; + item.view = button; + return item; } return nil; } @@ -61,6 +89,231 @@ extern "C" size_t START_BUTTON_2X_SZ; } @end +@interface FrontEndUITouchBarProceedBack : NSObject +{ +@public + urde::CFrontEndUITouchBar::EAction _action; +} +-(IBAction)onBack:(id)sender; +-(IBAction)onProceed:(id)sender; +@end + +@implementation FrontEndUITouchBarProceedBack +- (NSTouchBar*)makeTouchBar +{ + NSTouchBar* touchBar = [NSTouchBar new]; + touchBar.delegate = self; + id items = @[@"proceedBackGroup"]; + touchBar.customizationRequiredItemIdentifiers = items; + touchBar.defaultItemIdentifiers = items; + touchBar.principalItemIdentifier = @"proceedBackGroup"; + return touchBar; +} +-(NSTouchBarItem*)touchBar:(NSTouchBar*)touchBar + makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier +{ + if ([identifier isEqualToString:@"proceedBackGroup"]) + { + NSGroupTouchBarItem* item = [[NSGroupTouchBarItem alloc] initWithIdentifier:identifier]; + NSTouchBar* touchBar = [NSTouchBar new]; + touchBar.delegate = self; + id items = @[@"back", @"proceed"]; + touchBar.customizationRequiredItemIdentifiers = items; + touchBar.defaultItemIdentifiers = items; + item.groupTouchBar = touchBar; + return item; + } + else if ([identifier isEqualToString:@"back"]) + { + NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSButton* button = [NSButton buttonWithImage:[NSImage imageNamed:NSImageNameTouchBarGoBackTemplate] + target:self action:@selector(onBack:)]; + item.view = button; + return item; + } + else if ([identifier isEqualToString:@"proceed"]) + { + NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSButton* button = [NSButton buttonWithImage:[NSImage imageNamed:NSImageNameTouchBarGoForwardTemplate] + target:self action:@selector(onProceed:)]; + item.view = button; + return item; + } + return nil; +} +-(IBAction)onBack:(id)sender +{ + _action = urde::CFrontEndUITouchBar::EAction::Back; +} +-(IBAction)onProceed:(id)sender +{ + _action = urde::CFrontEndUITouchBar::EAction::Confirm; +} +@end + +@interface FrontEndUITouchBarStartOptions : NSObject +{ +@public + urde::CFrontEndUITouchBar::EAction _action; + BOOL _normalBeat; +} +-(IBAction)onStart:(id)sender; +-(IBAction)onNormal:(id)sender; +-(IBAction)onHard:(id)sender; +-(IBAction)onOptions:(id)sender; +-(IBAction)onCancel:(id)sender; +@end + +@implementation FrontEndUITouchBarStartOptions +- (NSTouchBar*)makeTouchBar +{ + NSTouchBar* touchBar = [NSTouchBar new]; + touchBar.delegate = self; + id items = @[@"startOptionsGroup"]; + touchBar.customizationRequiredItemIdentifiers = items; + touchBar.defaultItemIdentifiers = items; + touchBar.principalItemIdentifier = @"startOptionsGroup"; + return touchBar; +} +-(NSTouchBarItem*)touchBar:(NSTouchBar*)touchBar + makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier +{ + if ([identifier isEqualToString:@"startOptionsGroup"]) + { + NSGroupTouchBarItem* item = [[NSGroupTouchBarItem alloc] initWithIdentifier:identifier]; + NSTouchBar* touchBar = [NSTouchBar new]; + touchBar.delegate = self; + id items = _normalBeat ? @[@"cancel", @"normal", @"hard", @"options"] : + @[@"cancel", @"start", @"options"]; + touchBar.customizationRequiredItemIdentifiers = items; + touchBar.defaultItemIdentifiers = items; + item.groupTouchBar = touchBar; + return item; + } + else if ([identifier isEqualToString:@"start"]) + { + NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSButton* button = [NSButton buttonWithTitle:@"Start" target:self action:@selector(onStart:)]; + button.bezelColor = BlueConfirm(); + item.view = button; + return item; + } + else if ([identifier isEqualToString:@"normal"]) + { + NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSButton* button = [NSButton buttonWithTitle:@"Normal Mode" target:self action:@selector(onNormal:)]; + button.bezelColor = NormalModeColor(); + item.view = button; + return item; + } + else if ([identifier isEqualToString:@"hard"]) + { + NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSButton* button = [NSButton buttonWithTitle:@"Hard Mode" target:self action:@selector(onHard:)]; + button.bezelColor = HardModeColor(); + item.view = button; + return item; + } + else if ([identifier isEqualToString:@"options"]) + { + NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSButton* button = [NSButton buttonWithTitle:@"Options" target:self action:@selector(onOptions:)]; + item.view = button; + return item; + } + else if ([identifier isEqualToString:@"cancel"]) + { + NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSButton* button = [NSButton buttonWithImage:[NSImage imageNamed:NSImageNameTouchBarGoBackTemplate] + target:self action:@selector(onCancel:)]; + item.view = button; + return item; + } + return nil; +} +-(IBAction)onStart:(id)sender +{ + _action = urde::CFrontEndUITouchBar::EAction::Start; +} +-(IBAction)onNormal:(id)sender +{ + _action = urde::CFrontEndUITouchBar::EAction::Normal; +} +-(IBAction)onHard:(id)sender +{ + _action = urde::CFrontEndUITouchBar::EAction::Hard; +} +-(IBAction)onOptions:(id)sender +{ + _action = urde::CFrontEndUITouchBar::EAction::Options; +} +-(IBAction)onCancel:(id)sender +{ + _action = urde::CFrontEndUITouchBar::EAction::Back; +} +@end + +@interface FrontEndUITouchBarEraseBack : NSObject +{ +@public + urde::CFrontEndUITouchBar::EAction _action; +} +-(IBAction)onCancel:(id)sender; +-(IBAction)onErase:(id)sender; +@end + +@implementation FrontEndUITouchBarEraseBack +- (NSTouchBar*)makeTouchBar +{ + NSTouchBar* touchBar = [NSTouchBar new]; + touchBar.delegate = self; + id items = @[@"eraseBackGroup"]; + touchBar.customizationRequiredItemIdentifiers = items; + touchBar.defaultItemIdentifiers = items; + touchBar.principalItemIdentifier = @"eraseBackGroup"; + return touchBar; +} +-(NSTouchBarItem*)touchBar:(NSTouchBar*)touchBar + makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier +{ + if ([identifier isEqualToString:@"eraseBackGroup"]) + { + NSGroupTouchBarItem* item = [[NSGroupTouchBarItem alloc] initWithIdentifier:identifier]; + NSTouchBar* touchBar = [NSTouchBar new]; + touchBar.delegate = self; + id items = @[@"cancel", @"erase"]; + touchBar.customizationRequiredItemIdentifiers = items; + touchBar.defaultItemIdentifiers = items; + item.groupTouchBar = touchBar; + return item; + } + else if ([identifier isEqualToString:@"cancel"]) + { + NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSButton* button = [NSButton buttonWithTitle:@"Cancel" target:self action:@selector(onCancel:)]; + item.view = button; + return item; + } + else if ([identifier isEqualToString:@"erase"]) + { + NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSButton* button = [NSButton buttonWithTitle:@"Erase" target:self action:@selector(onErase:)]; + button.bezelColor = [NSColor redColor]; + item.view = button; + return item; + } + return nil; +} +-(IBAction)onCancel:(id)sender +{ + _action = urde::CFrontEndUITouchBar::EAction::Back; +} +-(IBAction)onErase:(id)sender +{ + _action = urde::CFrontEndUITouchBar::EAction::Confirm; +} +@end + static NSString* GetFileSelectTitle(const urde::CFrontEndUITouchBar::SFileSelectDetail& detail, char letter) { switch (detail.state) @@ -86,6 +339,7 @@ static NSString* GetFileSelectTitle(const urde::CFrontEndUITouchBar::SFileSelect -(IBAction)onFileA:(id)sender; -(IBAction)onFileB:(id)sender; -(IBAction)onFileC:(id)sender; +-(IBAction)onErase:(id)sender; -(IBAction)onFusionBonus:(id)sender; -(IBAction)onImageGallery:(id)sender; @end @@ -106,54 +360,82 @@ static NSString* GetFileSelectTitle(const urde::CFrontEndUITouchBar::SFileSelect { if ([identifier isEqualToString:@"fileSelectGroup"]) { - NSGroupTouchBarItem* group = [[NSGroupTouchBarItem alloc] initWithIdentifier:identifier]; + NSGroupTouchBarItem* item = [[NSGroupTouchBarItem alloc] initWithIdentifier:identifier]; NSTouchBar* touchBar = [NSTouchBar new]; touchBar.delegate = self; - id items = @[@"fileA", @"fileB", @"fileC", @"fusionBonus", @"imageGallery"]; + id items = @[@"fileA", @"fileB", @"fileC", @"erase", @"fusionBonus", @"imageGallery"]; touchBar.customizationRequiredItemIdentifiers = items; touchBar.defaultItemIdentifiers = items; - group.groupTouchBar = touchBar; - return group; + item.groupTouchBar = touchBar; + return item; } else if ([identifier isEqualToString:@"fileA"]) { - NSCustomTouchBarItem* pressStart = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; NSButton* button = [NSButton buttonWithTitle:GetFileSelectTitle(_details[0], 'A') target:self action:@selector(onFileA:)]; + button.bezelColor = FileColor(_details[0]); button.enabled = !_eraseGame || _details[0].state != urde::CFrontEndUITouchBar::EFileState::New; - pressStart.view = button; - return pressStart; + item.view = button; + return item; } else if ([identifier isEqualToString:@"fileB"]) { - NSCustomTouchBarItem* pressStart = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; NSButton* button = [NSButton buttonWithTitle:GetFileSelectTitle(_details[1], 'B') target:self action:@selector(onFileB:)]; + button.bezelColor = FileColor(_details[1]); button.enabled = !_eraseGame || _details[1].state != urde::CFrontEndUITouchBar::EFileState::New; - pressStart.view = button; - return pressStart; + item.view = button; + return item; } else if ([identifier isEqualToString:@"fileC"]) { - NSCustomTouchBarItem* pressStart = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; NSButton* button = [NSButton buttonWithTitle:GetFileSelectTitle(_details[2], 'C') target:self action:@selector(onFileC:)]; + button.bezelColor = FileColor(_details[2]); button.enabled = !_eraseGame || _details[2].state != urde::CFrontEndUITouchBar::EFileState::New; - pressStart.view = button; - return pressStart; + item.view = button; + return item; + } + else if ([identifier isEqualToString:@"erase"]) + { + NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + if (!_eraseGame) + { + NSButton* button = [NSButton buttonWithImage:[NSImage imageNamed:NSImageNameTouchBarDeleteTemplate] + target:self action:@selector(onErase:)]; + bool hasSave = false; + for (int i=0 ; i<3 ; ++i) + if (_details[i].state != urde::CFrontEndUITouchBar::EFileState::New) + { + hasSave = true; + break; + } + button.enabled = hasSave; + item.view = button; + } + else + { + NSButton* button = [NSButton buttonWithImage:[NSImage imageNamed:NSImageNameTouchBarGoBackTemplate] + target:self action:@selector(onErase:)]; + item.view = button; + } + return item; } else if ([identifier isEqualToString:@"fusionBonus"]) { - NSCustomTouchBarItem* pressStart = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton* button = [NSButton buttonWithTitle:@"Fusion Bonuses" target:self action:@selector(onFusionBonus:)]; + NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSButton* button = [NSButton buttonWithTitle:@"Bonuses" target:self action:@selector(onFusionBonus:)]; button.enabled = !_eraseGame; - pressStart.view = button; - return pressStart; + item.view = button; + return item; } else if ([identifier isEqualToString:@"imageGallery"]) { - NSCustomTouchBarItem* pressStart = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton* button = [NSButton buttonWithTitle:@"Image Gallery" target:self action:@selector(onImageGallery:)]; + NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSButton* button = [NSButton buttonWithTitle:@"Gallery" target:self action:@selector(onImageGallery:)]; button.enabled = !_eraseGame && _galleryActive; - pressStart.view = button; - return pressStart; + item.view = button; + return item; } return nil; } @@ -169,6 +451,13 @@ static NSString* GetFileSelectTitle(const urde::CFrontEndUITouchBar::SFileSelect { _action = urde::CFrontEndUITouchBar::EAction::FileC; } +-(IBAction)onErase:(id)sender +{ + if (!_eraseGame) + _action = urde::CFrontEndUITouchBar::EAction::Erase; + else + _action = urde::CFrontEndUITouchBar::EAction::Back; +} -(IBAction)onFusionBonus:(id)sender { _action = urde::CFrontEndUITouchBar::EAction::FusionBonus; @@ -179,14 +468,181 @@ static NSString* GetFileSelectTitle(const urde::CFrontEndUITouchBar::SFileSelect } @end +@interface FrontEndUITouchBarNoCardSelect : NSObject +{ +@public + urde::CFrontEndUITouchBar::EAction _action; + BOOL _galleryActive; +} +-(IBAction)onStart:(id)sender; +-(IBAction)onOptions:(id)sender; +-(IBAction)onFusionBonus:(id)sender; +-(IBAction)onImageGallery:(id)sender; +@end + +@implementation FrontEndUITouchBarNoCardSelect +- (NSTouchBar*)makeTouchBar +{ + NSTouchBar* touchBar = [NSTouchBar new]; + touchBar.delegate = self; + id items = @[@"noCardSelectGroup"]; + touchBar.customizationRequiredItemIdentifiers = items; + touchBar.defaultItemIdentifiers = items; + touchBar.principalItemIdentifier = @"noCardSelectGroup"; + return touchBar; +} +-(NSTouchBarItem*)touchBar:(NSTouchBar*)touchBar + makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier +{ + if ([identifier isEqualToString:@"noCardSelectGroup"]) + { + NSGroupTouchBarItem* item = [[NSGroupTouchBarItem alloc] initWithIdentifier:identifier]; + NSTouchBar* touchBar = [NSTouchBar new]; + touchBar.delegate = self; + id items = @[@"start", @"fusionBonus", @"options", @"imageGallery"]; + touchBar.customizationRequiredItemIdentifiers = items; + touchBar.defaultItemIdentifiers = items; + item.groupTouchBar = touchBar; + return item; + } + else if ([identifier isEqualToString:@"start"]) + { + NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSButton* button = [NSButton buttonWithTitle:@"Start" target:self action:@selector(onStart:)]; + button.bezelColor = BlueConfirm(); + item.view = button; + return item; + } + else if ([identifier isEqualToString:@"options"]) + { + NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSButton* button = [NSButton buttonWithTitle:@"Options" target:self action:@selector(onOptions:)]; + item.view = button; + return item; + } + else if ([identifier isEqualToString:@"fusionBonus"]) + { + NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSButton* button = [NSButton buttonWithTitle:@"Fusion Bonuses" target:self action:@selector(onFusionBonus:)]; + item.view = button; + return item; + } + else if ([identifier isEqualToString:@"imageGallery"]) + { + NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSButton* button = [NSButton buttonWithTitle:@"Image Gallery" target:self action:@selector(onImageGallery:)]; + button.enabled = _galleryActive; + item.view = button; + return item; + } + return nil; +} +-(IBAction)onStart:(id)sender +{ + _action = urde::CFrontEndUITouchBar::EAction::Start; +} +-(IBAction)onOptions:(id)sender +{ + _action = urde::CFrontEndUITouchBar::EAction::Options; +} +-(IBAction)onFusionBonus:(id)sender +{ + _action = urde::CFrontEndUITouchBar::EAction::FusionBonus; +} +-(IBAction)onImageGallery:(id)sender +{ + _action = urde::CFrontEndUITouchBar::EAction::ImageGallery; +} +@end + +@interface FrontEndUITouchBarFusionBonus : NSObject +{ +@public + urde::CFrontEndUITouchBar::EAction _action; + BOOL _fusionSuitActive; +} +-(IBAction)onNESMetroid:(id)sender; +-(IBAction)onFusionSuit:(id)sender; +-(IBAction)onBack:(id)sender; +@end + +@implementation FrontEndUITouchBarFusionBonus +- (NSTouchBar*)makeTouchBar +{ + NSTouchBar* touchBar = [NSTouchBar new]; + touchBar.delegate = self; + id items = @[@"fusionBonusGroup"]; + touchBar.customizationRequiredItemIdentifiers = items; + touchBar.defaultItemIdentifiers = items; + touchBar.principalItemIdentifier = @"fusionBonusGroup"; + return touchBar; +} +-(NSTouchBarItem*)touchBar:(NSTouchBar*)touchBar + makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier +{ + if ([identifier isEqualToString:@"fusionBonusGroup"]) + { + NSGroupTouchBarItem* item = [[NSGroupTouchBarItem alloc] initWithIdentifier:identifier]; + NSTouchBar* touchBar = [NSTouchBar new]; + touchBar.delegate = self; + id items = @[@"back", @"NESMetroid", @"fusionSuit"]; + touchBar.customizationRequiredItemIdentifiers = items; + touchBar.defaultItemIdentifiers = items; + item.groupTouchBar = touchBar; + return item; + } + else if ([identifier isEqualToString:@"NESMetroid"]) + { + NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSButton* button = [NSButton buttonWithTitle:@"Play NES Metroid" target:self action:@selector(onNESMetroid:)]; + item.view = button; + return item; + } + else if ([identifier isEqualToString:@"fusionSuit"]) + { + NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSButton* button = [NSButton buttonWithTitle:@"Fusion Suit" target:self action:@selector(onFusionSuit:)]; + if (_fusionSuitActive) + button.bezelColor = BlueConfirm(); + item.view = button; + return item; + } + else if ([identifier isEqualToString:@"back"]) + { + NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSButton* button = [NSButton buttonWithImage:[NSImage imageNamed:NSImageNameTouchBarGoBackTemplate] + target:self action:@selector(onBack:)]; + item.view = button; + return item; + } + return nil; +} +-(IBAction)onNESMetroid:(id)sender +{ + _action = urde::CFrontEndUITouchBar::EAction::NESMetroid; +} +-(IBAction)onFusionSuit:(id)sender +{ + _action = urde::CFrontEndUITouchBar::EAction::FusionSuit; +} +-(IBAction)onBack:(id)sender +{ + _action = urde::CFrontEndUITouchBar::EAction::Back; +} +@end + namespace urde { class CFrontEndUITouchBarMac : public CFrontEndUITouchBar { - EPhase m_phase = EPhase::None; FrontEndUITouchBarPressStart* m_pressStartBar; + FrontEndUITouchBarProceedBack* m_proceedBackBar; + FrontEndUITouchBarStartOptions* m_startOptions; + FrontEndUITouchBarEraseBack* m_eraseBack; FrontEndUITouchBarFileSelect* m_fileSelectBar; + FrontEndUITouchBarNoCardSelect* m_noCardSelectBar; + FrontEndUITouchBarFusionBonus* m_fusionBonusBar; void Activate() { @@ -196,9 +652,24 @@ class CFrontEndUITouchBarMac : public CFrontEndUITouchBar case EPhase::PressStart: provider = m_pressStartBar; break; + case EPhase::ProceedBack: + provider = m_proceedBackBar; + break; + case EPhase::StartOptions: + provider = m_startOptions; + break; + case EPhase::EraseBack: + provider = m_eraseBack; + break; case EPhase::FileSelect: provider = m_fileSelectBar; break; + case EPhase::NoCardSelect: + provider = m_noCardSelectBar; + break; + case EPhase::FusionBonus: + provider = m_fusionBonusBar; + break; default: break; } g_Main->GetMainWindow()->setTouchBarProvider((__bridge_retained void*)provider); @@ -208,13 +679,22 @@ public: CFrontEndUITouchBarMac() { m_pressStartBar = [FrontEndUITouchBarPressStart new]; + m_proceedBackBar = [FrontEndUITouchBarProceedBack new]; + m_startOptions = [FrontEndUITouchBarStartOptions new]; + m_eraseBack = [FrontEndUITouchBarEraseBack new]; m_fileSelectBar = [FrontEndUITouchBarFileSelect new]; + m_noCardSelectBar = [FrontEndUITouchBarNoCardSelect new]; + m_fusionBonusBar = [FrontEndUITouchBarFusionBonus new]; } void SetPhase(EPhase ph) { m_phase = ph; Activate(); } + EPhase GetPhase() + { + return m_phase; + } void SetFileSelectPhase(const SFileSelectDetail details[3], bool eraseGame, bool galleryActive) { m_fileSelectBar->_details[0] = details[0]; @@ -225,6 +705,24 @@ public: m_phase = EPhase::FileSelect; Activate(); } + void SetNoCardSelectPhase(bool galleryActive) + { + m_noCardSelectBar->_galleryActive = galleryActive; + m_phase = EPhase::NoCardSelect; + Activate(); + } + void SetFusionBonusPhase(bool fusionSuitActive) + { + m_fusionBonusBar->_fusionSuitActive = fusionSuitActive; + m_phase = EPhase::FusionBonus; + Activate(); + } + void SetStartOptionsPhase(bool normalBeat) + { + m_startOptions->_normalBeat = normalBeat; + m_phase = EPhase::StartOptions; + Activate(); + } EAction PopAction() { switch (m_phase) @@ -236,6 +734,30 @@ public: return EAction::Start; } break; + case EPhase::ProceedBack: + if (m_proceedBackBar->_action != EAction::None) + { + EAction action = m_proceedBackBar->_action; + m_proceedBackBar->_action = EAction::None; + return action; + } + break; + case EPhase::StartOptions: + if (m_startOptions->_action != EAction::None) + { + EAction action = m_startOptions->_action; + m_startOptions->_action = EAction::None; + return action; + } + break; + case EPhase::EraseBack: + if (m_eraseBack->_action != EAction::None) + { + EAction action = m_eraseBack->_action; + m_eraseBack->_action = EAction::None; + return action; + } + break; case EPhase::FileSelect: if (m_fileSelectBar->_action != EAction::None) { @@ -244,6 +766,22 @@ public: return action; } break; + case EPhase::NoCardSelect: + if (m_noCardSelectBar->_action != EAction::None) + { + EAction action = m_noCardSelectBar->_action; + m_noCardSelectBar->_action = EAction::None; + return action; + } + break; + case EPhase::FusionBonus: + if (m_fusionBonusBar->_action != EAction::None) + { + EAction action = m_fusionBonusBar->_action; + m_fusionBonusBar->_action = EAction::None; + return action; + } + break; default: break; } return EAction::None; diff --git a/hecl b/hecl index 4ab6eab56..42e21ac92 160000 --- a/hecl +++ b/hecl @@ -1 +1 @@ -Subproject commit 4ab6eab5641b4f77e187e602d812db4c43be8106 +Subproject commit 42e21ac921790c0fa5e63068f4564849a597c9ac