Implement CGameOptionsTouchBar

This commit is contained in:
Jack Andersen 2017-02-09 23:00:57 -10:00
parent c806f4a612
commit 17d986bb43
17 changed files with 1255 additions and 111 deletions

View File

@ -382,7 +382,7 @@ void CGameOptions::EnsureSettings()
} }
void CGameOptions::TryRestoreDefaults(const CFinalInput& input, int category, void CGameOptions::TryRestoreDefaults(const CFinalInput& input, int category,
int option, bool frontend) int option, bool frontend, bool forceRestore)
{ {
const std::pair<int, const SGameOption*>& options = GameOptionsRegistry[category]; const std::pair<int, const SGameOption*>& options = GameOptionsRegistry[category];
if (!options.first) if (!options.first)
@ -391,7 +391,7 @@ void CGameOptions::TryRestoreDefaults(const CFinalInput& input, int category,
if (options.second[option].option != EGameOption::RestoreDefaults) if (options.second[option].option != EGameOption::RestoreDefaults)
return; return;
if (!input.PA()) if (!forceRestore && !input.PA())
return; return;
if (frontend) if (frontend)

View File

@ -173,7 +173,7 @@ public:
void ResetControllerAssets(); void ResetControllerAssets();
static void TryRestoreDefaults(const CFinalInput& input, int category, 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 void SetOption(EGameOption option, int value);
static int GetOption(EGameOption option); static int GetOption(EGameOption option);
}; };

View File

@ -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<CGameOptionsTouchBar> NewGameOptionsTouchBar()
{
return std::make_unique<CGameOptionsTouchBar>();
}
#endif
}

View File

@ -0,0 +1,31 @@
#ifndef __URDE_CGAMEOPTIONSTOUCHBAR_HPP__
#define __URDE_CGAMEOPTIONSTOUCHBAR_HPP__
#include <utility>
#include <memory>
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<CGameOptionsTouchBar> NewGameOptionsTouchBar();
}
#endif // __URDE_CGAMEOPTIONSTOUCHBAR_HPP__

View File

@ -0,0 +1,307 @@
#include <AppKit/AppKit.h>
#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 <NSTouchBarDelegate>
{
@public
urde::CStringTable* _pauseScreenStrg;
urde::CGameOptionsTouchBar::EAction _action;
std::pair<int, int> _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<int, const urde::SGameOption*>& opt = urde::GameOptionsRegistry[_selection.first];
items = [NSMutableArray arrayWithCapacity:opt.first+1];
[items addObject:@"back"];
for (int i=0 ; i<opt.first ; ++i)
[items addObject:[NSString stringWithFormat:@"right/%d", i]];
}
else
{
const std::pair<int, const urde::SGameOption*>& 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<int, const urde::SGameOption*>& 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<int, const urde::SGameOption*>& 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<NSString*>* 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<int, const urde::SGameOption*>& 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<CStringTable> 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<CGameOptionsTouchBar> NewGameOptionsTouchBar()
{
return std::make_unique<CGameOptionsTouchBarMac>();
}
}

View File

@ -41,9 +41,10 @@ add_subdirectory(MP3)
if(APPLE) if(APPLE)
set_source_files_properties(MP1/CFrontEndUITouchBarMac.mm set_source_files_properties(MP1/CFrontEndUITouchBarMac.mm
CGameOptionsTouchBarMac.mm
PROPERTIES COMPILE_FLAGS -fobjc-arc) PROPERTIES COMPILE_FLAGS -fobjc-arc)
bintoc(startButton.c Resources/startButton@2x.png START_BUTTON_2X) 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() endif()
add_library(RuntimeCommon add_library(RuntimeCommon
@ -85,6 +86,7 @@ add_library(RuntimeCommon
IObjectStore.hpp IObjectStore.hpp
CSimplePool.hpp CSimplePool.cpp CSimplePool.hpp CSimplePool.cpp
CGameOptions.hpp CGameOptions.cpp CGameOptions.hpp CGameOptions.cpp
CGameOptionsTouchBar.hpp CGameOptionsTouchBar.cpp
CStaticInterference.hpp CStaticInterference.hpp
CCRC32.hpp CCRC32.cpp CCRC32.hpp CCRC32.cpp
IFactory.hpp IFactory.hpp

View File

@ -610,6 +610,7 @@ void CBooModel::UpdateUniformData(const CModelFlags& flags,
lightingOut.colorRegs[0] = flags.regColors[0]; lightingOut.colorRegs[0] = flags.regColors[0];
lightingOut.colorRegs[1] = flags.regColors[1]; lightingOut.colorRegs[1] = flags.regColors[1];
lightingOut.colorRegs[2] = flags.regColors[2]; lightingOut.colorRegs[2] = flags.regColors[2];
lightingOut.mulColor = flags.color;
lightingOut.fog = CGraphics::g_Fog; lightingOut.fog = CGraphics::g_Fog;
} }

View File

@ -37,6 +37,7 @@ public:
Light lights[URDE_MAX_LIGHTS]; Light lights[URDE_MAX_LIGHTS];
zeus::CColor ambient; zeus::CColor ambient;
zeus::CColor colorRegs[3]; zeus::CColor colorRegs[3];
zeus::CColor mulColor;
CGraphics::CFogState fog; CGraphics::CFogState fog;
}; };

View File

@ -27,6 +27,7 @@ static const char* LightingGLSL =
" vec4 colorReg0;\n" " vec4 colorReg0;\n"
" vec4 colorReg1;\n" " vec4 colorReg1;\n"
" vec4 colorReg2;\n" " vec4 colorReg2;\n"
" vec4 mulColor;\n"
" Fog fog;\n" " Fog fog;\n"
"};\n" "};\n"
"\n" "\n"

