ios: Hopefully fix the crash when suspended for real this time. Make many things worse, but will fix them from the working state.

This commit is contained in:
meancoot 2013-02-14 21:35:24 -05:00
parent 566f8ace45
commit 6a77d72966
8 changed files with 192 additions and 115 deletions

View File

@ -35,7 +35,8 @@ static void gfx_ctx_set_swap_interval(unsigned interval)
static void gfx_ctx_destroy(void)
{
RARCH_LOG("gfx_ctx_destroy().\n");
extern void ios_destroy_game_view();
ios_destroy_game_view();
}
static void gfx_ctx_get_video_size(unsigned *width, unsigned *height)
@ -46,7 +47,8 @@ static void gfx_ctx_get_video_size(unsigned *width, unsigned *height)
static bool gfx_ctx_init(void)
{
return true;
extern bool ios_init_game_view();
return ios_init_game_view();
}
static void gfx_ctx_swap_buffers(void)

View File

@ -84,6 +84,7 @@
96AFAFAD16C1EEE9009DE44C /* sinc.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEF716C1DC73009DE44C /* sinc.c */; };
96AFAFD416C1FBC0009DE44C /* input_common.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFC916C1FBC0009DE44C /* input_common.c */; };
96AFAFD716C1FBC0009DE44C /* null.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFCD16C1FBC0009DE44C /* null.c */; };
96C6A5D216CDB384009E3280 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96C6A5D116CDB384009E3280 /* QuartzCore.framework */; };
96CF015016C2C0B700ABF9C9 /* overlay.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAFCE16C1FBC0009DE44C /* overlay.c */; };
96CF015C16C2F72900ABF9C9 /* ios_input.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CF015B16C2F72900ABF9C9 /* ios_input.c */; };
/* End PBXBuildFile section */
@ -290,6 +291,7 @@
96AFAFD016C1FBC0009DE44C /* sdl_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sdl_input.c; sourceTree = "<group>"; };
96AFAFD116C1FBC0009DE44C /* sdl_joypad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sdl_joypad.c; sourceTree = "<group>"; };
96AFAFD216C1FBC0009DE44C /* x11_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = x11_input.c; sourceTree = "<group>"; };
96C6A5D116CDB384009E3280 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
96CF015B16C2F72900ABF9C9 /* ios_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ios_input.c; sourceTree = "<group>"; };
/* End PBXFileReference section */
@ -298,6 +300,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
96C6A5D216CDB384009E3280 /* QuartzCore.framework in Frameworks */,
96366C5916C9ACF500D64A22 /* AudioToolbox.framework in Frameworks */,
96366C5516C9AC3300D64A22 /* CoreAudio.framework in Frameworks */,
96AFAF2216C1DF88009DE44C /* libz.dylib in Frameworks */,
@ -351,6 +354,7 @@
96AFAE2816C1D4EA009DE44C /* Frameworks */ = {
isa = PBXGroup;
children = (
96C6A5D116CDB384009E3280 /* QuartzCore.framework */,
96366C5816C9ACF500D64A22 /* AudioToolbox.framework */,
96366C5416C9AC3300D64A22 /* CoreAudio.framework */,
96AFAE2916C1D4EA009DE44C /* UIKit.framework */,
@ -981,7 +985,6 @@
"-DHAVE_GLSL",
"-DINLINE=inline",
"-DLSB_FIRST",
"-DHAVE_THREAD",
"-D__LIBRETRO__",
"-DRARCH_PERFORMANCE_MODE",
"-DPACKAGE_VERSION=\\\"1.0\\\"",
@ -1019,7 +1022,6 @@
"-DHAVE_GLSL",
"-DINLINE=inline",
"-DLSB_FIRST",
"-DHAVE_THREAD",
"-D__LIBRETRO__",
"-DRARCH_PERFORMANCE_MODE",
"-DPACKAGE_VERSION=\\\"1.0\\\"",

View File

@ -14,77 +14,71 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#import <QuartzCore/QuartzCore.h>
#include "general.h"
static GLKView *gl_view;
static bool _isRunning;
static float screen_scale;
static int frame_skips = 4;
static bool is_syncing = true;
static bool active_iterate()
{
while(CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true) == kCFRunLoopRunHandledSource);
return rarch_main_iterate();
}
static bool idle_iterate()
{
CFRunLoopRunInMode(kCFRunLoopDefaultMode, .5, false);
return true;
}
@implementation RAGameView
{
EAGLContext *gl_context;
NSString* game;
bool paused;
bool exiting;
EAGLContext* _glContext;
CADisplayLink* _timer;
}
- (id)initWithGame:(NSString*)path
- (id)init
{
self = [super init];
game = path;
screen_scale = [[UIScreen mainScreen] scale];
_glContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
[EAGLContext setCurrentContext:_glContext];
self.view = [[GLKView alloc] initWithFrame:CGRectMake(0, 0, 640, 480) context:_glContext];
self.view.multipleTouchEnabled = YES;
_timer = [CADisplayLink displayLinkWithTarget:self selector:@selector(iterate)];
[_timer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
return self;
}
- (void)iterate
{
if (_isRunning) rarch_main_iterate();
}
- (void)needsToDie
{
[_timer invalidate];
_timer = nil;
glFinish();
GLKView* glview = (GLKView*)self.view;
glview.context = nil;
_glContext = nil;
[EAGLContext setCurrentContext:nil];
}
- (void)pause
{
paused = true;
_timer.paused = true;
}
- (void)resume
{
paused = false;
if (_isRunning) _timer.paused = false;
}
- (void)exit
{
exiting = true;
}
@end
- (void)dealloc
{
if ([EAGLContext currentContext] == gl_context) [EAGLContext setCurrentContext:nil];
gl_context = nil;
gl_view = nil;
}
static RAGameView* gameViewer;
- (void)loadView
{
gl_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
[EAGLContext setCurrentContext:gl_context];
gl_view = [[GLKView alloc] initWithFrame:CGRectMake(0, 0, 640, 480) context:gl_context];
gl_view.multipleTouchEnabled = YES;
self.view = gl_view;
[self performSelector:@selector(runGame) withObject:nil afterDelay:0.2f];
}
- (void)runGame
void ios_load_game(const char* path)
{
[RASettingsList refreshConfigFile];
@ -92,30 +86,86 @@ static bool idle_iterate()
const char* const cf =[[RetroArch_iOS get].config_file_path UTF8String];
const char* const libretro = [[RetroArch_iOS get].module_path UTF8String];
struct rarch_main_wrap main_wrapper = {[game UTF8String], sd, sd, cf, libretro};
struct rarch_main_wrap main_wrapper = {path, sd, sd, cf, libretro};
if (rarch_main_init_wrap(&main_wrapper) == 0)
{
rarch_init_msg_queue();
while (!exiting && (paused ? idle_iterate() : active_iterate()));
_isRunning = true;
}
else
_isRunning = false;
}
void ios_close_game()
{
if (_isRunning)
{
rarch_main_deinit();
rarch_deinit_msg_queue();
#ifdef PERF_TEST
rarch_perf_log();
#endif
rarch_main_clear_state();
_isRunning = false;
}
[[RetroArch_iOS get] gameHasExited];
}
@end
void ios_pause_emulator()
{
if (gameViewer)
[gameViewer pause];
}
void ios_resume_emulator()
{
if (gameViewer)
[gameViewer resume];
}
void ios_suspend_emulator()
{
if (gameViewer)
uninit_drivers();
}
void ios_activate_emulator()
{
if (!gameViewer)
init_drivers();
}
bool ios_init_game_view()
{
if (!gameViewer)
{
gameViewer = [RAGameView new];
[[RetroArch_iOS get] setViewer:gameViewer];
}
return true;
}
void ios_destroy_game_view()
{
if (gameViewer)
{
[gameViewer needsToDie];
[[RetroArch_iOS get] setViewer:nil];
gameViewer = nil;
}
}
void ios_flip_game_view()
{
if (gl_view)
if (gameViewer)
{
GLKView* gl_view = (GLKView*)gameViewer.view;
if (--frame_skips < 0)
{
[gl_view setNeedsDisplay];
@ -133,8 +183,10 @@ void ios_set_game_view_sync(bool on)
void ios_get_game_view_size(unsigned *width, unsigned *height)
{
if (gl_view)
if (gameViewer)
{
GLKView* gl_view = (GLKView*)gameViewer.view;
*width = gl_view.bounds.size.width * screen_scale;
*height = gl_view.bounds.size.height * screen_scale;
}
@ -142,8 +194,9 @@ void ios_get_game_view_size(unsigned *width, unsigned *height)
void ios_bind_game_view_fbo()
{
if (gl_view)
if (gameViewer)
{
GLKView* gl_view = (GLKView*)gameViewer.view;
[gl_view bindDrawable];
}
}

View File

@ -19,6 +19,8 @@ extern NSString* const GSEventKeyUpNotification;
- (void)pushViewController:(UIViewController*)theView;
- (void)popViewController;
- (void)setViewer:(UIViewController*)theView;
@property (strong, nonatomic) NSString* system_directory;
@property (strong, nonatomic) NSString* config_file_path;

View File

@ -6,6 +6,7 @@
//
#include <sys/stat.h>
#include "rarch_wrapper.h"
#define MAX_TOUCH 16
extern struct
@ -22,8 +23,6 @@ extern uint32_t ios_current_touch_count;
@implementation RetroArch_iOS
{
RAGameView* _game;
UIWindow* _window;
UINavigationController* _navigator;
}
@ -35,15 +34,11 @@ extern uint32_t ios_current_touch_count;
- (void)runGame:(NSString*)path
{
_game = [[RAGameView alloc] initWithGame:path];
_window.rootViewController = _game;
_navigator = nil;
ios_load_game([path UTF8String]);
}
- (void)gameHasExited
{
_game = nil;
_navigator = [[UINavigationController alloc] init];
[_navigator pushViewController: [[RAModuleList alloc] init] animated:YES];
@ -53,17 +48,19 @@ extern uint32_t ios_current_touch_count;
- (void)pushViewController:(UIViewController*)theView
{
if (_navigator != nil)
{
[_navigator pushViewController:theView animated:YES];
}
}
- (void)popViewController
{
if (_navigator != nil)
{
[_navigator popViewControllerAnimated:YES];
}
}
- (void)setViewer:(UIViewController*)theView
{
_navigator = nil;
_window.rootViewController = theView;
}
- (void)applicationDidFinishLaunching:(UIApplication *)application
@ -99,16 +96,24 @@ extern uint32_t ios_current_touch_count;
[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(keyReleased:) name: GSEventKeyUpNotification object: nil];
}
- (void)applicationDidBecomeActive:(UIApplication*)application
{
ios_resume_emulator();
}
- (void)applicationWillResignActive:(UIApplication*)application
{
ios_pause_emulator();
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
if (_game)
[_game resume];
ios_activate_emulator();
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
if (_game)
[_game pause];
ios_suspend_emulator();
}
-(void) keyPressed: (NSNotification*) notification
@ -130,34 +135,32 @@ extern uint32_t ios_current_touch_count;
- (void)processTouches:(NSArray*)touches
{
if (_game)
{
ios_current_touch_count = [touches count];
ios_current_touch_count = [touches count];
for(int i = 0; i != [touches count]; i ++)
{
UITouch *touch = [touches objectAtIndex:i];
CGPoint coord = [touch locationInView:_game.view];
float scale = [[UIScreen mainScreen] scale];
UIView* view = _window.rootViewController.view;
for(int i = 0; i != [touches count]; i ++)
{
UITouch *touch = [touches objectAtIndex:i];
CGPoint coord = [touch locationInView:view];
float scale = [[UIScreen mainScreen] scale];
// Exit hack!
if (touch.tapCount == 3)
// Exit hack!
if (touch.tapCount == 3)
{
if (coord.y < view.bounds.size.height / 10.0f)
{
if (coord.y < _game.view.bounds.size.height / 10.0f)
float tenpct = view.bounds.size.width / 10.0f;
if (coord.x >= tenpct * 4 && coord.x <= tenpct * 6)
{
float tenpct = _game.view.bounds.size.width / 10.0f;
if (coord.x >= tenpct * 4 && coord.x <= tenpct * 6)
{
[_game exit];
}
ios_close_game();
}
}
ios_touches[i].is_down = (touch.phase != UITouchPhaseEnded) && (touch.phase != UITouchPhaseCancelled);
ios_touches[i].screen_x = coord.x * scale;
ios_touches[i].screen_y = coord.y * scale;
}
ios_touches[i].is_down = (touch.phase != UITouchPhaseEnded) && (touch.phase != UITouchPhaseCancelled);
ios_touches[i].screen_x = coord.x * scale;
ios_touches[i].screen_y = coord.y * scale;
}
}

View File

@ -26,29 +26,31 @@ NSString *const GSEventKeyUpNotification = @"GSEventKeyUpHackNotification";
// Stolen from: http://nacho4d-nacho4d.blogspot.com/2012/01/catching-keyboard-events-in-ios.html
- (void)sendEvent:(UIEvent *)event
{
[super sendEvent:event];
[super sendEvent:event];
if ([event respondsToSelector:@selector(_gsEvent)])
{
int* eventMem = (int *)(void*)CFBridgingRetain([event performSelector:@selector(_gsEvent)]);
int eventType = eventMem ? eventMem[GSEVENT_TYPE] : 0;
if ([event respondsToSelector:@selector(_gsEvent)])
{
int* eventMem = (int *)(void*)CFBridgingRetain([event performSelector:@selector(_gsEvent)]);
int eventType = eventMem ? eventMem[GSEVENT_TYPE] : 0;
if (eventMem && (eventType == GSEVENT_TYPE_KEYDOWN || eventType == GSEVENT_TYPE_KEYUP))
{
// Read keycode from GSEventKey
int tmp = eventMem[GSEVENTKEY_KEYCODE];
UniChar *keycode = (UniChar *)&tmp;
if (eventMem && (eventType == GSEVENT_TYPE_KEYDOWN || eventType == GSEVENT_TYPE_KEYUP))
{
// Read keycode from GSEventKey
int tmp = eventMem[GSEVENTKEY_KEYCODE];
UniChar *keycode = (UniChar *)&tmp;
// Post notification
NSDictionary *inf = [[NSDictionary alloc] initWithObjectsAndKeys:
[NSNumber numberWithShort:keycode[0]], @"keycode",
nil];
// Post notification
NSDictionary *inf = [[NSDictionary alloc] initWithObjectsAndKeys:
[NSNumber numberWithShort:keycode[0]], @"keycode",
nil];
[[NSNotificationCenter defaultCenter]
postNotificationName:(eventType == GSEVENT_TYPE_KEYDOWN) ? GSEventKeyDownNotification : GSEventKeyUpNotification
object:nil userInfo:inf];
}
}
[[NSNotificationCenter defaultCenter]
postNotificationName:(eventType == GSEVENT_TYPE_KEYDOWN) ? GSEventKeyDownNotification : GSEventKeyUpNotification
object:nil userInfo:inf];
}
CFBridgingRelease(eventMem);
}
}
#endif

View File

@ -0,0 +1,17 @@
#ifndef __IOS_RARCH_WRAPPER_H__
#define __IOS_RARCH_WRAPPER_H__
bool ios_load_game(const char* path);
void ios_close_game();
void ios_pause_emulator();
void ios_resume_emulator();
void ios_suspend_emulator();
void ios_activate_emulator();
bool ios_init_game_view();
void ios_destroy_game_view();
void ios_flip_game_view();
void ios_set_game_view_sync(bool on);
void ios_get_game_view_size(unsigned *width, unsigned *height);
void ios_bind_game_view_fbo();
#endif

View File

@ -4,10 +4,6 @@
#include "conf/config_file.h"
@interface RAGameView : UIViewController
- (id)initWithGame:(NSString*)path;\
- (void)pause;
- (void)resume;
- (void)exit;
@end
@interface RAModuleList : UITableViewController