Vulkan on iOS: Hook up remaining functionality

This commit is contained in:
Henrik Rydgård 2024-05-22 21:36:55 +02:00
parent 5f79046e01
commit b66f7ea909
3 changed files with 136 additions and 50 deletions

View File

@ -39,13 +39,6 @@
#include "Core/HLE/sceUsbCam.h" #include "Core/HLE/sceUsbCam.h"
#include "Core/HLE/sceUsbGps.h" #include "Core/HLE/sceUsbGps.h"
#include <sys/types.h>
#include <sys/sysctl.h>
#include <mach/machine.h>
#define IS_IPAD() ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
#define IS_IPHONE() ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone)
class IOSGLESContext : public GraphicsContext { class IOSGLESContext : public GraphicsContext {
public: public:
IOSGLESContext() { IOSGLESContext() {
@ -118,12 +111,8 @@ id<PPSSPPViewController> sharedViewController;
g_iCadeTracker.InitKeyMap(); g_iCadeTracker.InitKeyMap();
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillTerminate:) name:UIApplicationWillTerminateNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillTerminate:) name:UIApplicationWillTerminateNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(controllerDidConnect:) name:GCControllerDidConnectNotification object:nil];
if ([GCController class]) // Checking the availability of a GameController framework [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(controllerDidDisconnect:) name:GCControllerDidDisconnectNotification object:nil];
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(controllerDidConnect:) name:GCControllerDidConnectNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(controllerDidDisconnect:) name:GCControllerDidDisconnectNotification object:nil];
}
} }
return self; return self;
} }
@ -174,10 +163,6 @@ extern float g_safeInsetBottom;
self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
} }
UIScreenEdgePanGestureRecognizer *mBackGestureRecognizer = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeFrom:) ];
[mBackGestureRecognizer setEdges:UIRectEdgeLeft];
[[self view] addGestureRecognizer:mBackGestureRecognizer];
GLKView* view = (GLKView *)self.view; GLKView* view = (GLKView *)self.view;
view.context = self.context; view.context = self.context;
view.drawableDepthFormat = GLKViewDrawableDepthFormat24; view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
@ -200,10 +185,8 @@ extern float g_safeInsetBottom;
self.iCadeView.delegate = self; self.iCadeView.delegate = self;
self.iCadeView.active = YES;*/ self.iCadeView.active = YES;*/
if ([GCController class]) { if ([[GCController controllers] count] > 0) {
if ([[GCController controllers] count] > 0) { [self setupController:[[GCController controllers] firstObject]];
[self setupController:[[GCController controllers] firstObject]];
}
} }
cameraHelper = [[CameraHelper alloc] init]; cameraHelper = [[CameraHelper alloc] init];
@ -214,6 +197,10 @@ extern float g_safeInsetBottom;
[self hideKeyboard]; [self hideKeyboard];
UIScreenEdgePanGestureRecognizer *mBackGestureRecognizer = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeFrom:) ];
[mBackGestureRecognizer setEdges:UIRectEdgeLeft];
[[self view] addGestureRecognizer:mBackGestureRecognizer];
// Was previously DISPATCH_QUEUE_PRIORITY_HIGH. // Was previously DISPATCH_QUEUE_PRIORITY_HIGH.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NativeInitGraphics(graphicsContext); NativeInitGraphics(graphicsContext);
@ -279,9 +266,7 @@ extern float g_safeInsetBottom;
[[NSNotificationCenter defaultCenter] removeObserver:self]; [[NSNotificationCenter defaultCenter] removeObserver:self];
if ([GCController class]) { self.gameController = nil;
self.gameController = nil;
}
if (graphicsContext) { if (graphicsContext) {
graphicsContext->Shutdown(); graphicsContext->Shutdown();
@ -294,6 +279,7 @@ extern float g_safeInsetBottom;
- (void)dealloc - (void)dealloc
{ {
INFO_LOG(SYSTEM, "dealloc");
[self shutdown]; [self shutdown];
} }

View File

@ -19,3 +19,6 @@
@end @end
extern id <PPSSPPViewController> sharedViewController; extern id <PPSSPPViewController> sharedViewController;
#define IS_IPAD() ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
#define IS_IPHONE() ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone)

View File

@ -23,6 +23,8 @@
#include "Core/Config.h" #include "Core/Config.h"
#include "Core/ConfigValues.h" #include "Core/ConfigValues.h"
#include "Core/System.h" #include "Core/System.h"
#include "Core/HLE/sceUsbCam.h"
#include "Core/HLE/sceUsbGps.h"
// TODO: Share this between backends. // TODO: Share this between backends.
static uint32_t FlagsFromConfig() { static uint32_t FlagsFromConfig() {
@ -249,12 +251,8 @@ static std::mutex renderLock;
g_iCadeTracker.InitKeyMap(); g_iCadeTracker.InitKeyMap();
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillTerminate:) name:UIApplicationWillTerminateNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillTerminate:) name:UIApplicationWillTerminateNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(controllerDidConnect:) name:GCControllerDidConnectNotification object:nil];
if ([GCController class]) // Checking the availability of a GameController framework [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(controllerDidDisconnect:) name:GCControllerDidDisconnectNotification object:nil];
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(controllerDidConnect:) name:GCControllerDidConnectNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(controllerDidDisconnect:) name:GCControllerDidDisconnectNotification object:nil];
}
} }
return self; return self;
} }
@ -361,11 +359,25 @@ void VulkanRenderLoop(IOSVulkanContext *graphicsContext, CAMetalLayer *metalLaye
int desiredBackbufferSizeX = g_display.pixel_xres; int desiredBackbufferSizeX = g_display.pixel_xres;
int desiredBackbufferSizeY = g_display.pixel_yres; int desiredBackbufferSizeY = g_display.pixel_yres;
if ([[GCController controllers] count] > 0) {
[self setupController:[[GCController controllers] firstObject]];
}
INFO_LOG(G3D, "Detected size: %dx%d", desiredBackbufferSizeX, desiredBackbufferSizeY); INFO_LOG(G3D, "Detected size: %dx%d", desiredBackbufferSizeX, desiredBackbufferSizeY);
CAMetalLayer *layer = (CAMetalLayer *)self.view.layer; CAMetalLayer *layer = (CAMetalLayer *)self.view.layer;
cameraHelper = [[CameraHelper alloc] init];
[cameraHelper setDelegate:self];
locationHelper = [[LocationHelper alloc] init];
[locationHelper setDelegate:self];
[self hideKeyboard]; [self hideKeyboard];
UIScreenEdgePanGestureRecognizer *mBackGestureRecognizer = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeFrom:) ];
[mBackGestureRecognizer setEdges:UIRectEdgeLeft];
[[self view] addGestureRecognizer:mBackGestureRecognizer];
// Spin up the emu thread. It will in turn spin up the Vulkan render thread // Spin up the emu thread. It will in turn spin up the Vulkan render thread
// on its own. // on its own.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
@ -384,33 +396,19 @@ void VulkanRenderLoop(IOSVulkanContext *graphicsContext, CAMetalLayer *metalLaye
return [self view]; return [self view];
} }
/** Since this is a single-view app, initialize Vulkan as view is appearing. */ - (void)viewWillAppear:(BOOL)animated {
- (void)viewWillAppear:(BOOL) animated {
[super viewWillAppear: animated]; [super viewWillAppear: animated];
self.view.contentScaleFactor = UIScreen.mainScreen.nativeScale; self.view.contentScaleFactor = UIScreen.mainScreen.nativeScale;
uint32_t fps = 60;
/*
_displayLink = [CADisplayLink displayLinkWithTarget: self selector: @selector(renderLoop)];
[_displayLink setFrameInterval: 60 / fps];
[_displayLink addToRunLoop: NSRunLoop.currentRunLoop forMode: NSDefaultRunLoopMode];
*/
} }
/* - (void)viewDidDisappear:(BOOL)animated {
-(void) renderLoop {
demo_draw(&demo);
}
*/
- (void)viewDidDisappear: (BOOL) animated {
// [_displayLink invalidate];
// [_displayLink release];
// demo_cleanup(&demo);
[super viewDidDisappear: animated]; [super viewDidDisappear: animated];
} }
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self hideKeyboard];
}
- (BOOL)prefersHomeIndicatorAutoHidden { - (BOOL)prefersHomeIndicatorAutoHidden {
return YES; return YES;
@ -440,11 +438,42 @@ extern float g_safeInsetBottom;
} }
} }
// Enables tapping for edge area.
-(UIRectEdge)preferredScreenEdgesDeferringSystemGestures
{
return UIRectEdgeAll;
}
- (void)bindDefaultFBO - (void)bindDefaultFBO
{ {
// Do nothing // Do nothing
} }
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
g_touchTracker.Began(touches, self.view);
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
g_touchTracker.Moved(touches, self.view);
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
g_touchTracker.Ended(touches, self.view);
}
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
g_touchTracker.Cancelled(touches, self.view);
}
- (void)buttonDown:(iCadeState)button - (void)buttonDown:(iCadeState)button
{ {
g_iCadeTracker.ButtonDown(button); g_iCadeTracker.ButtonDown(button);
@ -455,6 +484,74 @@ extern float g_safeInsetBottom;
g_iCadeTracker.ButtonUp(button); g_iCadeTracker.ButtonUp(button);
} }
- (void)controllerDidConnect:(NSNotification *)note
{
if (![[GCController controllers] containsObject:self.gameController]) self.gameController = nil;
if (self.gameController != nil) return; // already have a connected controller
[self setupController:(GCController *)note.object];
}
- (void)controllerDidDisconnect:(NSNotification *)note
{
if (self.gameController == note.object) {
self.gameController = nil;
if ([[GCController controllers] count] > 0) {
[self setupController:[[GCController controllers] firstObject]];
}
}
}
- (void)setupController:(GCController *)controller
{
self.gameController = controller;
if (!SetupController(controller)) {
self.gameController = nil;
}
}
- (void)startVideo:(int)width height:(int)height {
[cameraHelper startVideo:width h:height];
}
- (void)stopVideo {
[cameraHelper stopVideo];
}
- (void)PushCameraImageIOS:(long long)len buffer:(unsigned char*)data {
Camera::pushCameraImage(len, data);
}
- (void)startLocation {
[locationHelper startLocationUpdates];
}
- (void)stopLocation {
[locationHelper stopLocationUpdates];
}
- (void)SetGpsDataIOS:(CLLocation *)newLocation {
GPS::setGpsData((long long)newLocation.timestamp.timeIntervalSince1970,
newLocation.horizontalAccuracy/5.0,
newLocation.coordinate.latitude, newLocation.coordinate.longitude,
newLocation.altitude,
MAX(newLocation.speed * 3.6, 0.0), /* m/s to km/h */
0 /* bearing */);
}
- (void)handleSwipeFrom:(UIScreenEdgePanGestureRecognizer *)recognizer
{
if (recognizer.state == UIGestureRecognizerStateEnded) {
KeyInput key;
key.flags = KEY_DOWN | KEY_UP;
key.keyCode = NKCODE_BACK;
key.deviceId = DEVICE_ID_TOUCH;
NativeKey(key);
INFO_LOG(SYSTEM, "Detected back swipe");
}
}
// The below is inspired by https://stackoverflow.com/questions/7253477/how-to-display-the-iphone-ipad-keyboard-over-a-full-screen-opengl-es-app // The below is inspired by https://stackoverflow.com/questions/7253477/how-to-display-the-iphone-ipad-keyboard-over-a-full-screen-opengl-es-app
// It's a bit limited but good enough. // It's a bit limited but good enough.