View File

@ -26,6 +26,7 @@ static const char* LightingHLSL =
" float4 colorReg0;\n" " float4 colorReg0;\n"
" float4 colorReg1;\n" " float4 colorReg1;\n"
" float4 colorReg2;\n" " float4 colorReg2;\n"
" float4 mulColor;\n"
" Fog fog;\n" " Fog fog;\n"
"};\n" "};\n"
"\n" "\n"

View File

@ -26,6 +26,7 @@ static const char* LightingMetal =
" float4 colorReg0;\n" " float4 colorReg0;\n"
" float4 colorReg1;\n" " float4 colorReg1;\n"
" float4 colorReg2;\n" " float4 colorReg2;\n"
" float4 mulColor;\n"
" Fog fog;\n" " Fog fog;\n"
"};\n" "};\n"
"\n" "\n"

View File

@ -169,7 +169,7 @@ void CFrontEndUI::SNewFileSelectFrame::Update(float dt)
else if (x8_subMenu != ESubMenu::Root) else if (x8_subMenu != ESubMenu::Root)
{ {
ResetFrame(); ResetFrame();
DeactivateExistingGamePopup(); DeactivateEraseGamePopup();
DeactivateNewGamePopup(); DeactivateNewGamePopup();
x8_subMenu = ESubMenu::Root; x8_subMenu = ESubMenu::Root;
} }
@ -186,7 +186,7 @@ CFrontEndUI::SNewFileSelectFrame::ProcessUserInput(const CFinalInput& input, CFr
{ {
xc_action = EAction::None; xc_action = EAction::None;
if (x8_subMenu != ESubMenu::ExistingGamePopup) if (x8_subMenu != ESubMenu::EraseGamePopup)
x4_saveUI->ProcessUserInput(input); x4_saveUI->ProcessUserInput(input);
if (IsTextDoneAnimating()) if (IsTextDoneAnimating())
@ -198,34 +198,69 @@ CFrontEndUI::SNewFileSelectFrame::ProcessUserInput(const CFinalInput& input, CFr
if (x10c_saveReady) if (x10c_saveReady)
{ {
x1c_loadedFrame->ProcessUserInput(input); x1c_loadedFrame->ProcessUserInput(input);
if (tbAction >= CFrontEndUITouchBar::EAction::FileA && if (x8_subMenu == ESubMenu::Root || x8_subMenu == ESubMenu::EraseGame)
tbAction <= CFrontEndUITouchBar::EAction::ImageGallery)
{ {
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)); x20_tablegroup_fileselect->SetUserSelection(int(tbAction) - int(CFrontEndUITouchBar::EAction::FileA));
break; HandleActiveChange(x20_tablegroup_fileselect);
case CFrontEndUITouchBar::EAction::FusionBonus: DoFileMenuAdvance(x20_tablegroup_fileselect);
case CFrontEndUITouchBar::EAction::ImageGallery: }
x20_tablegroup_fileselect->SetUserSelection(int(tbAction) - int(CFrontEndUITouchBar::EAction::FusionBonus) + 4); else if (tbAction == CFrontEndUITouchBar::EAction::Back)
break; {
default: break; 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()) if (x40_tablegroup_popup->GetIsActive())
DeactivateExistingGamePopup(); DeactivateEraseGamePopup();
else else
ActivateExistingGamePopup(); ActivateEraseGamePopup();
x10d_needsExistingToggle = false; x10d_needsEraseToggle = false;
} }
if (x10e_needsNewToggle) if (x10e_needsNewToggle)
@ -273,9 +308,14 @@ void CFrontEndUI::SNewFileSelectFrame::HandleActiveChange(CGuiTableGroup* active
m_touchBar.SetFileSelectPhase(tbDetails, x8_subMenu == ESubMenu::EraseGame, m_touchBar.SetFileSelectPhase(tbDetails, x8_subMenu == ESubMenu::EraseGame,
CSlideShow::SlideShowGalleryFlags()); 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) if (x8_subMenu == ESubMenu::Root || x8_subMenu == ESubMenu::NewGamePopup)
@ -284,7 +324,7 @@ void CFrontEndUI::SNewFileSelectFrame::HandleActiveChange(CGuiTableGroup* active
x24_model_erase->SetIsVisible(true); x24_model_erase->SetIsVisible(true);
} }
void CFrontEndUI::SNewFileSelectFrame::DeactivateExistingGamePopup() void CFrontEndUI::SNewFileSelectFrame::DeactivateEraseGamePopup()
{ {
x40_tablegroup_popup->SetIsActive(false); x40_tablegroup_popup->SetIsActive(false);
x40_tablegroup_popup->SetIsVisible(false); x40_tablegroup_popup->SetIsVisible(false);
@ -296,7 +336,7 @@ void CFrontEndUI::SNewFileSelectFrame::DeactivateExistingGamePopup()
x0_base->SetColor(zeus::CColor::skWhite); x0_base->SetColor(zeus::CColor::skWhite);
} }
void CFrontEndUI::SNewFileSelectFrame::ActivateExistingGamePopup() void CFrontEndUI::SNewFileSelectFrame::ActivateEraseGamePopup()
{ {
x40_tablegroup_popup->SetIsActive(true); x40_tablegroup_popup->SetIsActive(true);
x40_tablegroup_popup->SetIsVisible(true); x40_tablegroup_popup->SetIsVisible(true);
@ -305,7 +345,7 @@ void CFrontEndUI::SNewFileSelectFrame::ActivateExistingGamePopup()
x40_tablegroup_popup->GetTransform()); x40_tablegroup_popup->GetTransform());
x20_tablegroup_fileselect->SetIsActive(false); x20_tablegroup_fileselect->SetIsActive(false);
x8_subMenu = ESubMenu::ExistingGamePopup; x8_subMenu = ESubMenu::EraseGamePopup;
HandleActiveChange(x40_tablegroup_popup); HandleActiveChange(x40_tablegroup_popup);
x48_textpane_popupadvance.SetPairText(g_MainStringTable->GetString(95)); x48_textpane_popupadvance.SetPairText(g_MainStringTable->GetString(95));
@ -545,11 +585,11 @@ void CFrontEndUI::SNewFileSelectFrame::SetupFrameContents()
void CFrontEndUI::SNewFileSelectFrame::DoPopupCancel(CGuiTableGroup* caller) 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); CSfxManager::SfxStart(1094, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
x8_subMenu = ESubMenu::EraseGame; x8_subMenu = ESubMenu::EraseGame;
x10d_needsExistingToggle = true; x10d_needsEraseToggle = true;
} }
else else
{ {
@ -561,7 +601,7 @@ void CFrontEndUI::SNewFileSelectFrame::DoPopupCancel(CGuiTableGroup* caller)
void CFrontEndUI::SNewFileSelectFrame::DoPopupAdvance(CGuiTableGroup* caller) void CFrontEndUI::SNewFileSelectFrame::DoPopupAdvance(CGuiTableGroup* caller)
{ {
if (x8_subMenu == ESubMenu::ExistingGamePopup) if (x8_subMenu == ESubMenu::EraseGamePopup)
{ {
if (x40_tablegroup_popup->GetUserSelection() == 1) if (x40_tablegroup_popup->GetUserSelection() == 1)
{ {
@ -570,7 +610,7 @@ void CFrontEndUI::SNewFileSelectFrame::DoPopupAdvance(CGuiTableGroup* caller)
} }
else else
x8_subMenu = ESubMenu::EraseGame; x8_subMenu = ESubMenu::EraseGame;
x10d_needsExistingToggle = true; x10d_needsEraseToggle = true;
} }
else else
{ {
@ -582,8 +622,8 @@ void CFrontEndUI::SNewFileSelectFrame::DoPopupAdvance(CGuiTableGroup* caller)
xc_action = EAction::GameOptions; xc_action = EAction::GameOptions;
return; return;
} }
g_GameState->SetHardMode(x20_tablegroup_fileselect->GetUserSelection()); g_GameState->SetHardMode(!x40_tablegroup_popup->GetUserSelection());
x4_saveUI->StartGame(x40_tablegroup_popup->GetUserSelection()); x4_saveUI->StartGame(x20_tablegroup_fileselect->GetUserSelection());
} }
else else
{ {
@ -593,7 +633,7 @@ void CFrontEndUI::SNewFileSelectFrame::DoPopupAdvance(CGuiTableGroup* caller)
xc_action = EAction::GameOptions; xc_action = EAction::GameOptions;
return; 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)) if (x4_saveUI->GetGameData(userSel))
{ {
PlayAdvanceSfx(); PlayAdvanceSfx();
x10d_needsExistingToggle = true; x10d_needsEraseToggle = true;
} }
} }
else else
@ -669,7 +709,8 @@ void CFrontEndUI::SNewFileSelectFrame::StartTextAnimating(CGuiTextPane* text, co
text->TextSupport()->SetTypeWriteEffectOptions(true, 0.1f, chRate); text->TextSupport()->SetTypeWriteEffectOptions(true, 0.1f, chRate);
} }
CFrontEndUI::SFusionBonusFrame::SFusionBonusFrame() CFrontEndUI::SFusionBonusFrame::SFusionBonusFrame(CFrontEndUITouchBar& touchBar)
: m_touchBar(touchBar)
{ {
x4_gbaSupport = std::make_unique<CGBASupport>(); x4_gbaSupport = std::make_unique<CGBASupport>();
xc_gbaScreen = g_SimplePool->GetObj("FRME_GBAScreen"); 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::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) if (linkInProgress != x40_linkInProgress)
{ {
@ -833,12 +875,12 @@ CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::ProcessUserInput(const CFinalInpu
case EUIType::LinkFailed: case EUIType::LinkFailed:
case EUIType::LinkCompleteOrLinking: case EUIType::LinkCompleteOrLinking:
case EUIType::TurnOffGBA: case EUIType::TurnOffGBA:
if (input.PA()) if (input.PA() || tbAction == CFrontEndUITouchBar::EAction::Confirm)
{ {
PlayAdvanceSfx(); PlayAdvanceSfx();
SetUIText(NextLinkUI[int(x0_uiType)]); SetUIText(NextLinkUI[int(x0_uiType)]);
} }
else if (input.PB()) else if (input.PB() || tbAction == CFrontEndUITouchBar::EAction::Back)
{ {
EUIType prevUi = PrevLinkUI[int(x0_uiType)]; EUIType prevUi = PrevLinkUI[int(x0_uiType)];
if (prevUi == EUIType::Empty) if (prevUi == EUIType::Empty)
@ -912,8 +954,8 @@ void CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::Draw()
} }
CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::SGBALinkFrame(CGuiFrame* linkFrame, CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::SGBALinkFrame(CGuiFrame* linkFrame,
CGBASupport* support, CGBASupport* support,
bool linkInProgress) bool linkInProgress)
: x4_gbaSupport(support), x8_frme(linkFrame), x40_linkInProgress(linkInProgress) : x4_gbaSupport(support), x8_frme(linkFrame), x40_linkInProgress(linkInProgress)
{ {
support->InitializeSupport(); support->InitializeSupport();
@ -1030,7 +1072,8 @@ void CFrontEndUI::SFusionBonusFrame::Update(float dt, CSaveUI* saveUI)
} }
CFrontEndUI::SFusionBonusFrame::EAction 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; x8_action = EAction::None;
@ -1041,7 +1084,10 @@ CFrontEndUI::SFusionBonusFrame::ProcessUserInput(const CFinalInput& input, CSave
{ {
if (x0_gbaLinkFrame) 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) if (action != SGBALinkFrame::EAction::None)
{ {
x0_gbaLinkFrame.reset(); x0_gbaLinkFrame.reset();
@ -1057,7 +1103,51 @@ CFrontEndUI::SFusionBonusFrame::ProcessUserInput(const CFinalInput& input, CSave
} }
else if (x24_loadedFrame) 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); 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) void CFrontEndUI::SFusionBonusFrame::DoCancel(CGuiTableGroup* caller)
{ {
if (x39_fusionNotComplete || x3a_mpNotComplete) x8_action = EAction::GoBack;
{ x28_tablegroup_options->SetUserSelection(0);
CSfxManager::SfxStart(1094, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); x2c_tablegroup_fusionsuit->SetIsActive(false);
} x30_textpane_instructions.SetPairText(u"");
else 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) 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; bool fusionActive = x2c_tablegroup_fusionsuit->GetUserSelection() == 1;
g_GameState->SystemOptions().SetPlayerFusionSuitActive(fusionActive); g_GameState->SystemOptions().SetPlayerFusionSuitActive(fusionActive);
g_GameState->GetPlayerState()->SetIsFusionEnabled(fusionActive); g_GameState->GetPlayerState()->SetIsFusionEnabled(fusionActive);
m_touchBar.SetFusionBonusPhase(g_GameState->SystemOptions().GetPlayerFusionSuitActive());
} }
SetTableColors(caller); SetTableColors(caller);
} }
@ -1244,10 +1328,40 @@ void CFrontEndUI::SFrontEndFrame::Update(float dt)
} }
CFrontEndUI::SFrontEndFrame::EAction 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; x4_action = EAction::None;
x14_loadedFrme->ProcessUserInput(input); 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; return x4_action;
} }
@ -1297,8 +1411,8 @@ void CFrontEndUI::SFrontEndFrame::DoAdvance(CGuiTableGroup* caller)
} }
} }
CFrontEndUI::SFrontEndFrame::SFrontEndFrame(u32 rnd) CFrontEndUI::SFrontEndFrame::SFrontEndFrame(u32 rnd, CFrontEndUITouchBar& touchBar)
: x0_rnd(rnd) : x0_rnd(rnd), m_touchBar(touchBar)
{ {
x8_frme = g_SimplePool->GetObj("FRME_FrontEndPL"); x8_frme = g_SimplePool->GetObj("FRME_FrontEndPL");
} }
@ -1488,6 +1602,7 @@ void CFrontEndUI::SOptionsFrontEndFrame::DoSliderChange(CGuiSliderGroup* caller,
const auto& optionCategory = GameOptionsRegistry[leftSel]; const auto& optionCategory = GameOptionsRegistry[leftSel];
const SGameOption& option = optionCategory.second[rightSel]; const SGameOption& option = optionCategory.second[rightSel];
CGameOptions::SetOption(option.option, caller->GetGurVal()); 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 auto& optionCategory = GameOptionsRegistry[leftSel];
const SGameOption& option = optionCategory.second[rightSel]; const SGameOption& option = optionCategory.second[rightSel];
CGameOptions::SetOption(option.option, caller->GetUserSelection()); CGameOptions::SetOption(option.option, caller->GetUserSelection());
m_touchBarValueDirty = true;
CSfxManager::SfxStart(1095, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); CSfxManager::SfxStart(1095, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
if (option.option == EGameOption::Rumble && caller->GetUserSelection() > 0) if (option.option == EGameOption::Rumble && caller->GetUserSelection() > 0)
@ -1720,6 +1836,7 @@ bool CFrontEndUI::SOptionsFrontEndFrame::PumpLoad()
return false; return false;
x1c_loadedFrame = x4_frme.GetObj(); x1c_loadedFrame = x4_frme.GetObj();
x20_loadedPauseStrg = x10_pauseScreen.GetObj(); x20_loadedPauseStrg = x10_pauseScreen.GetObj();
m_touchBar = NewGameOptionsTouchBar();
FinishedLoading(); FinishedLoading();
return true; return true;
} }
@ -1739,10 +1856,89 @@ bool CFrontEndUI::SOptionsFrontEndFrame::ProcessUserInput(const CFinalInput& inp
else else
{ {
x1c_loadedFrame->ProcessUserInput(input); x1c_loadedFrame->ProcessUserInput(input);
CGameOptions::TryRestoreDefaults(input, int leftSel = x24_tablegroup_leftmenu->GetUserSelection();
x24_tablegroup_leftmenu->GetUserSelection(), int rightSel = x28_tablegroup_rightmenu->GetUserSelection();
x28_tablegroup_rightmenu->GetUserSelection(), CGameOptions::TryRestoreDefaults(input, leftSel, rightSel, true, false);
true);
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; return !x134_25_exitOptions;
@ -2211,6 +2407,7 @@ void CFrontEndUI::ProcessUserInput(const CFinalInput& input, CArchitectureQueue&
if (xf0_optionsFrme->ProcessUserInput(input, xdc_saveUI.get())) if (xf0_optionsFrme->ProcessUserInput(input, xdc_saveUI.get()))
return; return;
/* Exit options UI */ /* Exit options UI */
m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None);
xf0_optionsFrme.reset(); xf0_optionsFrme.reset();
return; return;
} }
@ -2238,18 +2435,21 @@ void CFrontEndUI::ProcessUserInput(const CFinalInput& input, CArchitectureQueue&
else else
{ {
/* Control FrontEnd without memory card */ /* Control FrontEnd without memory card */
switch (xe8_frontendNoCardFrme->ProcessUserInput(input)) switch (xe8_frontendNoCardFrme->ProcessUserInput(input, touchBarAction))
{ {
case SFrontEndFrame::EAction::FusionBonus: case SFrontEndFrame::EAction::FusionBonus:
m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None);
StartStateTransition(EScreen::FusionBonus); StartStateTransition(EScreen::FusionBonus);
return; return;
case SFrontEndFrame::EAction::GameOptions: case SFrontEndFrame::EAction::GameOptions:
m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None);
xf0_optionsFrme = std::make_unique<SOptionsFrontEndFrame>(); xf0_optionsFrme = std::make_unique<SOptionsFrontEndFrame>();
return; return;
case SFrontEndFrame::EAction::StartGame: case SFrontEndFrame::EAction::StartGame:
TransitionToGame(); TransitionToGame();
return; return;
case SFrontEndFrame::EAction::SlideShow: case SFrontEndFrame::EAction::SlideShow:
m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None);
xd2_deferSlideShow = true; xd2_deferSlideShow = true;
StartSlideShow(queue); StartSlideShow(queue);
return; return;
@ -2260,12 +2460,14 @@ void CFrontEndUI::ProcessUserInput(const CFinalInput& input, CArchitectureQueue&
else if (x50_curScreen == EScreen::FusionBonus && x54_nextScreen == EScreen::FusionBonus) else if (x50_curScreen == EScreen::FusionBonus && x54_nextScreen == EScreen::FusionBonus)
{ {
/* Control Fusion bonus UI */ /* 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: case SFusionBonusFrame::EAction::GoBack:
m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None);
StartStateTransition(EScreen::FileSelect); StartStateTransition(EScreen::FileSelect);
return; return;
case SFusionBonusFrame::EAction::PlayNESMetroid: case SFusionBonusFrame::EAction::PlayNESMetroid:
m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None);
xf4_curAudio->StopMixing(); xf4_curAudio->StopMixing();
xec_emuFrme = std::make_unique<SNesEmulatorFrame>(); xec_emuFrme = std::make_unique<SNesEmulatorFrame>();
if (xdc_saveUI) if (xdc_saveUI)
@ -2287,6 +2489,7 @@ void CFrontEndUI::TransitionToGame()
CSfxManager::SfxStart(sfx[1], 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); CSfxManager::SfxStart(sfx[1], 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
x14_phase = EPhase::ToPlayGame; x14_phase = EPhase::ToPlayGame;
m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None);
StartStateTransition(EScreen::ToPlayGame); StartStateTransition(EScreen::ToPlayGame);
} }
@ -2347,8 +2550,8 @@ CIOWin::EMessageReturn CFrontEndUI::Update(float dt, CArchitectureQueue& queue)
if (PumpLoad()) if (PumpLoad())
{ {
xe0_frontendCardFrme = std::make_unique<SNewFileSelectFrame>(xdc_saveUI.get(), x1c_rndB, *m_touchBar); xe0_frontendCardFrme = std::make_unique<SNewFileSelectFrame>(xdc_saveUI.get(), x1c_rndB, *m_touchBar);
xe4_fusionBonusFrme = std::make_unique<SFusionBonusFrame>(); xe4_fusionBonusFrme = std::make_unique<SFusionBonusFrame>(*m_touchBar);
xe8_frontendNoCardFrme = std::make_unique<SFrontEndFrame>(x1c_rndB); xe8_frontendNoCardFrme = std::make_unique<SFrontEndFrame>(x1c_rndB, *m_touchBar);
x38_pressStart.GetObj(); x38_pressStart.GetObj();
CAudioSys::AddAudioGroup(x44_frontendAudioGrp->GetAudioGroupData()); CAudioSys::AddAudioGroup(x44_frontendAudioGrp->GetAudioGroupData());
xd4_audio1 = std::make_unique<CStaticAudioPlayer>("Audio/frontend_1.rsf", 416480, 1973664); xd4_audio1 = std::make_unique<CStaticAudioPlayer>("Audio/frontend_1.rsf", 416480, 1973664);

View File

@ -14,6 +14,7 @@
#include "Graphics/Shaders/CTexturedQuadFilter.hpp" #include "Graphics/Shaders/CTexturedQuadFilter.hpp"
#include "Graphics/Shaders/CColoredQuadFilter.hpp" #include "Graphics/Shaders/CColoredQuadFilter.hpp"
#include "CFrontEndUITouchBar.hpp" #include "CFrontEndUITouchBar.hpp"
#include "CGameOptionsTouchBar.hpp"
namespace urde namespace urde
{ {
@ -106,7 +107,7 @@ public:
{ {
Root, Root,
EraseGame, EraseGame,
ExistingGamePopup, EraseGamePopup,
NewGamePopup NewGamePopup
}; };
@ -140,7 +141,7 @@ public:
float x104_rowPitch = 0.f; float x104_rowPitch = 0.f;
float x108_curTime = 0.f; float x108_curTime = 0.f;
bool x10c_saveReady = false; bool x10c_saveReady = false;
bool x10d_needsExistingToggle = false; bool x10d_needsEraseToggle = false;
bool x10e_needsNewToggle = false; bool x10e_needsNewToggle = false;
CFrontEndUITouchBar& m_touchBar; CFrontEndUITouchBar& m_touchBar;
@ -154,8 +155,8 @@ public:
void Draw() const; void Draw() const;
void HandleActiveChange(CGuiTableGroup* active); void HandleActiveChange(CGuiTableGroup* active);
void DeactivateExistingGamePopup(); void DeactivateEraseGamePopup();
void ActivateExistingGamePopup(); void ActivateEraseGamePopup();
void DeactivateNewGamePopup(); void DeactivateNewGamePopup();
void ActivateNewGamePopup(); void ActivateNewGamePopup();
@ -218,7 +219,8 @@ public:
bool x40_linkInProgress; bool x40_linkInProgress;
void SetUIText(EUIType tp); 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 Update(float dt);
void FinishedLoading(); void FinishedLoading();
void Draw(); void Draw();
@ -245,12 +247,15 @@ public:
bool x39_fusionNotComplete = false; bool x39_fusionNotComplete = false;
bool x3a_mpNotComplete = false; bool x3a_mpNotComplete = false;
SFusionBonusFrame(); CFrontEndUITouchBar& m_touchBar;
SFusionBonusFrame(CFrontEndUITouchBar& touchBar);
void FinishedLoading(); void FinishedLoading();
bool PumpLoad(); bool PumpLoad();
void SetTableColors(CGuiTableGroup* tbgp) const; void SetTableColors(CGuiTableGroup* tbgp) const;
void Update(float dt, CSaveUI* saveUI); 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 Draw() const;
void ResetCompletionFlags() void ResetCompletionFlags()
@ -282,11 +287,14 @@ public:
CGuiTableGroup* x18_tablegroup_mainmenu = nullptr; CGuiTableGroup* x18_tablegroup_mainmenu = nullptr;
SGuiTextPair x1c_gbaPair; SGuiTextPair x1c_gbaPair;
SGuiTextPair x24_cheatPair; SGuiTextPair x24_cheatPair;
SFrontEndFrame(u32 rnd);
CFrontEndUITouchBar& m_touchBar;
SFrontEndFrame(u32 rnd, CFrontEndUITouchBar& touchBar);
void FinishedLoading(); void FinishedLoading();
bool PumpLoad(); bool PumpLoad();
void Update(float dt); void Update(float dt);
EAction ProcessUserInput(const CFinalInput& input); EAction ProcessUserInput(const CFinalInput& input, CFrontEndUITouchBar::EAction tbAction);
void Draw() const; void Draw() const;
void HandleActiveChange(CGuiTableGroup* active); void HandleActiveChange(CGuiTableGroup* active);
@ -344,6 +352,11 @@ public:
bool x134_25_exitOptions : 1; bool x134_25_exitOptions : 1;
}; };
}; };
std::unique_ptr<CGameOptionsTouchBar> m_touchBar;
bool m_touchBarInValue = false;
bool m_touchBarValueDirty = false;
SOptionsFrontEndFrame(); SOptionsFrontEndFrame();
void DoSliderChange(CGuiSliderGroup* caller, float value); void DoSliderChange(CGuiSliderGroup* caller, float value);

View File

@ -4,9 +4,17 @@ namespace urde
{ {
CFrontEndUITouchBar::~CFrontEndUITouchBar() {} 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], 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; } CFrontEndUITouchBar::EAction CFrontEndUITouchBar::PopAction() { return EAction::None; }
#ifndef __APPLE__ #ifndef __APPLE__

View File

@ -13,20 +13,30 @@ public:
{ {
None, None,
PressStart, PressStart,
BackConfirm, ProceedBack,
FileSelect StartOptions,
EraseBack,
FileSelect,
NoCardSelect,
FusionBonus
}; };
enum class EAction enum class EAction
{ {
None, None,
Start, Start,
Normal,
Hard,
Back, Back,
Confirm, Confirm,
Options,
FileA, FileA,
FileB, FileB,
FileC, FileC,
Erase,
FusionBonus, FusionBonus,
ImageGallery ImageGallery,
NESMetroid,
FusionSuit
}; };
enum class EFileState enum class EFileState
{ {
@ -40,10 +50,18 @@ public:
int percent; int percent;
}; };
protected:
EPhase m_phase = EPhase::None;
public:
virtual ~CFrontEndUITouchBar(); virtual ~CFrontEndUITouchBar();
virtual void SetPhase(EPhase ph); virtual void SetPhase(EPhase ph);
virtual EPhase GetPhase();
virtual void SetFileSelectPhase(const SFileSelectDetail details[3], virtual void SetFileSelectPhase(const SFileSelectDetail details[3],
bool eraseGame, bool galleryActive); bool eraseGame, bool galleryActive);
virtual void SetNoCardSelectPhase(bool galleryActive);
virtual void SetFusionBonusPhase(bool fusionSuitActive);
virtual void SetStartOptionsPhase(bool normalBeat);
virtual EAction PopAction(); virtual EAction PopAction();
}; };

View File

@ -10,6 +10,34 @@
extern "C" uint8_t START_BUTTON_2X[]; extern "C" uint8_t START_BUTTON_2X[];
extern "C" size_t START_BUTTON_2X_SZ; 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 <NSTouchBarDelegate> @interface FrontEndUITouchBarPressStart : NSObject <NSTouchBarDelegate>
{ {
@public @public
@ -34,24 +62,24 @@ extern "C" size_t START_BUTTON_2X_SZ;
{ {
if ([identifier isEqualToString:@"pressStartGroup"]) if ([identifier isEqualToString:@"pressStartGroup"])
{ {
NSGroupTouchBarItem* group = [[NSGroupTouchBarItem alloc] initWithIdentifier:identifier]; NSGroupTouchBarItem* item = [[NSGroupTouchBarItem alloc] initWithIdentifier:identifier];
NSTouchBar* touchBar = [NSTouchBar new]; NSTouchBar* touchBar = [NSTouchBar new];
touchBar.delegate = self; touchBar.delegate = self;
id items = @[@"pressStart"]; id items = @[@"pressStart"];
touchBar.customizationRequiredItemIdentifiers = items; touchBar.customizationRequiredItemIdentifiers = items;
touchBar.defaultItemIdentifiers = items; touchBar.defaultItemIdentifiers = items;
group.groupTouchBar = touchBar; item.groupTouchBar = touchBar;
return group; return item;
} }
else if ([identifier isEqualToString:@"pressStart"]) else if ([identifier isEqualToString:@"pressStart"])
{ {
NSData* imgData = [NSData dataWithBytesNoCopy:START_BUTTON_2X length:START_BUTTON_2X_SZ freeWhenDone:NO]; NSData* imgData = [NSData dataWithBytesNoCopy:START_BUTTON_2X length:START_BUTTON_2X_SZ freeWhenDone:NO];
NSImage* img = [[NSImage alloc] initWithData:imgData]; 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:)]; NSButton* button = [NSButton buttonWithTitle:@"Start" image:img target:self action:@selector(onPressStart:)];
button.imageHugsTitle = YES; button.imageHugsTitle = YES;
pressStart.view = button; item.view = button;
return pressStart; return item;
} }
return nil; return nil;
} }
@ -61,6 +89,231 @@ extern "C" size_t START_BUTTON_2X_SZ;
} }
@end @end
@interface FrontEndUITouchBarProceedBack : NSObject <NSTouchBarDelegate>
{
@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 <NSTouchBarDelegate>
{
@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 <NSTouchBarDelegate>
{
@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) static NSString* GetFileSelectTitle(const urde::CFrontEndUITouchBar::SFileSelectDetail& detail, char letter)
{ {
switch (detail.state) switch (detail.state)
@ -86,6 +339,7 @@ static NSString* GetFileSelectTitle(const urde::CFrontEndUITouchBar::SFileSelect
-(IBAction)onFileA:(id)sender; -(IBAction)onFileA:(id)sender;
-(IBAction)onFileB:(id)sender; -(IBAction)onFileB:(id)sender;
-(IBAction)onFileC:(id)sender; -(IBAction)onFileC:(id)sender;
-(IBAction)onErase:(id)sender;
-(IBAction)onFusionBonus:(id)sender; -(IBAction)onFusionBonus:(id)sender;
-(IBAction)onImageGallery:(id)sender; -(IBAction)onImageGallery:(id)sender;
@end @end
@ -106,54 +360,82 @@ static NSString* GetFileSelectTitle(const urde::CFrontEndUITouchBar::SFileSelect
{ {
if ([identifier isEqualToString:@"fileSelectGroup"]) if ([identifier isEqualToString:@"fileSelectGroup"])
{ {
NSGroupTouchBarItem* group = [[NSGroupTouchBarItem alloc] initWithIdentifier:identifier]; NSGroupTouchBarItem* item = [[NSGroupTouchBarItem alloc] initWithIdentifier:identifier];
NSTouchBar* touchBar = [NSTouchBar new]; NSTouchBar* touchBar = [NSTouchBar new];
touchBar.delegate = self; touchBar.delegate = self;
id items = @[@"fileA", @"fileB", @"fileC", @"fusionBonus", @"imageGallery"]; id items = @[@"fileA", @"fileB", @"fileC", @"erase", @"fusionBonus", @"imageGallery"];
touchBar.customizationRequiredItemIdentifiers = items; touchBar.customizationRequiredItemIdentifiers = items;
touchBar.defaultItemIdentifiers = items; touchBar.defaultItemIdentifiers = items;
group.groupTouchBar = touchBar; item.groupTouchBar = touchBar;
return group; return item;
} }
else if ([identifier isEqualToString:@"fileA"]) 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:)]; 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; button.enabled = !_eraseGame || _details[0].state != urde::CFrontEndUITouchBar::EFileState::New;
pressStart.view = button; item.view = button;
return pressStart; return item;
} }
else if ([identifier isEqualToString:@"fileB"]) 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:)]; 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; button.enabled = !_eraseGame || _details[1].state != urde::CFrontEndUITouchBar::EFileState::New;
pressStart.view = button; item.view = button;
return pressStart; return item;
} }
else if ([identifier isEqualToString:@"fileC"]) 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:)]; 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; button.enabled = !_eraseGame || _details[2].state != urde::CFrontEndUITouchBar::EFileState::New;
pressStart.view = button; item.view = button;
return pressStart; 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"]) else if ([identifier isEqualToString:@"fusionBonus"])
{ {
NSCustomTouchBarItem* pressStart = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier];
NSButton* button = [NSButton buttonWithTitle:@"Fusion Bonuses" target:self action:@selector(onFusionBonus:)]; NSButton* button = [NSButton buttonWithTitle:@"Bonuses" target:self action:@selector(onFusionBonus:)];
button.enabled = !_eraseGame; button.enabled = !_eraseGame;
pressStart.view = button; item.view = button;
return pressStart; return item;
} }
else if ([identifier isEqualToString:@"imageGallery"]) else if ([identifier isEqualToString:@"imageGallery"])
{ {
NSCustomTouchBarItem* pressStart = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier];
NSButton* button = [NSButton buttonWithTitle:@"Image Gallery" target:self action:@selector(onImageGallery:)]; NSButton* button = [NSButton buttonWithTitle:@"Gallery" target:self action:@selector(onImageGallery:)];
button.enabled = !_eraseGame && _galleryActive; button.enabled = !_eraseGame && _galleryActive;
pressStart.view = button; item.view = button;
return pressStart; return item;
} }
return nil; return nil;
} }
@ -169,6 +451,13 @@ static NSString* GetFileSelectTitle(const urde::CFrontEndUITouchBar::SFileSelect
{ {
_action = urde::CFrontEndUITouchBar::EAction::FileC; _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 -(IBAction)onFusionBonus:(id)sender
{ {
_action = urde::CFrontEndUITouchBar::EAction::FusionBonus; _action = urde::CFrontEndUITouchBar::EAction::FusionBonus;
@ -179,14 +468,181 @@ static NSString* GetFileSelectTitle(const urde::CFrontEndUITouchBar::SFileSelect
} }
@end @end
@interface FrontEndUITouchBarNoCardSelect : NSObject <NSTouchBarDelegate>
{
@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 <NSTouchBarDelegate>
{
@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 namespace urde
{ {
class CFrontEndUITouchBarMac : public CFrontEndUITouchBar class CFrontEndUITouchBarMac : public CFrontEndUITouchBar
{ {
EPhase m_phase = EPhase::None;
FrontEndUITouchBarPressStart* m_pressStartBar; FrontEndUITouchBarPressStart* m_pressStartBar;
FrontEndUITouchBarProceedBack* m_proceedBackBar;
FrontEndUITouchBarStartOptions* m_startOptions;
FrontEndUITouchBarEraseBack* m_eraseBack;
FrontEndUITouchBarFileSelect* m_fileSelectBar; FrontEndUITouchBarFileSelect* m_fileSelectBar;
FrontEndUITouchBarNoCardSelect* m_noCardSelectBar;
FrontEndUITouchBarFusionBonus* m_fusionBonusBar;
void Activate() void Activate()
{ {
@ -196,9 +652,24 @@ class CFrontEndUITouchBarMac : public CFrontEndUITouchBar
case EPhase::PressStart: case EPhase::PressStart:
provider = m_pressStartBar; provider = m_pressStartBar;
break; 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: case EPhase::FileSelect:
provider = m_fileSelectBar; provider = m_fileSelectBar;
break; break;
case EPhase::NoCardSelect:
provider = m_noCardSelectBar;
break;
case EPhase::FusionBonus:
provider = m_fusionBonusBar;
break;
default: break; default: break;
} }
g_Main->GetMainWindow()->setTouchBarProvider((__bridge_retained void*)provider); g_Main->GetMainWindow()->setTouchBarProvider((__bridge_retained void*)provider);
@ -208,13 +679,22 @@ public:
CFrontEndUITouchBarMac() CFrontEndUITouchBarMac()
{ {
m_pressStartBar = [FrontEndUITouchBarPressStart new]; m_pressStartBar = [FrontEndUITouchBarPressStart new];
m_proceedBackBar = [FrontEndUITouchBarProceedBack new];
m_startOptions = [FrontEndUITouchBarStartOptions new];
m_eraseBack = [FrontEndUITouchBarEraseBack new];
m_fileSelectBar = [FrontEndUITouchBarFileSelect new]; m_fileSelectBar = [FrontEndUITouchBarFileSelect new];
m_noCardSelectBar = [FrontEndUITouchBarNoCardSelect new];
m_fusionBonusBar = [FrontEndUITouchBarFusionBonus new];
} }
void SetPhase(EPhase ph) void SetPhase(EPhase ph)
{ {
m_phase = ph; m_phase = ph;
Activate(); Activate();
} }
EPhase GetPhase()
{
return m_phase;
}
void SetFileSelectPhase(const SFileSelectDetail details[3], bool eraseGame, bool galleryActive) void SetFileSelectPhase(const SFileSelectDetail details[3], bool eraseGame, bool galleryActive)
{ {
m_fileSelectBar->_details[0] = details[0]; m_fileSelectBar->_details[0] = details[0];
@ -225,6 +705,24 @@ public:
m_phase = EPhase::FileSelect; m_phase = EPhase::FileSelect;
Activate(); 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() EAction PopAction()
{ {
switch (m_phase) switch (m_phase)
@ -236,6 +734,30 @@ public:
return EAction::Start; return EAction::Start;
} }
break; 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: case EPhase::FileSelect:
if (m_fileSelectBar->_action != EAction::None) if (m_fileSelectBar->_action != EAction::None)
{ {
@ -244,6 +766,22 @@ public:
return action; return action;
} }
break; 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; default: break;
} }
return EAction::None; return EAction::None;

2
hecl

@ -1 +1 @@
Subproject commit 4ab6eab5641b4f77e187e602d812db4c43be8106 Subproject commit 42e21ac921790c0fa5e63068f4564849a597c9ac