From 3f03ba79500fca4efb06ef62a1cd3b6db470931e Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Wed, 8 Feb 2017 23:23:17 -1000 Subject: [PATCH] Implement key FrontEnd Touch Bar functionality --- Editor/ViewManager.cpp | 10 +- Runtime/CMakeLists.txt | 7 + Runtime/IMain.hpp | 6 +- Runtime/MP1/CFrontEndUI.cpp | 87 +++++++-- Runtime/MP1/CFrontEndUI.hpp | 9 +- Runtime/MP1/CFrontEndUITouchBar.cpp | 19 ++ Runtime/MP1/CFrontEndUITouchBar.hpp | 54 ++++++ Runtime/MP1/CFrontEndUITouchBarMac.mm | 258 ++++++++++++++++++++++++++ Runtime/MP1/CMakeLists.txt | 6 + Runtime/MP1/MP1.cpp | 10 +- Runtime/MP1/MP1.hpp | 7 +- Runtime/Resources/startButton@2x.png | Bin 0 -> 4608 bytes hecl | 2 +- 13 files changed, 443 insertions(+), 32 deletions(-) create mode 100644 Runtime/MP1/CFrontEndUITouchBar.cpp create mode 100644 Runtime/MP1/CFrontEndUITouchBar.hpp create mode 100644 Runtime/MP1/CFrontEndUITouchBarMac.mm create mode 100644 Runtime/Resources/startButton@2x.png diff --git a/Editor/ViewManager.cpp b/Editor/ViewManager.cpp index cac2e9ca8..dc9697a16 100644 --- a/Editor/ViewManager.cpp +++ b/Editor/ViewManager.cpp @@ -80,7 +80,7 @@ void ViewManager::BuildTestPART(urde::IObjectStore& objStore) void ViewManager::InitMP1(MP1::CMain& main) { - main.Init(m_fileStoreManager, m_voiceEngine.get(), *m_amuseAllocWrapper); + main.Init(m_fileStoreManager, m_mainWindow.get(), m_voiceEngine.get(), *m_amuseAllocWrapper); } void ViewManager::TestGameView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) @@ -363,14 +363,6 @@ void ViewManager::init(boo::IApplication* app) break; } } - - /* - CGraphics::InitializeBoo(gf, m_mainWindow->getCommandQueue(), root->renderTex()); - CModelShaders::Initialize(m_fileStoreManager, gf); - CElementGen::Initialize(); - CMoviePlayer::Initialize(); - CLineRenderer::Initialize(); - */ } bool ViewManager::proc() diff --git a/Runtime/CMakeLists.txt b/Runtime/CMakeLists.txt index 344946a83..7a20254c4 100644 --- a/Runtime/CMakeLists.txt +++ b/Runtime/CMakeLists.txt @@ -39,6 +39,13 @@ add_subdirectory(MP1) add_subdirectory(MP2) add_subdirectory(MP3) +if(APPLE) + set_source_files_properties(MP1/CFrontEndUITouchBarMac.mm + PROPERTIES COMPILE_FLAGS -fobjc-arc) + bintoc(startButton.c Resources/startButton@2x.png START_BUTTON_2X) + list(APPEND PLAT_SRCS startButton.c) +endif() + add_library(RuntimeCommon RetroTypes.hpp RetroTypes.cpp ${CLIENT_SOURCES} diff --git a/Runtime/IMain.hpp b/Runtime/IMain.hpp index fa3702fe9..bbd1c9314 100644 --- a/Runtime/IMain.hpp +++ b/Runtime/IMain.hpp @@ -34,11 +34,13 @@ class IMain public: virtual ~IMain() = default; virtual void Init(const hecl::Runtime::FileStoreManager& storeMgr, - boo::IAudioVoiceEngine* voiceEngine, - amuse::IBackendVoiceAllocator& backend)=0; + boo::IWindow* window, + boo::IAudioVoiceEngine* voiceEngine, + amuse::IBackendVoiceAllocator& backend)=0; virtual void Draw()=0; virtual bool Proc()=0; virtual void Shutdown()=0; + virtual boo::IWindow* GetMainWindow() const=0; }; } diff --git a/Runtime/MP1/CFrontEndUI.cpp b/Runtime/MP1/CFrontEndUI.cpp index c1a41fd16..533427995 100644 --- a/Runtime/MP1/CFrontEndUI.cpp +++ b/Runtime/MP1/CFrontEndUI.cpp @@ -74,8 +74,8 @@ void CFrontEndUI::PlayAdvanceSfx() CSfxManager::SfxStart(1091, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); } -CFrontEndUI::SNewFileSelectFrame::SNewFileSelectFrame(CSaveUI* sui, u32 rnd) -: x0_rnd(rnd), x4_saveUI(sui) +CFrontEndUI::SNewFileSelectFrame::SNewFileSelectFrame(CSaveUI* sui, u32 rnd, CFrontEndUITouchBar& touchBar) +: x0_rnd(rnd), x4_saveUI(sui), m_touchBar(touchBar) { x10_frme = g_SimplePool->GetObj("FRME_NewFileSelect"); } @@ -182,7 +182,7 @@ void CFrontEndUI::SNewFileSelectFrame::Update(float dt) } CFrontEndUI::SNewFileSelectFrame::EAction -CFrontEndUI::SNewFileSelectFrame::ProcessUserInput(const CFinalInput& input) +CFrontEndUI::SNewFileSelectFrame::ProcessUserInput(const CFinalInput& input, CFrontEndUITouchBar::EAction tbAction) { xc_action = EAction::None; @@ -196,7 +196,28 @@ CFrontEndUI::SNewFileSelectFrame::ProcessUserInput(const CFinalInput& input) return xc_action; if (x10c_saveReady) + { x1c_loadedFrame->ProcessUserInput(input); + if (tbAction >= CFrontEndUITouchBar::EAction::FileA && + tbAction <= CFrontEndUITouchBar::EAction::ImageGallery) + { + switch (tbAction) + { + 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); + } + } if (x10d_needsExistingToggle) { @@ -234,9 +255,29 @@ void CFrontEndUI::SNewFileSelectFrame::HandleActiveChange(CGuiTableGroup* active zeus::CColor{0.627450f, 0.627450f, 0.627450f, 0.784313f}); if (active == x20_tablegroup_fileselect) + { x24_model_erase->SetLocalTransform(zeus::CTransform::Translate( 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)) + { + 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()); + } + else + { + m_touchBar.SetPhase(CFrontEndUITouchBar::EPhase::None); + } + if (x8_subMenu == ESubMenu::Root || x8_subMenu == ESubMenu::NewGamePopup) x24_model_erase->SetIsVisible(false); else @@ -356,19 +397,20 @@ void CFrontEndUI::SNewFileSelectFrame::ActivateErase() x28_textpane_erase.x0_panes[0]->TextSupport()->SetFontColor(color); x38_textpane_gba.x0_panes[0]->TextSupport()->SetFontColor(color); x30_textpane_cheats.x0_panes[0]->TextSupport()->SetFontColor(color); + x38_textpane_gba.x0_panes[0]->SetIsSelectable(false); + x30_textpane_cheats.x0_panes[0]->SetIsSelectable(false); for (int i=2 ; i>=0 ; --i) { SFileMenuOption& fileOpt = x64_fileSelections[i]; - const CGameState::GameFileStateInfo* data = x4_saveUI->GetGameData(i); - if (data) + if (x4_saveUI->GetGameData(i)) { - fileOpt.x4_textpanes[0].x0_panes[0]->SetIsSelectable(true); + fileOpt.x0_base->SetIsSelectable(true); x20_tablegroup_fileselect->SetUserSelection(i); } else { - fileOpt.x4_textpanes[0].x0_panes[0]->SetIsSelectable(false); + fileOpt.x0_base->SetIsSelectable(false); } } @@ -577,8 +619,7 @@ void CFrontEndUI::SNewFileSelectFrame::DoFileMenuAdvance(CGuiTableGroup* caller) { if (x8_subMenu == ESubMenu::EraseGame) { - const CGameState::GameFileStateInfo* data = x4_saveUI->GetGameData(userSel); - if (data) + if (x4_saveUI->GetGameData(userSel)) { PlayAdvanceSfx(); x10d_needsExistingToggle = true; @@ -586,9 +627,11 @@ void CFrontEndUI::SNewFileSelectFrame::DoFileMenuAdvance(CGuiTableGroup* caller) } else { - const CGameState::GameFileStateInfo* data = x4_saveUI->GetGameData(userSel); - if (data) + if (x4_saveUI->GetGameData(userSel)) + { + m_touchBar.SetPhase(CFrontEndUITouchBar::EPhase::None); x4_saveUI->StartGame(userSel); + } else x10e_needsNewToggle = true; } @@ -1760,6 +1803,9 @@ CFrontEndUI::CFrontEndUI() for (int i=0 ; CDvdFile::FileExists(GetAttractMovieFileName(i).c_str()) ; ++i) ++xc0_attractCount; + + m_touchBar = NewFrontEndUITouchBar(); + m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None); } void CFrontEndUI::StartSlideShow(CArchitectureQueue& queue) @@ -2113,9 +2159,13 @@ void CFrontEndUI::ProcessUserInput(const CFinalInput& input, CArchitectureQueue& if (x14_phase != EPhase::DisplayFrontEnd || input.ControllerIdx() != 0) return; + /* Pop most recent action from Touch Bar */ + CFrontEndUITouchBar::EAction touchBarAction = m_touchBar->PopAction(); + if (x50_curScreen != x54_nextScreen) { - if (x54_nextScreen == EScreen::AttractMovie && (input.PStart() || input.PA())) + if (x54_nextScreen == EScreen::AttractMovie && (input.PStart() || input.PA() || + touchBarAction == CFrontEndUITouchBar::EAction::Start)) { /* Player wants to return to opening credits from attract movie */ SetFadeBlackTimer(std::min(1.f, x58_fadeBlackTimer)); @@ -2123,7 +2173,7 @@ void CFrontEndUI::ProcessUserInput(const CFinalInput& input, CArchitectureQueue& return; } - if (input.PA() || input.PStart()) + if (input.PA() || input.PStart() || touchBarAction == CFrontEndUITouchBar::EAction::Start) { if (x50_curScreen == EScreen::OpenCredits && x54_nextScreen == EScreen::Title && x58_fadeBlackTimer > 1.f) @@ -2139,13 +2189,14 @@ void CFrontEndUI::ProcessUserInput(const CFinalInput& input, CArchitectureQueue& { if (x50_curScreen == EScreen::Title) { - if (input.PStart() || input.PA()) + if (input.PStart() || input.PA() || touchBarAction == CFrontEndUITouchBar::EAction::Start) { if (x58_fadeBlackTimer < 30.f - g_tweakGame->GetPressStartDelay()) { /* Proceed to file select UI */ CSfxManager::SfxStart(FETransitionBackSFX[x18_rndA][0], 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); CSfxManager::SfxStart(FETransitionBackSFX[x18_rndA][1], 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); + m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None); StartStateTransition(EScreen::FileSelect); return; } @@ -2165,15 +2216,18 @@ void CFrontEndUI::ProcessUserInput(const CFinalInput& input, CArchitectureQueue& else if (xe0_frontendCardFrme) { /* Control FrontEnd with memory card */ - switch (xe0_frontendCardFrme->ProcessUserInput(input)) + switch (xe0_frontendCardFrme->ProcessUserInput(input, touchBarAction)) { case SNewFileSelectFrame::EAction::FusionBonus: + m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None); StartStateTransition(EScreen::FusionBonus); return; case SNewFileSelectFrame::EAction::GameOptions: + m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None); xf0_optionsFrme = std::make_unique(); return; case SNewFileSelectFrame::EAction::SlideShow: + m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None); xd2_deferSlideShow = true; StartSlideShow(queue); return; @@ -2291,7 +2345,7 @@ CIOWin::EMessageReturn CFrontEndUI::Update(float dt, CArchitectureQueue& queue) /* Poll loading DGRP resources */ if (PumpLoad()) { - xe0_frontendCardFrme = std::make_unique(xdc_saveUI.get(), x1c_rndB); + xe0_frontendCardFrme = std::make_unique(xdc_saveUI.get(), x1c_rndB, *m_touchBar); xe4_fusionBonusFrme = std::make_unique(); xe8_frontendNoCardFrme = std::make_unique(x1c_rndB); x38_pressStart.GetObj(); @@ -2337,6 +2391,7 @@ CIOWin::EMessageReturn CFrontEndUI::Update(float dt, CArchitectureQueue& queue) { /* Ready to display FrontEnd */ x14_phase = EPhase::DisplayFrontEnd; + m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::PressStart); StartStateTransition(EScreen::Title); } else diff --git a/Runtime/MP1/CFrontEndUI.hpp b/Runtime/MP1/CFrontEndUI.hpp index 480a3546c..a5b5aee3b 100644 --- a/Runtime/MP1/CFrontEndUI.hpp +++ b/Runtime/MP1/CFrontEndUI.hpp @@ -13,6 +13,7 @@ #include "GuiSys/CGuiTextSupport.hpp" #include "Graphics/Shaders/CTexturedQuadFilter.hpp" #include "Graphics/Shaders/CColoredQuadFilter.hpp" +#include "CFrontEndUITouchBar.hpp" namespace urde { @@ -142,12 +143,14 @@ public: bool x10d_needsExistingToggle = false; bool x10e_needsNewToggle = false; - SNewFileSelectFrame(CSaveUI* sui, u32 rnd); + CFrontEndUITouchBar& m_touchBar; + + SNewFileSelectFrame(CSaveUI* sui, u32 rnd, CFrontEndUITouchBar& touchBar); void FinishedLoading(); bool PumpLoad(); bool IsTextDoneAnimating() const; void Update(float dt); - EAction ProcessUserInput(const CFinalInput& input); + EAction ProcessUserInput(const CFinalInput& input, CFrontEndUITouchBar::EAction tbAction); void Draw() const; void HandleActiveChange(CGuiTableGroup* active); @@ -408,6 +411,8 @@ private: CColoredQuadFilter m_fadeToBlack = {CCameraFilterPass::EFilterType::Blend}; std::experimental::optional m_pressStartQuad; + std::unique_ptr m_touchBar; + void SetFadeBlackWithMovie() { x58_fadeBlackTimer = 1000000.f; diff --git a/Runtime/MP1/CFrontEndUITouchBar.cpp b/Runtime/MP1/CFrontEndUITouchBar.cpp new file mode 100644 index 000000000..9254eddb1 --- /dev/null +++ b/Runtime/MP1/CFrontEndUITouchBar.cpp @@ -0,0 +1,19 @@ +#include "CFrontEndUITouchBar.hpp" + +namespace urde +{ + +CFrontEndUITouchBar::~CFrontEndUITouchBar() {} +void CFrontEndUITouchBar::SetPhase(EPhase ph) {} +void CFrontEndUITouchBar::SetFileSelectPhase(const SFileSelectDetail details[3], + bool eraseGame, bool galleryActive) {} +CFrontEndUITouchBar::EAction CFrontEndUITouchBar::PopAction() { return EAction::None; } + +#ifndef __APPLE__ +std::unique_ptr NewFrontEndUITouchBar() +{ + return std::make_unique(); +} +#endif + +} diff --git a/Runtime/MP1/CFrontEndUITouchBar.hpp b/Runtime/MP1/CFrontEndUITouchBar.hpp new file mode 100644 index 000000000..e87912ed6 --- /dev/null +++ b/Runtime/MP1/CFrontEndUITouchBar.hpp @@ -0,0 +1,54 @@ +#ifndef __URDE_CFRONTENDUITOUCHBAR_HPP__ +#define __URDE_CFRONTENDUITOUCHBAR_HPP__ + +#include + +namespace urde +{ + +class CFrontEndUITouchBar +{ +public: + enum class EPhase + { + None, + PressStart, + BackConfirm, + FileSelect + }; + enum class EAction + { + None, + Start, + Back, + Confirm, + FileA, + FileB, + FileC, + FusionBonus, + ImageGallery + }; + enum class EFileState + { + New, + Normal, + Hard + }; + struct SFileSelectDetail + { + EFileState state; + int percent; + }; + + virtual ~CFrontEndUITouchBar(); + virtual void SetPhase(EPhase ph); + virtual void SetFileSelectPhase(const SFileSelectDetail details[3], + bool eraseGame, bool galleryActive); + virtual EAction PopAction(); +}; + +std::unique_ptr NewFrontEndUITouchBar(); + +} + +#endif // __URDE_CFRONTENDUITOUCHBAR_HPP__ diff --git a/Runtime/MP1/CFrontEndUITouchBarMac.mm b/Runtime/MP1/CFrontEndUITouchBarMac.mm new file mode 100644 index 000000000..aba0c9edb --- /dev/null +++ b/Runtime/MP1/CFrontEndUITouchBarMac.mm @@ -0,0 +1,258 @@ +#include +#include "CFrontEndUITouchBar.hpp" +#include "GameGlobalObjects.hpp" +#include "MP1/MP1.hpp" + +#if !__has_feature(objc_arc) +#error ARC Required +#endif + +extern "C" uint8_t START_BUTTON_2X[]; +extern "C" size_t START_BUTTON_2X_SZ; + +@interface FrontEndUITouchBarPressStart : NSObject +{ +@public + BOOL _startPressed; +} +-(IBAction)onPressStart:(id)sender; +@end + +@implementation FrontEndUITouchBarPressStart +- (NSTouchBar*)makeTouchBar +{ + NSTouchBar* touchBar = [NSTouchBar new]; + touchBar.delegate = self; + id items = @[@"pressStartGroup"]; + touchBar.customizationRequiredItemIdentifiers = items; + touchBar.defaultItemIdentifiers = items; + touchBar.principalItemIdentifier = @"pressStartGroup"; + return touchBar; +} +-(NSTouchBarItem*)touchBar:(NSTouchBar*)touchBar + makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier +{ + if ([identifier isEqualToString:@"pressStartGroup"]) + { + NSGroupTouchBarItem* group = [[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; + } + 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]; + NSButton* button = [NSButton buttonWithTitle:@"Start" image:img target:self action:@selector(onPressStart:)]; + button.imageHugsTitle = YES; + pressStart.view = button; + return pressStart; + } + return nil; +} +-(IBAction)onPressStart:(id)sender +{ + _startPressed = YES; +} +@end + +static NSString* GetFileSelectTitle(const urde::CFrontEndUITouchBar::SFileSelectDetail& detail, char letter) +{ + switch (detail.state) + { + case urde::CFrontEndUITouchBar::EFileState::New: + return [NSString stringWithFormat:@"[New Game %c]", letter]; + case urde::CFrontEndUITouchBar::EFileState::Normal: + return [NSString stringWithFormat:@"[Samus %c] %d%%", letter, detail.percent]; + case urde::CFrontEndUITouchBar::EFileState::Hard: + return [NSString stringWithFormat:@"[Hard %c] %d%%", letter, detail.percent]; + } + return @""; +} + +@interface FrontEndUITouchBarFileSelect : NSObject +{ +@public + urde::CFrontEndUITouchBar::SFileSelectDetail _details[3]; + urde::CFrontEndUITouchBar::EAction _action; + BOOL _eraseGame; + BOOL _galleryActive; +} +-(IBAction)onFileA:(id)sender; +-(IBAction)onFileB:(id)sender; +-(IBAction)onFileC:(id)sender; +-(IBAction)onFusionBonus:(id)sender; +-(IBAction)onImageGallery:(id)sender; +@end + +@implementation FrontEndUITouchBarFileSelect +- (NSTouchBar*)makeTouchBar +{ + NSTouchBar* touchBar = [NSTouchBar new]; + touchBar.delegate = self; + id items = @[@"fileSelectGroup"]; + touchBar.customizationRequiredItemIdentifiers = items; + touchBar.defaultItemIdentifiers = items; + touchBar.principalItemIdentifier = @"fileSelectGroup"; + return touchBar; +} +-(NSTouchBarItem*)touchBar:(NSTouchBar*)touchBar + makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier +{ + if ([identifier isEqualToString:@"fileSelectGroup"]) + { + NSGroupTouchBarItem* group = [[NSGroupTouchBarItem alloc] initWithIdentifier:identifier]; + NSTouchBar* touchBar = [NSTouchBar new]; + touchBar.delegate = self; + id items = @[@"fileA", @"fileB", @"fileC", @"fusionBonus", @"imageGallery"]; + touchBar.customizationRequiredItemIdentifiers = items; + touchBar.defaultItemIdentifiers = items; + group.groupTouchBar = touchBar; + return group; + } + else if ([identifier isEqualToString:@"fileA"]) + { + NSCustomTouchBarItem* pressStart = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSButton* button = [NSButton buttonWithTitle:GetFileSelectTitle(_details[0], 'A') target:self action:@selector(onFileA:)]; + button.enabled = !_eraseGame || _details[0].state != urde::CFrontEndUITouchBar::EFileState::New; + pressStart.view = button; + return pressStart; + } + else if ([identifier isEqualToString:@"fileB"]) + { + NSCustomTouchBarItem* pressStart = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSButton* button = [NSButton buttonWithTitle:GetFileSelectTitle(_details[1], 'B') target:self action:@selector(onFileB:)]; + button.enabled = !_eraseGame || _details[1].state != urde::CFrontEndUITouchBar::EFileState::New; + pressStart.view = button; + return pressStart; + } + else if ([identifier isEqualToString:@"fileC"]) + { + NSCustomTouchBarItem* pressStart = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSButton* button = [NSButton buttonWithTitle:GetFileSelectTitle(_details[2], 'C') target:self action:@selector(onFileC:)]; + button.enabled = !_eraseGame || _details[2].state != urde::CFrontEndUITouchBar::EFileState::New; + pressStart.view = button; + return pressStart; + } + else if ([identifier isEqualToString:@"fusionBonus"]) + { + NSCustomTouchBarItem* pressStart = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSButton* button = [NSButton buttonWithTitle:@"Fusion Bonuses" target:self action:@selector(onFusionBonus:)]; + button.enabled = !_eraseGame; + pressStart.view = button; + return pressStart; + } + else if ([identifier isEqualToString:@"imageGallery"]) + { + NSCustomTouchBarItem* pressStart = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSButton* button = [NSButton buttonWithTitle:@"Image Gallery" target:self action:@selector(onImageGallery:)]; + button.enabled = !_eraseGame && _galleryActive; + pressStart.view = button; + return pressStart; + } + return nil; +} +-(IBAction)onFileA:(id)sender +{ + _action = urde::CFrontEndUITouchBar::EAction::FileA; +} +-(IBAction)onFileB:(id)sender +{ + _action = urde::CFrontEndUITouchBar::EAction::FileB; +} +-(IBAction)onFileC:(id)sender +{ + _action = urde::CFrontEndUITouchBar::EAction::FileC; +} +-(IBAction)onFusionBonus:(id)sender +{ + _action = urde::CFrontEndUITouchBar::EAction::FusionBonus; +} +-(IBAction)onImageGallery:(id)sender +{ + _action = urde::CFrontEndUITouchBar::EAction::ImageGallery; +} +@end + +namespace urde +{ + +class CFrontEndUITouchBarMac : public CFrontEndUITouchBar +{ + EPhase m_phase = EPhase::None; + FrontEndUITouchBarPressStart* m_pressStartBar; + FrontEndUITouchBarFileSelect* m_fileSelectBar; + + void Activate() + { + id provider = nil; + switch (m_phase) + { + case EPhase::PressStart: + provider = m_pressStartBar; + break; + case EPhase::FileSelect: + provider = m_fileSelectBar; + break; + default: break; + } + g_Main->GetMainWindow()->setTouchBarProvider((__bridge_retained void*)provider); + } + +public: + CFrontEndUITouchBarMac() + { + m_pressStartBar = [FrontEndUITouchBarPressStart new]; + m_fileSelectBar = [FrontEndUITouchBarFileSelect new]; + } + void SetPhase(EPhase ph) + { + m_phase = ph; + Activate(); + } + void SetFileSelectPhase(const SFileSelectDetail details[3], bool eraseGame, bool galleryActive) + { + m_fileSelectBar->_details[0] = details[0]; + m_fileSelectBar->_details[1] = details[1]; + m_fileSelectBar->_details[2] = details[2]; + m_fileSelectBar->_eraseGame = eraseGame; + m_fileSelectBar->_galleryActive = galleryActive; + m_phase = EPhase::FileSelect; + Activate(); + } + EAction PopAction() + { + switch (m_phase) + { + case EPhase::PressStart: + if (m_pressStartBar->_startPressed) + { + m_pressStartBar->_startPressed = NO; + return EAction::Start; + } + break; + case EPhase::FileSelect: + if (m_fileSelectBar->_action != EAction::None) + { + EAction action = m_fileSelectBar->_action; + m_fileSelectBar->_action = EAction::None; + return action; + } + break; + default: break; + } + return EAction::None; + } +}; + +std::unique_ptr NewFrontEndUITouchBar() +{ + return std::make_unique(); +} + +} diff --git a/Runtime/MP1/CMakeLists.txt b/Runtime/MP1/CMakeLists.txt index 925da93e9..95d8b2b6f 100644 --- a/Runtime/MP1/CMakeLists.txt +++ b/Runtime/MP1/CMakeLists.txt @@ -1,6 +1,10 @@ include_directories(. ..) add_subdirectory(World) +if(APPLE) + set(MP1_PLAT_SOURCES CFrontEndUITouchBarMac.mm) +endif() + set(MP1_SOURCES CTweaks.hpp CTweaks.cpp CInGameTweakManager.hpp CInGameTweakManager.cpp @@ -10,6 +14,7 @@ set(MP1_SOURCES CMFGame.hpp CMFGame.cpp CPlayMovie.hpp CPlayMovie.cpp CFrontEndUI.hpp CFrontEndUI.cpp + CFrontEndUITouchBar.hpp CFrontEndUITouchBar.cpp CPreFrontEnd.hpp CPreFrontEnd.cpp CSlideShow.hpp CSlideShow.cpp CSaveUI.hpp CSaveUI.cpp @@ -19,6 +24,7 @@ set(MP1_SOURCES CStateSetterFlow.hpp CStateSetterFlow.cpp CAudioStateWin.hpp CAudioStateWin.cpp MP1.hpp MP1.cpp + ${MP1_PLAT_SOURCES} ${MP1_WORLD_SOURCES}) runtime_add_list(MP1 MP1_SOURCES) diff --git a/Runtime/MP1/MP1.cpp b/Runtime/MP1/MP1.cpp index 53d53f700..0414ceb63 100644 --- a/Runtime/MP1/MP1.cpp +++ b/Runtime/MP1/MP1.cpp @@ -29,7 +29,8 @@ URDE_DECL_SPECIALIZE_MULTI_BLEND_SHADER(CTextSupportShader) namespace MP1 { -CGameArchitectureSupport::CGameArchitectureSupport(CMain& parent, boo::IAudioVoiceEngine* voiceEngine, +CGameArchitectureSupport::CGameArchitectureSupport(CMain& parent, + boo::IAudioVoiceEngine* voiceEngine, amuse::IBackendVoiceAllocator& backend) : m_parent(parent), x0_audioSys(voiceEngine, backend, 0,0,0,0,0), @@ -254,9 +255,11 @@ void CMain::StreamNewGameState(CBitStreamReader& r, u32 idx) } void CMain::Init(const hecl::Runtime::FileStoreManager& storeMgr, + boo::IWindow* window, boo::IAudioVoiceEngine* voiceEngine, amuse::IBackendVoiceAllocator& backend) { + m_mainWindow = window; InitializeSubsystems(storeMgr); x128_globalObjects.PostInitialize(); x70_tweaks.RegisterTweaks(); @@ -320,6 +323,11 @@ void CMain::Shutdown() TMultiBlendShader::Shutdown(); } +boo::IWindow* CMain::GetMainWindow() const +{ + return m_mainWindow; +} + #if MP1_USE_BOO int CMain::appMain(boo::IApplication* app) diff --git a/Runtime/MP1/MP1.hpp b/Runtime/MP1/MP1.hpp index 2702bb1dd..c49691149 100644 --- a/Runtime/MP1/MP1.hpp +++ b/Runtime/MP1/MP1.hpp @@ -134,7 +134,8 @@ class CGameArchitectureSupport } public: - CGameArchitectureSupport(CMain& parent, boo::IAudioVoiceEngine* voiceEngine, + CGameArchitectureSupport(CMain& parent, + boo::IAudioVoiceEngine* voiceEngine, amuse::IBackendVoiceAllocator& backend); ~CGameArchitectureSupport(); @@ -235,6 +236,8 @@ private: std::unique_ptr x164_archSupport; + boo::IWindow* m_mainWindow = nullptr; + void InitializeSubsystems(const hecl::Runtime::FileStoreManager& storeMgr); public: @@ -249,11 +252,13 @@ public: //int RsMain(int argc, const boo::SystemChar* argv[]); void Init(const hecl::Runtime::FileStoreManager& storeMgr, + boo::IWindow* window, boo::IAudioVoiceEngine* voiceEngine, amuse::IBackendVoiceAllocator& backend); bool Proc(); void Draw(); void Shutdown(); + boo::IWindow* GetMainWindow() const; void MemoryCardInitializePump() { diff --git a/Runtime/Resources/startButton@2x.png b/Runtime/Resources/startButton@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..82635d81913e74ffffc70e034976a51ef931fcc5 GIT binary patch literal 4608 zcmZ`-c|4R|8y+HMO(aC7u~x&_X)vY67P1aASx1d^#>fnVB9vqeH4`IC_H8isHQEp@ z_C1R1*(;LeqxXHkx3BMgpWp91=bY=luKPasea`vgdBTh@>2R29yS z*ADF8eM2_~Ja;<=f~n4VK;c`Vncc}j4_y=i0ASYi5}p{8){KjphK4UjXD=mCX5NF(BGbLI?0RvscR zFTKlZbhMn_^U3C zzHl@V1Cy7PQ<0XHmzGsEmzRag%0uPk)gixe{?72H`hq70O~iYeQ1BEsavHIT$`Wh?!AGr?(XPc zcM!(PhRoW%z8tH1a7}Y(=6Na#`>5wg^P)AV)4>zBGY%S`in)x) zi{m5nd8Lz2nIrD9z%!riBkzLY;oZjNvn$3FzFa(cCB~eld*ZN|xN6uq_!72RziE8= z^IYHP&RYY%yAoHf2XB0E;~bS&7_HwSY&%s?MaZ#T(cH%-h-_~R-p{94oEpT;aYI|s zV^;lMvgFB{!nw~Q^=hiBs_WH6sQ=l%p?X{V!{%|+N7c9C4s`x8)#qC#ebUhrt08FE z^@odfmG19rx>&f5zjnsm(0NB_OS4)P{K|MkxV zfIuj9adwssI(P0Id#a(#Lxo)PRW+)U~d zN3V*4f*ennLBgw7dZZgSh6O}YWFJC|sLqOh6~Ccn%Yd&Iw+EeRiVX13BB>0QcFfG9+y;k+3}g=}@^^P4BY4T;$alQ4 z>YxwR*b%WfJq6*gcm=1o@!R*#dKz(YLY>|v%ZZAnOC%Uqf8EXh}CYnhaQOBEi<0PxkuqTPgcXiA(@UR8ko{J17_NHPo2RPaI42xb& zjm*x@`mx6>6x!6jPQMrMbfD^*Xn>$R6Ig%9LBO7GF0=E@eFIFY2cMhfgaPF`>i(-q z1Ins34FA-TATXV*Vq4T)Rw*t2xHpDnAS{v+61H;-3nNc3ZG3BwLyvoUe_pRc(H%l;GDLTnasXH5&j3yxb^=J8`yPk+ zKHMV$EVJcm=vcH?!LuUOSYEFB-frye7(g!!RK4Q1pCnxiWy#LUvK^|x4c!mr61lVr zKwajlnThAfq)`&yu@ze$JpT^&z6L=NAB8zUQM|t0oysf-g}_M3E(vZUGy}0CC9An`w~s% z&IRv2RrZqD#QE+XWPZEq8!eR(dQ z&)6VBk}*9;iv9b8_OVbtC^tx+lOCuhWdB%teor;uf)?Cl>o!1?F!Ix*dWdoMS23Rw zA-`nSru3vKwT5<97eqaPky@v2+n)p+Z8_A~39txCv-7Kmh2EV9aWcQP5#eO7ON!Ti z9`h1b+`98(>++pjUK$rJTzF>;FA$xNf0L-9mfuoYQeYa%Xsk$8eE3|Br>TT4P|&E6 z=m&0hJ2B#OG05>aQ~L{0^Lo@chhX2b<~0Y#Za!y(tFUkqCv%vKtNVifo#$u!OP%f& zceBVwcq~?pM;`|*l6nhm+?28XA4Uc$qc;WZIgbu%j{7tjpa%{(Y>@-KXj*vo<&E0R z!=`RcDZ)j|K3h$5Zi=v*Jbespya>lQ3dN#paB#N5^mX8uA>*1pnaK^EfZ04pHXh)& z7*;>`hAr>4h1x!~c^vK=dPO6XI^)d9CW)n*c%=1ic3&-R_!y)az_X-c_E?E$cvE?W ztvHROFZIcIsj7R*ZE33hLGo9+tch%Ydwpc@W(Wk(&y5DqYkqznhP+2rtn5kI%iSZGlAs@`|%XE@ql%Z8^P3;?;o1ak6 zi`EoI$&IGN86t_^D_+cQC*KyfvX$TBFwA;Pf4N@AaIE7<%Y#D3r>Wy>n*K#=0TpTf zUJM4gl}fy>HpAtfnY9kzS@Wb&53M7-Fg;9x6V0Vx2QH&h8>iP)V&dSqNZm0Cxoak) zPS|d(>eI3oQwz@^8{_BY@047t4qbA3tmH(?&CXLB+*-4y1y%C&EnAHpmiz&o zAI3h1SksB%e2&oGH0|>VHu^4t=CtE(j0Qb)>)7_iwIQPD&MN?NsOqBm6Ecx9W*(`U z+ACuaYh}^1Xw(gqjcnOHFMY3a#QeuuaRV9Qe|ehR(N^q^HFJvuJ{ zaV%5VNeCx%DRw{H34Pi`@5!wli=?yw*O<`>)s^uq!$v2W7+?B^k@j337d&cV zcvJ}$pEd?6SDYAEOuWs6FluM4P$F;>YFQ&Qaqnqq6<-pZ^5b=13EyUZzREG-|S!=h+HkIA#b!2z&T$X~K!mZBqjsr(*pP8bz z+1goKb^ukblBE)CrN?|l+O(&yNK+rh%W^zT{hA3DBt>MLdXRS~5hwjVxIa_%M9Pu= zurPhBCS<6@^n2x_I7K&JUyG~PSA?GvuM zj<>zlenEfW%zjW!%BQ+I!iRa@L_j5TSO?e49TZ)YBmE7O)2wdM)bn?tVC4Ln6VH@5& zYF*{iA@F=~Ry{+PdznAzs$clDKn35su#t*T>z*X!P*i9^mSTFN>Kpxv$Bz{p?Ndi1 z*}3E_3xvo;5r+7s3^QFsF_q@}mk4K^5^b{>>rrkoF;jjN+vF3eP9` zwCf1XKK6Ktgw-!yMw0ged=xKnuV5g${Cx2=Ki)>HW+R36*=n%L?N;F;LVLnGqPN{^ zrtT`@WssQGTTEk;npz`U`4z_x-PaW40>T=}FIG-TuTG>4PHjg<+`4NJV0N*G9jUNn zF%ngw^W&b7Y6*W0u0vx&r_pLo0%aWc3>bSCrQgzk6K?{2wPe&e+@%yqYdlb|(JcW? zFhJ&q*JQK6Dk#E2>S(jrQ|k4uCvVZDX1Ty05pa&V#NY`v%3)|PRGqkgIXg%hynS@z znVt0$Z1vESocAtRY)M2%t>}P^?sHmo=9{u|X=U1Dt*p%Qs4XIowB-nw-M|=~)^+TT zdJ+$BX7G86kbnRP#B~kknr4nTMJ%KjM2zv~aLT<=iP3}G7ZF?w@v4QM^LIo>m$Dva zRn9CfE`Icyw41(-ofKF7us+336urtkps)~dbue7B{I z%$(LM+Q%g^d32WQ;0kw>x$@e^g3@@yqnm6dBRwpXaUnc(k`c*Oo_bH@?1H= z(v?|XrA|>!reIGiD>qB(K2Tiak7*gd>B~OTM$1r!{Ejmx4!0dKZAU$*P%H5qP3XJb zTjH(Ll!3XqBbj|xo0rUNaqJ7V*_y$PaWT1aMBePjTBV4Z_va}hD49WZYaAH#TK{Or z1tv?&^R;<#i!(XbH%`woUk-8)8Ic;aOvjF)LpM>d6EUp-vdR7*PK9>xveQ&Drbs>8 zQ@%O9T+u({4i{|wLt^`)FL*fL;!xm3t6;P#Ih+Y)ZCJ@jp>3M6)XTEi98A@?T)aWE z?tuYr3XfeCS0-Zs2HsyC@ChsEBoV9G~IQ@E3yaptZI z!3!kKDHZ_z$hp%D!>{7hs@*5A`(+=ac=(5nbAQr+2WH2DL4j#Yh|o!g!t{~ABAd`; zY3>Q}!JPFrouvHeqwyD)Ov=c1vzI}E8#iqECf5Gv8*6DNFKCCM=d(eMUFLe`-ftN_ MtxNF2^Y+320SYlN>;M1& literal 0 HcmV?d00001 diff --git a/hecl b/hecl index 532fd0ede..4ab6eab56 160000 --- a/hecl +++ b/hecl @@ -1 +1 @@ -Subproject commit 532fd0ede4078a0c3cf88868a53932a46f575676 +Subproject commit 4ab6eab5641b4f77e187e602d812db4c43be8106