From a4dfd35ab72b6f6e2f94331fe12ec17b2728fe29 Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 15 Aug 2013 19:28:51 -0400 Subject: [PATCH] (Apple) Improvements: Add core gl context support on OSX Add support for multiple game pads on OSX Remove block on analog input for Player 2-4's game pads --- apple/OSX/hid_pad.c | 12 ++++++- apple/OSX/platform.h | 2 +- apple/RetroArch/RAGameView.m | 60 +++++++++++++++++++++++++--------- apple/RetroArch/apple_joypad.c | 2 +- gfx/context/apple_gl_ctx.c | 2 +- gfx/gl.c | 4 +-- 6 files changed, 61 insertions(+), 21 deletions(-) diff --git a/apple/OSX/hid_pad.c b/apple/OSX/hid_pad.c index 79c453e9b3..33bb819b9e 100644 --- a/apple/OSX/hid_pad.c +++ b/apple/OSX/hid_pad.c @@ -19,6 +19,7 @@ // NOTE: I pieced this together through trial and error, any corrections are welcome static IOHIDManagerRef g_hid_manager; +static uint32_t g_num_pads; static void hid_input_callback(void* inContext, IOReturn inResult, void* inSender, IOHIDValueRef inIOHIDValueRef) { @@ -83,9 +84,18 @@ static void hid_input_callback(void* inContext, IOReturn inResult, void* inSende static void hid_device_attached(void* inContext, IOReturn inResult, void* inSender, IOHIDDeviceRef inDevice) { + void* context = 0; + + if (IOHIDDeviceConformsTo(inDevice, kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick)) + { + if (g_num_pads > 4) + return; + context = (void*)(g_num_pads++); + } + IOHIDDeviceOpen(inDevice, kIOHIDOptionsTypeNone); IOHIDDeviceScheduleWithRunLoop(inDevice, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); - IOHIDDeviceRegisterInputValueCallback(inDevice, hid_input_callback, 0); + IOHIDDeviceRegisterInputValueCallback(inDevice, hid_input_callback, context); } static void hid_device_removed(void* inContext, IOReturn inResult, void* inSender, IOHIDDeviceRef inDevice) diff --git a/apple/OSX/platform.h b/apple/OSX/platform.h index f858ade962..b35cf774af 100644 --- a/apple/OSX/platform.h +++ b/apple/OSX/platform.h @@ -19,7 +19,7 @@ #import -@interface RAGameView : NSOpenGLView +@interface RAGameView : NSView + (RAGameView*)get; - (void)display; diff --git a/apple/RetroArch/RAGameView.m b/apple/RetroArch/RAGameView.m index daa9fd97e9..4b9c592f33 100644 --- a/apple/RetroArch/RAGameView.m +++ b/apple/RetroArch/RAGameView.m @@ -35,6 +35,7 @@ static UIView* g_pause_indicator_view; static RAGameView* g_instance; static NSOpenGLContext* g_context; +static NSOpenGLPixelFormat* g_format; #define g_view g_instance // < RAGameView is a container on iOS; on OSX these are both the same object @@ -57,25 +58,22 @@ static float g_screen_scale = 1.0f; - (id)init { - static const NSOpenGLPixelFormatAttribute attributes [] = { - NSOpenGLPFAWindow, - NSOpenGLPFADoubleBuffer, // double buffered - NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute)16, // 16 bit depth buffer - (NSOpenGLPixelFormatAttribute)nil - }; - - self = [super initWithFrame:CGRectMake(0, 0, 100, 100) pixelFormat:[[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]]; - self.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; - - g_context = self.openGLContext; - [g_context makeCurrentContext]; - + self = [super init]; + self.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; return self; } +- (void)setFrame:(NSRect)frameRect +{ + [super setFrame:frameRect]; + + if (g_view && g_context) + [g_context update]; +} + - (void)display { - [self.openGLContext flushBuffer]; + [g_context flushBuffer]; } - (void)bindDrawable @@ -237,6 +235,38 @@ void apple_destroy_game_view() #endif } +bool apple_create_gl_context(uint32_t version) +{ +#ifdef OSX + [NSOpenGLContext clearCurrentContext]; + + dispatch_sync(dispatch_get_main_queue(), ^{ + [NSOpenGLContext clearCurrentContext]; + [g_context clearDrawable]; + g_context = nil; + g_format = nil; + + NSOpenGLPixelFormatAttribute attributes [] = { + NSOpenGLPFADoubleBuffer, // double buffered + NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute)16, // 16 bit depth buffer + version ? NSOpenGLPFAOpenGLProfile : 0, version, + (NSOpenGLPixelFormatAttribute)nil + }; + + g_format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]; + g_context = [[NSOpenGLContext alloc] initWithFormat:g_format shareContext:nil]; + g_context.view = g_view; + [g_context makeCurrentContext]; + }); + + [g_context makeCurrentContext]; + +#endif + + return true; + +} + void apple_flip_game_view() { if (--g_fast_forward_skips < 0) @@ -255,7 +285,7 @@ void apple_set_game_view_sync(unsigned interval) g_fast_forward_skips = interval ? 0 : 3; #elif defined(OSX) GLint value = interval ? 1 : 0; - [g_view.openGLContext setValues:&value forParameter:NSOpenGLCPSwapInterval]; + [g_context setValues:&value forParameter:NSOpenGLCPSwapInterval]; #endif } diff --git a/apple/RetroArch/apple_joypad.c b/apple/RetroArch/apple_joypad.c index 312f245b43..76a8dc2853 100644 --- a/apple/RetroArch/apple_joypad.c +++ b/apple/RetroArch/apple_joypad.c @@ -56,7 +56,7 @@ static bool apple_joypad_button(unsigned port, uint16_t joykey) static int16_t apple_joypad_axis(unsigned port, uint32_t joyaxis) { - if (joyaxis == AXIS_NONE || port != 0) + if (joyaxis == AXIS_NONE) return 0; int16_t val = 0; diff --git a/gfx/context/apple_gl_ctx.c b/gfx/context/apple_gl_ctx.c index 3fc50861b2..d8db42630f 100644 --- a/gfx/context/apple_gl_ctx.c +++ b/gfx/context/apple_gl_ctx.c @@ -34,7 +34,7 @@ static bool gfx_ctx_bind_api(enum gfx_ctx_api api, unsigned major, unsigned mino #ifdef IOS return api == GFX_CTX_OPENGL_ES_API; #else - return api == GFX_CTX_OPENGL_API; + return apple_create_gl_context((major << 12) | (minor << 8)); #endif } diff --git a/gfx/gl.c b/gfx/gl.c index 768e79631c..7a62910a78 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -153,7 +153,7 @@ static bool check_sync_proc(gl_t *gl) #ifndef HAVE_OPENGLES static bool init_vao(gl_t *gl) { - if (!gl_query_extension(gl, "ARB_vertex_array_object")) + if (!gl->core_context && !gl_query_extension(gl, "ARB_vertex_array_object")) return false; bool present = glGenVertexArrays && glBindVertexArray && glDeleteVertexArrays; @@ -184,7 +184,7 @@ static bool init_vao(gl_t *gl) #elif !defined(HAVE_OPENGLES2) static bool check_fbo_proc(gl_t *gl) { - if (!gl_query_extension(gl, "ARB_framebuffer_object")) + if (!gl->core_context && !gl_query_extension(gl, "ARB_framebuffer_object")) return false; return glGenFramebuffers && glBindFramebuffer && glFramebufferTexture2D &&