2015-07-22 02:48:26 -04:00
|
|
|
#include "PathUtils.h"
|
|
|
|
#import "EmulatorViewController.h"
|
|
|
|
#import "GlEsView.h"
|
|
|
|
#include "../PS2VM.h"
|
|
|
|
#include "../PS2VM_Preferences.h"
|
|
|
|
#include "../AppConfig.h"
|
|
|
|
#include "GSH_OpenGLiOS.h"
|
2015-07-26 01:02:39 -04:00
|
|
|
#include "IosUtils.h"
|
2015-10-31 20:38:27 -04:00
|
|
|
#include "PH_Generic.h"
|
2015-07-22 02:48:26 -04:00
|
|
|
|
|
|
|
CPS2VM* g_virtualMachine = nullptr;
|
|
|
|
|
|
|
|
@interface EmulatorViewController ()
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation EmulatorViewController
|
|
|
|
|
|
|
|
-(void)viewDidLoad
|
|
|
|
{
|
|
|
|
CGRect screenBounds = [[UIScreen mainScreen] bounds];
|
|
|
|
|
|
|
|
auto view = [[GlEsView alloc] initWithFrame: screenBounds];
|
|
|
|
self.view = view;
|
2015-08-12 16:59:32 -04: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
|
|
|
}
|
|
|
|
|
|
|
|
-(void)viewDidAppear: (BOOL)animated
|
|
|
|
{
|
2015-07-22 02:48:26 -04:00
|
|
|
g_virtualMachine = new CPS2VM();
|
|
|
|
g_virtualMachine->Initialize();
|
2015-10-21 10:11:23 -04:00
|
|
|
g_virtualMachine->CreateGSHandler(CGSH_OpenGLiOS::GetFactoryFunction((CAEAGLLayer*)self.view.layer));
|
2015-07-22 02:48:26 -04:00
|
|
|
|
2015-10-31 20:38:27 -04:00
|
|
|
g_virtualMachine->CreatePadHandler(CPH_Generic::GetFactoryFunction());
|
2015-10-26 22:26:34 -04:00
|
|
|
|
|
|
|
CGRect screenBounds = [[UIScreen mainScreen] bounds];
|
|
|
|
self.virtualPadView = [[VirtualPadView alloc] initWithFrame: screenBounds
|
2015-10-31 20:38:27 -04:00
|
|
|
padHandler: static_cast<CPH_Generic*>(g_virtualMachine->GetPadHandler())];
|
2015-10-26 22:26:34 -04:00
|
|
|
[self.view addSubview: self.virtualPadView];
|
|
|
|
|
2015-11-24 10:31:44 -05:00
|
|
|
[self setupFpsCounter];
|
2015-12-02 10:19:28 -05:00
|
|
|
|
|
|
|
UIButton* but = [UIButton buttonWithType: UIButtonTypeRoundedRect];
|
|
|
|
[but setTitle: @"Save" forState: UIControlStateNormal];
|
|
|
|
[but setBackgroundColor: [UIColor whiteColor]];
|
|
|
|
[but addTarget: self action: @selector(onSaveStateButtonClick) forControlEvents: UIControlEventTouchUpInside];
|
|
|
|
but.frame = CGRectMake(screenBounds.size.width - 50, (screenBounds.size.height - 25) / 2, 50, 25);
|
|
|
|
[self.view addSubview: but];
|
2015-11-24 10:31:44 -05:00
|
|
|
|
2015-07-22 02:48:26 -04:00
|
|
|
g_virtualMachine->Pause();
|
|
|
|
g_virtualMachine->Reset();
|
|
|
|
|
2015-07-26 01:02:39 -04:00
|
|
|
if(IosUtils::IsLoadableExecutableFileName(self.imagePath))
|
|
|
|
{
|
|
|
|
g_virtualMachine->m_ee->m_os->BootFromFile([self.imagePath UTF8String]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
CAppConfig::GetInstance().SetPreferenceString(PS2VM_CDROM0PATH, [self.imagePath UTF8String]);
|
|
|
|
g_virtualMachine->Reset();
|
|
|
|
g_virtualMachine->m_ee->m_os->BootFromCDROM(CPS2OS::ArgumentList());
|
|
|
|
}
|
2015-07-22 02:48:26 -04:00
|
|
|
|
|
|
|
g_virtualMachine->Resume();
|
|
|
|
}
|
|
|
|
|
2015-08-12 16:59:32 -04:00
|
|
|
- (void)toggleHardwareController:(BOOL)useHardware {
|
|
|
|
if (useHardware) {
|
|
|
|
self.gController = [GCController controllers][0];
|
|
|
|
if (self.gController.gamepad) {
|
|
|
|
[self.gController.gamepad.buttonA setValueChangedHandler:^(GCControllerButtonInput *button, float value, BOOL pressed) {
|
|
|
|
|
|
|
|
auto padHandler = g_virtualMachine->GetPadHandler();
|
|
|
|
if(padHandler)
|
|
|
|
{
|
2015-10-31 20:38:27 -04:00
|
|
|
static_cast<CPH_Generic*>(padHandler)->SetButtonState(PS2::CControllerInfo::SQUARE, pressed);
|
2015-08-12 16:59:32 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
}];
|
|
|
|
[self.gController.gamepad.buttonB setValueChangedHandler:^(GCControllerButtonInput *button, float value, BOOL pressed) {
|
|
|
|
|
|
|
|
auto padHandler = g_virtualMachine->GetPadHandler();
|
|
|
|
if(padHandler)
|
|
|
|
{
|
2015-10-31 20:38:27 -04:00
|
|
|
static_cast<CPH_Generic*>(padHandler)->SetButtonState(PS2::CControllerInfo::CIRCLE, pressed);
|
2015-08-12 16:59:32 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
}];
|
|
|
|
[self.gController.gamepad.buttonX setValueChangedHandler:^(GCControllerButtonInput *button, float value, BOOL pressed) {
|
|
|
|
|
|
|
|
auto padHandler = g_virtualMachine->GetPadHandler();
|
|
|
|
if(padHandler)
|
|
|
|
{
|
2015-10-31 20:38:27 -04:00
|
|
|
static_cast<CPH_Generic*>(padHandler)->SetButtonState(PS2::CControllerInfo::CROSS, pressed);
|
2015-08-12 16:59:32 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
}];
|
|
|
|
[self.gController.gamepad.buttonY setValueChangedHandler:^(GCControllerButtonInput *button, float value, BOOL pressed) {
|
|
|
|
|
|
|
|
auto padHandler = g_virtualMachine->GetPadHandler();
|
|
|
|
if(padHandler)
|
|
|
|
{
|
2015-10-31 20:38:27 -04:00
|
|
|
static_cast<CPH_Generic*>(padHandler)->SetButtonState(PS2::CControllerInfo::TRIANGLE, pressed);
|
2015-08-12 16:59:32 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
}];
|
|
|
|
[self.gController.gamepad.dpad setValueChangedHandler:^(GCControllerDirectionPad *dpad, float xValue, float yValue){
|
|
|
|
auto padHandler = g_virtualMachine->GetPadHandler();
|
|
|
|
if(padHandler)
|
|
|
|
{
|
2015-10-31 20:38:27 -04:00
|
|
|
static_cast<CPH_Generic*>(padHandler)->SetAxisState(PS2::CControllerInfo::ANALOG_LEFT_X, xValue);
|
|
|
|
static_cast<CPH_Generic*>(padHandler)->SetAxisState(PS2::CControllerInfo::ANALOG_LEFT_Y, yValue);
|
2015-08-12 16:59:32 -04:00
|
|
|
}
|
|
|
|
}];
|
|
|
|
//Add controller pause handler here
|
|
|
|
}
|
|
|
|
if (self.gController.extendedGamepad) {
|
|
|
|
[self.gController.extendedGamepad.buttonA setValueChangedHandler:^(GCControllerButtonInput *button, float value, BOOL pressed) {
|
|
|
|
|
|
|
|
auto padHandler = g_virtualMachine->GetPadHandler();
|
|
|
|
if(padHandler)
|
|
|
|
{
|
2015-10-31 20:38:27 -04:00
|
|
|
static_cast<CPH_Generic*>(padHandler)->SetButtonState(PS2::CControllerInfo::SQUARE, pressed);
|
2015-08-12 16:59:32 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
}];
|
|
|
|
[self.gController.extendedGamepad.buttonB setValueChangedHandler:^(GCControllerButtonInput *button, float value, BOOL pressed) {
|
|
|
|
|
|
|
|
auto padHandler = g_virtualMachine->GetPadHandler();
|
|
|
|
if(padHandler)
|
|
|
|
{
|
2015-10-31 20:38:27 -04:00
|
|
|
static_cast<CPH_Generic*>(padHandler)->SetButtonState(PS2::CControllerInfo::CIRCLE, pressed);
|
2015-08-12 16:59:32 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
}];
|
|
|
|
[self.gController.extendedGamepad.buttonX setValueChangedHandler:^(GCControllerButtonInput *button, float value, BOOL pressed) {
|
|
|
|
|
|
|
|
auto padHandler = g_virtualMachine->GetPadHandler();
|
|
|
|
if(padHandler)
|
|
|
|
{
|
2015-10-31 20:38:27 -04:00
|
|
|
static_cast<CPH_Generic*>(padHandler)->SetButtonState(PS2::CControllerInfo::CROSS, pressed);
|
2015-08-12 16:59:32 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
}];
|
|
|
|
[self.gController.extendedGamepad.buttonY setValueChangedHandler:^(GCControllerButtonInput *button, float value, BOOL pressed) {
|
|
|
|
|
|
|
|
auto padHandler = g_virtualMachine->GetPadHandler();
|
|
|
|
if(padHandler)
|
|
|
|
{
|
2015-10-31 20:38:27 -04:00
|
|
|
static_cast<CPH_Generic*>(padHandler)->SetButtonState(PS2::CControllerInfo::TRIANGLE, pressed);
|
2015-08-12 16:59:32 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
}];
|
|
|
|
[self.gController.extendedGamepad.dpad setValueChangedHandler:^(GCControllerDirectionPad *dpad, float xValue, float yValue){
|
|
|
|
auto padHandler = g_virtualMachine->GetPadHandler();
|
|
|
|
if(padHandler)
|
|
|
|
{
|
2015-10-31 20:38:27 -04:00
|
|
|
static_cast<CPH_Generic*>(padHandler)->SetAxisState(PS2::CControllerInfo::ANALOG_LEFT_X, xValue);
|
|
|
|
static_cast<CPH_Generic*>(padHandler)->SetAxisState(PS2::CControllerInfo::ANALOG_LEFT_Y, yValue);
|
2015-08-12 16:59:32 -04:00
|
|
|
}
|
|
|
|
}];
|
|
|
|
[self.gController.extendedGamepad.leftThumbstick.xAxis setValueChangedHandler:^(GCControllerAxisInput *axis, float value){
|
|
|
|
auto padHandler = g_virtualMachine->GetPadHandler();
|
|
|
|
if(padHandler)
|
|
|
|
{
|
2015-10-31 20:38:27 -04:00
|
|
|
static_cast<CPH_Generic*>(padHandler)->SetAxisState(PS2::CControllerInfo::ANALOG_LEFT_X, value);
|
2015-08-12 16:59:32 -04:00
|
|
|
}
|
|
|
|
}];
|
|
|
|
[self.gController.extendedGamepad.leftThumbstick.yAxis setValueChangedHandler:^(GCControllerAxisInput *axis, float value){
|
|
|
|
auto padHandler = g_virtualMachine->GetPadHandler();
|
|
|
|
if(padHandler)
|
|
|
|
{
|
2015-10-31 20:38:27 -04:00
|
|
|
static_cast<CPH_Generic*>(padHandler)->SetAxisState(PS2::CControllerInfo::ANALOG_LEFT_Y, value);
|
2015-08-12 16:59:32 -04:00
|
|
|
}
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
self.gController = nil;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-24 10:31:44 -05:00
|
|
|
-(void)setupFpsCounter
|
|
|
|
{
|
|
|
|
auto screenBounds = [[UIScreen mainScreen] bounds];
|
|
|
|
|
|
|
|
self.fpsCounterLabel = [[UILabel alloc] initWithFrame: screenBounds];
|
|
|
|
self.fpsCounterLabel.textColor = [UIColor whiteColor];
|
|
|
|
[self.view addSubview: self.fpsCounterLabel];
|
|
|
|
|
|
|
|
g_virtualMachine->GetGSHandler()->OnNewFrame.connect(
|
|
|
|
[self] (uint32 drawCallCount)
|
|
|
|
{
|
|
|
|
@synchronized(self)
|
|
|
|
{
|
|
|
|
self.frames++;
|
|
|
|
self.drawCallCount += drawCallCount;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
[NSTimer scheduledTimerWithTimeInterval: 1 target: self selector: @selector(updateFpsCounter) userInfo: nil repeats: YES];
|
|
|
|
}
|
|
|
|
|
|
|
|
-(void)updateFpsCounter
|
|
|
|
{
|
|
|
|
@synchronized(self)
|
|
|
|
{
|
|
|
|
uint32 dcpf = (self.frames != 0) ? (self.drawCallCount / self.frames) : 0;
|
|
|
|
self.fpsCounterLabel.text = [NSString stringWithFormat: @"%d f/s, %d dc/f",
|
|
|
|
self.frames, dcpf];
|
|
|
|
self.frames = 0;
|
|
|
|
self.drawCallCount = 0;
|
|
|
|
}
|
|
|
|
[self.fpsCounterLabel sizeToFit];
|
|
|
|
}
|
|
|
|
|
2015-12-02 10:19:28 -05:00
|
|
|
-(void)onSaveStateButtonClick
|
|
|
|
{
|
|
|
|
auto dataPath = Framework::PathUtils::GetPersonalDataPath();
|
|
|
|
auto statePath = dataPath / "state.sta";
|
|
|
|
g_virtualMachine->SaveState(statePath.c_str());
|
|
|
|
NSLog(@"Saved state to '%s'.", statePath.string().c_str());
|
|
|
|
}
|
|
|
|
|
2015-07-22 02:48:26 -04:00
|
|
|
-(BOOL)prefersStatusBarHidden
|
|
|
|
{
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
2015-10-21 10:11:23 -04:00
|
|
|
-(UIInterfaceOrientationMask)supportedInterfaceOrientations
|
|
|
|
{
|
|
|
|
return UIInterfaceOrientationMaskLandscape;
|
|
|
|
}
|
|
|
|
|
2015-08-12 16:59:32 -04:00
|
|
|
- (void)dealloc
|
|
|
|
{
|
|
|
|
[[NSNotificationCenter defaultCenter] removeObserver:self.connectObserver];
|
|
|
|
[[NSNotificationCenter defaultCenter] removeObserver:self.disconnectObserver];
|
|
|
|
}
|
|
|
|
|
2015-07-22 02:48:26 -04:00
|
|
|
@end
|