2015-07-22 02:48:26 -04:00
|
|
|
#include "PathUtils.h"
|
|
|
|
#import "EmulatorViewController.h"
|
2021-06-19 15:43:12 -04:00
|
|
|
#import "SettingsViewController.h"
|
2021-06-27 08:42:26 -04:00
|
|
|
#import "RenderView.h"
|
2015-07-22 02:48:26 -04:00
|
|
|
#include "../PS2VM.h"
|
|
|
|
#include "../PS2VM_Preferences.h"
|
|
|
|
#include "../AppConfig.h"
|
2016-01-07 19:48:21 -05:00
|
|
|
#include "PreferenceDefs.h"
|
2015-07-22 02:48:26 -04:00
|
|
|
#include "GSH_OpenGLiOS.h"
|
2021-06-27 08:42:26 -04:00
|
|
|
#include "GSH_VulkaniOS.h"
|
2017-11-01 07:26:08 -04:00
|
|
|
#include "../ui_shared/BootablesProcesses.h"
|
2015-10-31 20:38:27 -04:00
|
|
|
#include "PH_Generic.h"
|
2016-04-04 11:51:15 -04:00
|
|
|
#include "../../tools/PsfPlayer/Source/SH_OpenAL.h"
|
2019-08-02 21:33:37 -04:00
|
|
|
#include "../ui_shared/StatsManager.h"
|
2015-07-22 02:48:26 -04:00
|
|
|
|
|
|
|
CPS2VM* g_virtualMachine = nullptr;
|
2019-08-16 17:34:57 -04:00
|
|
|
CGSHandler::NewFrameEvent::Connection g_newFrameConnection;
|
|
|
|
#ifdef PROFILE
|
|
|
|
CPS2VM::ProfileFrameDoneSignal::Connection g_profileFrameDoneConnection;
|
|
|
|
#endif
|
2015-07-22 02:48:26 -04:00
|
|
|
|
|
|
|
@interface EmulatorViewController ()
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation EmulatorViewController
|
|
|
|
|
2020-12-02 18:37:31 -05:00
|
|
|
+ (void)registerPreferences
|
2016-01-07 19:48:21 -05:00
|
|
|
{
|
|
|
|
CAppConfig::GetInstance().RegisterPreferenceBoolean(PREFERENCE_UI_SHOWFPS, false);
|
2016-01-08 10:27:02 -05:00
|
|
|
CAppConfig::GetInstance().RegisterPreferenceBoolean(PREFERENCE_UI_SHOWVIRTUALPAD, true);
|
2016-04-04 11:51:15 -04:00
|
|
|
CAppConfig::GetInstance().RegisterPreferenceBoolean(PREFERENCE_AUDIO_ENABLEOUTPUT, true);
|
2021-06-27 08:42:26 -04:00
|
|
|
CAppConfig::GetInstance().RegisterPreferenceInteger(PREFERENCE_VIDEO_GS_HANDLER, PREFERENCE_VALUE_VIDEO_GS_HANDLER_OPENGL);
|
2016-01-07 19:48:21 -05:00
|
|
|
}
|
|
|
|
|
2020-12-02 18:37:31 -05:00
|
|
|
- (void)viewDidLoad
|
2015-07-22 02:48:26 -04:00
|
|
|
{
|
2020-12-02 18:37:31 -05:00
|
|
|
self.connectObserver = [[NSNotificationCenter defaultCenter] addObserverForName:GCControllerDidConnectNotification
|
|
|
|
object:nil
|
|
|
|
queue:[NSOperationQueue mainQueue]
|
|
|
|
usingBlock:^(NSNotification* note) {
|
|
|
|
if([[GCController controllers] count] == 1)
|
|
|
|
{
|
|
|
|
[self toggleHardwareController:YES];
|
|
|
|
}
|
|
|
|
}];
|
|
|
|
self.disconnectObserver = [[NSNotificationCenter defaultCenter] addObserverForName:GCControllerDidDisconnectNotification
|
|
|
|
object:nil
|
|
|
|
queue:[NSOperationQueue mainQueue]
|
|
|
|
usingBlock:^(NSNotification* note) {
|
|
|
|
if(![[GCController controllers] count])
|
|
|
|
{
|
|
|
|
[self toggleHardwareController:NO];
|
|
|
|
}
|
|
|
|
}];
|
|
|
|
|
|
|
|
if([[GCController controllers] count])
|
|
|
|
{
|
|
|
|
[self toggleHardwareController:YES];
|
|
|
|
}
|
|
|
|
|
|
|
|
self.iCadeReader = [[iCadeReaderView alloc] init];
|
|
|
|
[self.view addSubview:self.iCadeReader];
|
|
|
|
self.iCadeReader.delegate = self;
|
|
|
|
self.iCadeReader.active = YES;
|
2015-10-21 10:11:23 -04:00
|
|
|
}
|
|
|
|
|
2020-12-02 18:37:31 -05:00
|
|
|
- (void)viewDidAppear:(BOOL)animated
|
2015-10-21 10:11:23 -04:00
|
|
|
{
|
2016-01-22 19:50:39 -05:00
|
|
|
assert(g_virtualMachine == nullptr);
|
2015-07-22 02:48:26 -04:00
|
|
|
g_virtualMachine = new CPS2VM();
|
|
|
|
g_virtualMachine->Initialize();
|
2021-06-27 08:42:26 -04:00
|
|
|
|
|
|
|
auto gsHandlerId = CAppConfig::GetInstance().GetPreferenceInteger(PREFERENCE_VIDEO_GS_HANDLER);
|
|
|
|
switch(gsHandlerId)
|
|
|
|
{
|
|
|
|
default:
|
|
|
|
[[fallthrough]];
|
|
|
|
case PREFERENCE_VALUE_VIDEO_GS_HANDLER_OPENGL:
|
|
|
|
g_virtualMachine->CreateGSHandler(CGSH_OpenGLiOS::GetFactoryFunction((CAEAGLLayer*)self.view.layer));
|
|
|
|
break;
|
|
|
|
case PREFERENCE_VALUE_VIDEO_GS_HANDLER_VULKAN:
|
|
|
|
g_virtualMachine->CreateGSHandler(CGSH_VulkaniOS::GetFactoryFunction((CAMetalLayer*)self.view.layer));
|
|
|
|
break;
|
|
|
|
}
|
2015-07-22 02:48:26 -04:00
|
|
|
|
2015-10-31 20:38:27 -04:00
|
|
|
g_virtualMachine->CreatePadHandler(CPH_Generic::GetFactoryFunction());
|
2020-12-02 18:37:31 -05:00
|
|
|
|
2021-06-21 15:01:23 -04:00
|
|
|
[self setupSoundHandler];
|
2021-06-19 16:06:17 -04:00
|
|
|
[self updateOnScreenWidgets];
|
2020-12-02 18:37:31 -05:00
|
|
|
|
2015-07-22 02:48:26 -04:00
|
|
|
g_virtualMachine->Pause();
|
|
|
|
g_virtualMachine->Reset();
|
|
|
|
|
2019-10-17 21:27:28 -04:00
|
|
|
auto bootablePath = fs::path([self.bootablePath fileSystemRepresentation]);
|
2017-11-01 09:46:23 -04:00
|
|
|
if(IsBootableExecutablePath(bootablePath))
|
2015-07-26 01:02:39 -04:00
|
|
|
{
|
2017-11-01 09:46:23 -04:00
|
|
|
g_virtualMachine->m_ee->m_os->BootFromFile(bootablePath);
|
2015-07-26 01:02:39 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-08-29 10:43:10 -04:00
|
|
|
CAppConfig::GetInstance().SetPreferencePath(PREF_PS2_CDROM0_PATH, bootablePath);
|
2015-07-26 01:02:39 -04:00
|
|
|
g_virtualMachine->Reset();
|
2015-12-06 14:53:35 -05:00
|
|
|
g_virtualMachine->m_ee->m_os->BootFromCDROM();
|
2015-07-26 01:02:39 -04:00
|
|
|
}
|
2015-07-22 02:48:26 -04:00
|
|
|
|
|
|
|
g_virtualMachine->Resume();
|
|
|
|
}
|
|
|
|
|
2020-12-02 18:37:31 -05:00
|
|
|
- (void)viewDidDisappear:(BOOL)animated
|
2016-01-22 19:50:39 -05:00
|
|
|
{
|
2021-06-19 16:06:17 -04:00
|
|
|
[self resetStatsTimer];
|
2016-01-22 19:50:39 -05:00
|
|
|
g_virtualMachine->Pause();
|
|
|
|
g_virtualMachine->Destroy();
|
|
|
|
delete g_virtualMachine;
|
|
|
|
g_virtualMachine = nullptr;
|
2019-08-16 17:34:57 -04:00
|
|
|
g_newFrameConnection.reset();
|
|
|
|
#ifdef PROFILE
|
|
|
|
g_profileFrameDoneConnection.reset();
|
|
|
|
#endif
|
2016-01-22 19:50:39 -05:00
|
|
|
}
|
|
|
|
|
2020-12-02 18:37:31 -05:00
|
|
|
- (void)toggleHardwareController:(BOOL)useHardware
|
2016-01-30 21:06:39 -05:00
|
|
|
{
|
|
|
|
if(useHardware)
|
|
|
|
{
|
|
|
|
self.gController = [GCController controllers][0];
|
2016-05-01 16:34:06 -04:00
|
|
|
if(self.gController.extendedGamepad)
|
2016-01-30 21:06:39 -05:00
|
|
|
{
|
2016-05-01 16:34:06 -04:00
|
|
|
[self.gController.extendedGamepad setValueChangedHandler:
|
2020-12-02 18:37:31 -05:00
|
|
|
^(GCExtendedGamepad* gamepad, GCControllerElement* element) {
|
|
|
|
auto padHandler = static_cast<CPH_Generic*>(g_virtualMachine->GetPadHandler());
|
|
|
|
if(!padHandler) return;
|
|
|
|
if(element == gamepad.buttonA)
|
|
|
|
padHandler->SetButtonState(PS2::CControllerInfo::CROSS, gamepad.buttonA.pressed);
|
|
|
|
else if(element == gamepad.buttonB)
|
|
|
|
padHandler->SetButtonState(PS2::CControllerInfo::CIRCLE, gamepad.buttonB.pressed);
|
|
|
|
else if(element == gamepad.buttonX)
|
|
|
|
padHandler->SetButtonState(PS2::CControllerInfo::SQUARE, gamepad.buttonX.pressed);
|
|
|
|
else if(element == gamepad.buttonY)
|
|
|
|
padHandler->SetButtonState(PS2::CControllerInfo::TRIANGLE, gamepad.buttonY.pressed);
|
|
|
|
else if(element == gamepad.leftShoulder)
|
|
|
|
padHandler->SetButtonState(PS2::CControllerInfo::L1, gamepad.leftShoulder.pressed);
|
|
|
|
else if(element == gamepad.rightShoulder)
|
|
|
|
padHandler->SetButtonState(PS2::CControllerInfo::R1, gamepad.rightShoulder.pressed);
|
|
|
|
else if(element == gamepad.leftTrigger)
|
|
|
|
padHandler->SetButtonState(PS2::CControllerInfo::L2, gamepad.leftTrigger.pressed);
|
|
|
|
else if(element == gamepad.rightTrigger)
|
|
|
|
padHandler->SetButtonState(PS2::CControllerInfo::R2, gamepad.rightTrigger.pressed);
|
|
|
|
else if(element == gamepad.dpad)
|
|
|
|
{
|
|
|
|
padHandler->SetButtonState(PS2::CControllerInfo::DPAD_UP, gamepad.dpad.up.pressed);
|
|
|
|
padHandler->SetButtonState(PS2::CControllerInfo::DPAD_DOWN, gamepad.dpad.down.pressed);
|
|
|
|
padHandler->SetButtonState(PS2::CControllerInfo::DPAD_LEFT, gamepad.dpad.left.pressed);
|
|
|
|
padHandler->SetButtonState(PS2::CControllerInfo::DPAD_RIGHT, gamepad.dpad.right.pressed);
|
|
|
|
}
|
|
|
|
else if(element == gamepad.leftThumbstick)
|
|
|
|
{
|
|
|
|
padHandler->SetAxisState(PS2::CControllerInfo::ANALOG_LEFT_X, gamepad.leftThumbstick.xAxis.value);
|
|
|
|
padHandler->SetAxisState(PS2::CControllerInfo::ANALOG_LEFT_Y, -gamepad.leftThumbstick.yAxis.value);
|
|
|
|
}
|
|
|
|
else if(element == gamepad.rightThumbstick)
|
|
|
|
{
|
|
|
|
padHandler->SetAxisState(PS2::CControllerInfo::ANALOG_RIGHT_X, gamepad.rightThumbstick.xAxis.value);
|
|
|
|
padHandler->SetAxisState(PS2::CControllerInfo::ANALOG_RIGHT_Y, -gamepad.rightThumbstick.yAxis.value);
|
|
|
|
}
|
|
|
|
}];
|
2016-01-30 21:06:39 -05:00
|
|
|
}
|
2016-05-01 16:34:06 -04:00
|
|
|
else if(self.gController.gamepad)
|
2016-01-30 21:06:39 -05:00
|
|
|
{
|
2016-05-01 16:34:06 -04:00
|
|
|
[self.gController.gamepad setValueChangedHandler:
|
2020-12-02 18:37:31 -05:00
|
|
|
^(GCGamepad* gamepad, GCControllerElement* element) {
|
|
|
|
auto padHandler = static_cast<CPH_Generic*>(g_virtualMachine->GetPadHandler());
|
|
|
|
if(!padHandler) return;
|
|
|
|
if(element == gamepad.buttonA)
|
|
|
|
padHandler->SetButtonState(PS2::CControllerInfo::CROSS, gamepad.buttonA.pressed);
|
|
|
|
else if(element == gamepad.buttonB)
|
|
|
|
padHandler->SetButtonState(PS2::CControllerInfo::CIRCLE, gamepad.buttonB.pressed);
|
|
|
|
else if(element == gamepad.buttonX)
|
|
|
|
padHandler->SetButtonState(PS2::CControllerInfo::SQUARE, gamepad.buttonX.pressed);
|
|
|
|
else if(element == gamepad.buttonY)
|
|
|
|
padHandler->SetButtonState(PS2::CControllerInfo::TRIANGLE, gamepad.buttonY.pressed);
|
|
|
|
else if(element == gamepad.leftShoulder)
|
|
|
|
padHandler->SetButtonState(PS2::CControllerInfo::L1, gamepad.leftShoulder.pressed);
|
|
|
|
else if(element == gamepad.rightShoulder)
|
|
|
|
padHandler->SetButtonState(PS2::CControllerInfo::R1, gamepad.rightShoulder.pressed);
|
|
|
|
else if(element == gamepad.dpad)
|
|
|
|
{
|
|
|
|
padHandler->SetButtonState(PS2::CControllerInfo::DPAD_UP, gamepad.dpad.up.pressed);
|
|
|
|
padHandler->SetButtonState(PS2::CControllerInfo::DPAD_DOWN, gamepad.dpad.down.pressed);
|
|
|
|
padHandler->SetButtonState(PS2::CControllerInfo::DPAD_LEFT, gamepad.dpad.left.pressed);
|
|
|
|
padHandler->SetButtonState(PS2::CControllerInfo::DPAD_RIGHT, gamepad.dpad.right.pressed);
|
|
|
|
padHandler->SetAxisState(PS2::CControllerInfo::ANALOG_LEFT_X, gamepad.dpad.xAxis.value);
|
|
|
|
padHandler->SetAxisState(PS2::CControllerInfo::ANALOG_LEFT_Y, -gamepad.dpad.yAxis.value);
|
|
|
|
}
|
|
|
|
}];
|
2016-05-01 16:34:06 -04:00
|
|
|
//Add controller pause handler here
|
2016-01-30 21:06:39 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
self.gController = nil;
|
|
|
|
}
|
2015-08-12 16:59:32 -04:00
|
|
|
}
|
|
|
|
|
2021-06-19 16:06:17 -04:00
|
|
|
- (void)resetStatsTimer
|
|
|
|
{
|
|
|
|
if(self.fpsCounterTimer)
|
|
|
|
{
|
|
|
|
[self.fpsCounterTimer invalidate];
|
|
|
|
self.fpsCounterTimer = nil;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)updateOnScreenWidgets
|
|
|
|
{
|
|
|
|
auto screenBounds = [[UIScreen mainScreen] bounds];
|
|
|
|
if(@available(iOS 11, *))
|
|
|
|
{
|
|
|
|
UIEdgeInsets insets = self.view.safeAreaInsets;
|
|
|
|
screenBounds = UIEdgeInsetsInsetRect(screenBounds, insets);
|
|
|
|
}
|
|
|
|
|
|
|
|
//Remove previous widgets
|
|
|
|
if(self.virtualPadView)
|
|
|
|
{
|
|
|
|
[self.virtualPadView removeFromSuperview];
|
|
|
|
self.virtualPadView = nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(self.fpsCounterLabel)
|
|
|
|
{
|
|
|
|
[self.fpsCounterLabel removeFromSuperview];
|
|
|
|
self.fpsCounterLabel = nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef PROFILE
|
|
|
|
if(self.profilerStatsLabel)
|
|
|
|
{
|
|
|
|
[self.profilerStatsLabel removeFromSuperview];
|
|
|
|
self.profilerStatsLabel = nil;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
[self resetStatsTimer];
|
|
|
|
|
|
|
|
if(CAppConfig::GetInstance().GetPreferenceBoolean(PREFERENCE_UI_SHOWVIRTUALPAD))
|
|
|
|
{
|
|
|
|
auto padHandler = static_cast<CPH_Generic*>(g_virtualMachine->GetPadHandler());
|
|
|
|
self.virtualPadView = [[VirtualPadView alloc] initWithFrame:screenBounds padHandler:padHandler];
|
|
|
|
[self.view addSubview:self.virtualPadView];
|
|
|
|
[self.view sendSubviewToBack:self.virtualPadView];
|
|
|
|
}
|
|
|
|
|
|
|
|
if(CAppConfig::GetInstance().GetPreferenceBoolean(PREFERENCE_UI_SHOWFPS))
|
|
|
|
{
|
|
|
|
[self setupFpsCounterWithBounds:screenBounds];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-21 15:01:23 -04:00
|
|
|
- (void)setupSoundHandler
|
|
|
|
{
|
|
|
|
if(CAppConfig::GetInstance().GetPreferenceBoolean(PREFERENCE_AUDIO_ENABLEOUTPUT))
|
|
|
|
{
|
|
|
|
g_virtualMachine->CreateSoundHandler(&CSH_OpenAL::HandlerFactory);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_virtualMachine->DestroySoundHandler();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-02 18:37:31 -05:00
|
|
|
- (void)setupFpsCounterWithBounds:(CGRect)screenBounds
|
2015-11-24 10:31:44 -05:00
|
|
|
{
|
2020-12-02 18:37:31 -05:00
|
|
|
self.fpsCounterLabel = [[UILabel alloc] initWithFrame:screenBounds];
|
2015-11-24 10:31:44 -05:00
|
|
|
self.fpsCounterLabel.textColor = [UIColor whiteColor];
|
2020-12-02 18:37:31 -05:00
|
|
|
[self.view addSubview:self.fpsCounterLabel];
|
|
|
|
|
2019-08-02 22:17:50 -04:00
|
|
|
#ifdef PROFILE
|
2020-12-02 18:37:31 -05:00
|
|
|
self.profilerStatsLabel = [[UILabel alloc] initWithFrame:screenBounds];
|
2019-08-02 22:17:50 -04:00
|
|
|
self.profilerStatsLabel.textColor = [UIColor whiteColor];
|
2020-12-02 18:37:31 -05:00
|
|
|
self.profilerStatsLabel.font = [UIFont fontWithName:@"Courier" size:10.f];
|
2019-08-02 22:17:50 -04:00
|
|
|
self.profilerStatsLabel.numberOfLines = 0;
|
2020-12-02 18:37:31 -05:00
|
|
|
[self.view addSubview:self.profilerStatsLabel];
|
2019-08-02 22:17:50 -04:00
|
|
|
#endif
|
2020-12-02 18:37:31 -05:00
|
|
|
|
2019-08-16 17:34:57 -04:00
|
|
|
g_newFrameConnection = g_virtualMachine->GetGSHandler()->OnNewFrame.Connect(std::bind(&CStatsManager::OnNewFrame, &CStatsManager::GetInstance(), std::placeholders::_1));
|
2019-08-02 22:17:50 -04:00
|
|
|
#ifdef PROFILE
|
2019-08-16 17:34:57 -04:00
|
|
|
g_profileFrameDoneConnection = g_virtualMachine->ProfileFrameDone.Connect(std::bind(&CStatsManager::OnProfileFrameDone, &CStatsManager::GetInstance(), g_virtualMachine, std::placeholders::_1));
|
2019-08-02 22:17:50 -04:00
|
|
|
#endif
|
2020-12-02 18:37:31 -05:00
|
|
|
self.fpsCounterTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(updateFpsCounter) userInfo:nil repeats:YES];
|
2015-11-24 10:31:44 -05:00
|
|
|
}
|
|
|
|
|
2020-12-02 18:37:31 -05:00
|
|
|
- (void)updateFpsCounter
|
2015-11-24 10:31:44 -05:00
|
|
|
{
|
2019-08-02 21:33:37 -04:00
|
|
|
uint32 drawCallCount = CStatsManager::GetInstance().GetDrawCalls();
|
|
|
|
uint32 frames = CStatsManager::GetInstance().GetFrames();
|
|
|
|
uint32 dcpf = (frames != 0) ? (drawCallCount / frames) : 0;
|
2020-12-02 18:37:31 -05:00
|
|
|
self.fpsCounterLabel.text = [NSString stringWithFormat:@"%d f/s, %d dc/f", frames, dcpf];
|
2015-11-24 10:31:44 -05:00
|
|
|
[self.fpsCounterLabel sizeToFit];
|
2019-08-02 22:17:50 -04:00
|
|
|
#ifdef PROFILE
|
2020-12-02 18:37:31 -05:00
|
|
|
self.profilerStatsLabel.text = [NSString stringWithUTF8String:CStatsManager::GetInstance().GetProfilingInfo().c_str()];
|
2019-08-02 22:17:50 -04:00
|
|
|
#endif
|
2019-08-02 21:33:37 -04:00
|
|
|
CStatsManager::GetInstance().ClearStats();
|
2015-11-24 10:31:44 -05:00
|
|
|
}
|
|
|
|
|
2020-12-02 18:37:31 -05:00
|
|
|
- (void)onLoadStateButtonClick
|
2018-12-23 22:07:34 -05:00
|
|
|
{
|
2018-12-23 22:43:41 -05:00
|
|
|
auto statePath = g_virtualMachine->GenerateStatePath(0);
|
|
|
|
g_virtualMachine->LoadState(statePath);
|
|
|
|
NSLog(@"Loaded state from '%s'.", statePath.string().c_str());
|
2018-12-23 22:07:34 -05:00
|
|
|
}
|
|
|
|
|
2020-12-02 18:37:31 -05:00
|
|
|
- (void)onSaveStateButtonClick
|
2015-12-02 10:19:28 -05:00
|
|
|
{
|
2018-12-23 22:43:41 -05:00
|
|
|
auto statePath = g_virtualMachine->GenerateStatePath(0);
|
|
|
|
g_virtualMachine->SaveState(statePath);
|
2015-12-02 10:19:28 -05:00
|
|
|
NSLog(@"Saved state to '%s'.", statePath.string().c_str());
|
|
|
|
}
|
|
|
|
|
2020-12-02 18:37:31 -05:00
|
|
|
- (void)onExitButtonClick
|
2016-01-08 18:39:27 -05:00
|
|
|
{
|
2020-12-02 18:37:31 -05:00
|
|
|
[self dismissViewControllerAnimated:YES completion:nil];
|
2016-01-08 18:39:27 -05:00
|
|
|
}
|
|
|
|
|
2020-12-02 18:37:31 -05:00
|
|
|
- (IBAction)onPauseButtonClick:(id)sender
|
2018-12-23 22:07:34 -05:00
|
|
|
{
|
2021-06-18 15:07:28 -04:00
|
|
|
UIAlertControllerStyle style = UIAlertControllerStyleAlert;
|
|
|
|
if([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone)
|
|
|
|
{
|
|
|
|
style = UIAlertControllerStyleActionSheet;
|
|
|
|
}
|
|
|
|
|
|
|
|
UIAlertController* alert = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:style];
|
2020-12-02 18:37:31 -05:00
|
|
|
|
2018-12-23 22:07:34 -05:00
|
|
|
//Load State
|
|
|
|
{
|
|
|
|
UIAlertAction* action = [UIAlertAction
|
2020-12-02 18:37:31 -05:00
|
|
|
actionWithTitle:@"Load State"
|
|
|
|
style:UIAlertActionStyleDefault
|
|
|
|
handler:^(UIAlertAction*) {
|
|
|
|
[self onLoadStateButtonClick];
|
|
|
|
}];
|
|
|
|
[alert addAction:action];
|
2018-12-23 22:07:34 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
//Save State
|
|
|
|
{
|
|
|
|
UIAlertAction* action = [UIAlertAction
|
2020-12-02 18:37:31 -05:00
|
|
|
actionWithTitle:@"Save State"
|
|
|
|
style:UIAlertActionStyleDefault
|
|
|
|
handler:^(UIAlertAction*) {
|
|
|
|
[self onSaveStateButtonClick];
|
|
|
|
}];
|
|
|
|
[alert addAction:action];
|
2018-12-23 22:07:34 -05:00
|
|
|
}
|
|
|
|
|
2021-06-19 15:43:12 -04:00
|
|
|
//Settings
|
|
|
|
{
|
|
|
|
UIAlertAction* action = [UIAlertAction
|
|
|
|
actionWithTitle:@"Settings"
|
|
|
|
style:UIAlertActionStyleDefault
|
|
|
|
handler:^(UIAlertAction*) {
|
|
|
|
[self performSegueWithIdentifier:@"showSettings" sender:self];
|
|
|
|
}];
|
|
|
|
[alert addAction:action];
|
|
|
|
}
|
|
|
|
|
2018-12-23 22:07:34 -05:00
|
|
|
//Resume
|
|
|
|
{
|
|
|
|
UIAlertAction* action = [UIAlertAction
|
2020-12-02 18:37:31 -05:00
|
|
|
actionWithTitle:@"Resume"
|
|
|
|
style:UIAlertActionStyleCancel
|
|
|
|
handler:nil];
|
|
|
|
[alert addAction:action];
|
2018-12-23 22:07:34 -05:00
|
|
|
}
|
2020-12-02 18:37:31 -05:00
|
|
|
|
2018-12-23 22:07:34 -05:00
|
|
|
//Exit
|
|
|
|
{
|
|
|
|
UIAlertAction* action = [UIAlertAction
|
2020-12-02 18:37:31 -05:00
|
|
|
actionWithTitle:@"Exit"
|
|
|
|
style:UIAlertActionStyleDestructive
|
|
|
|
handler:^(UIAlertAction*) {
|
|
|
|
[self onExitButtonClick];
|
|
|
|
}];
|
|
|
|
[alert addAction:action];
|
2018-12-23 22:07:34 -05:00
|
|
|
}
|
|
|
|
|
2020-12-02 18:37:31 -05:00
|
|
|
[self presentViewController:alert animated:YES completion:nil];
|
2018-12-23 22:07:34 -05:00
|
|
|
}
|
|
|
|
|
2020-12-02 18:37:31 -05:00
|
|
|
- (BOOL)prefersStatusBarHidden
|
2015-07-22 02:48:26 -04:00
|
|
|
{
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
2020-12-02 18:37:31 -05:00
|
|
|
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
|
2015-10-21 10:11:23 -04:00
|
|
|
{
|
|
|
|
return UIInterfaceOrientationMaskLandscape;
|
|
|
|
}
|
|
|
|
|
2021-06-19 15:43:12 -04:00
|
|
|
- (void)prepareForSegue:(UIStoryboardSegue*)segue sender:(id)sender
|
|
|
|
{
|
|
|
|
if([segue.identifier isEqualToString:@"showSettings"])
|
|
|
|
{
|
2021-06-22 10:15:17 -04:00
|
|
|
UINavigationController* navViewController = segue.destinationViewController;
|
|
|
|
SettingsViewController* settingsViewController = (SettingsViewController*)navViewController.visibleViewController;
|
2021-06-19 15:43:12 -04:00
|
|
|
settingsViewController.completionHandler = ^() {
|
2021-06-21 15:01:23 -04:00
|
|
|
[self setupSoundHandler];
|
2021-06-19 16:06:17 -04:00
|
|
|
[self updateOnScreenWidgets];
|
2021-06-19 15:43:12 -04:00
|
|
|
auto gsHandler = g_virtualMachine->GetGSHandler();
|
|
|
|
if(gsHandler)
|
|
|
|
{
|
|
|
|
gsHandler->NotifyPreferencesChanged();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-12 16:59:32 -04:00
|
|
|
- (void)dealloc
|
|
|
|
{
|
2020-12-02 18:37:31 -05:00
|
|
|
[[NSNotificationCenter defaultCenter] removeObserver:self.connectObserver];
|
|
|
|
[[NSNotificationCenter defaultCenter] removeObserver:self.disconnectObserver];
|
2015-08-12 16:59:32 -04:00
|
|
|
}
|
|
|
|
|
2015-07-22 02:48:26 -04:00
|
|
|
@end
|