diff --git a/frontend/frontend.c b/frontend/frontend.c index ebfce8fed9..2731de736f 100644 --- a/frontend/frontend.c +++ b/frontend/frontend.c @@ -24,7 +24,7 @@ #include "menu/rmenu.h" #endif -#if defined(__APPLE__) && !defined(OSX) +#if defined(__APPLE__) && !defined(OSX) && !defined(IOS) #include "SDL.h" // OSX seems to really need -lSDLmain, // so we include SDL.h here so it can hack our main. @@ -44,6 +44,10 @@ #include "platform/platform_xdk.c" #elif defined(PSP) #include "platform/platform_psp.c" +#elif defined(__APPLE__) +#include +#include +#include "../apple/RetroArch/rarch_wrapper.h" #endif #if defined(HAVE_RGUI) || defined(HAVE_RMENU) || defined(HAVE_RMENU_XUI) @@ -189,21 +193,106 @@ static void rarch_get_environment(int argc, char *argv[]) #endif } +static void system_shutdown(void) +{ +#if defined(__QNX__) + bps_shutdown(); +#elif defined(__APPLE__) + dispatch_async_f(dispatch_get_main_queue(), 0, apple_rarch_exited); +#endif +} + +#ifdef __APPLE__ +static pthread_mutex_t apple_event_queue_lock = PTHREAD_MUTEX_INITIALIZER; + +static struct +{ + void (*function)(void*); + void* userdata; +} apple_event_queue[16]; + +static uint32_t apple_event_queue_size; + +void apple_frontend_post_event(void (*fn)(void*), void* userdata) +{ + pthread_mutex_lock(&apple_event_queue_lock); + + if (apple_event_queue_size < 16) + { + apple_event_queue[apple_event_queue_size].function = fn; + apple_event_queue[apple_event_queue_size].userdata = userdata; + apple_event_queue_size ++; + } + + pthread_mutex_unlock(&apple_event_queue_lock); +} + +static void apple_free_main_wrap(struct rarch_main_wrap* wrap) +{ + if (wrap) + { + free((char*)wrap->libretro_path); + free((char*)wrap->rom_path); + free((char*)wrap->sram_path); + free((char*)wrap->state_path); + free((char*)wrap->config_path); + } + + free(wrap); +} + +static void process_events(void) +{ + pthread_mutex_lock(&apple_event_queue_lock); + + for (int i = 0; i < apple_event_queue_size; i ++) + apple_event_queue[i].function(apple_event_queue[i].userdata); + + apple_event_queue_size = 0; + + pthread_mutex_unlock(&apple_event_queue_lock); +} + +void* rarch_main_apple(void* args) +#else int rarch_main(int argc, char *argv[]) +#endif { rarch_preinit(); +#ifndef __APPLE__ rarch_main_clear_state(); +#endif rarch_get_environment(argc, argv); -#ifndef RARCH_CONSOLE +#if !defined(RARCH_CONSOLE) +#ifdef __APPLE__ + struct rarch_main_wrap* argdata = (struct rarch_main_wrap*)args; + int init_ret = rarch_main_init_wrap(argdata); + apple_free_main_wrap(argdata); + + if (init_ret) + { + rarch_main_clear_state(); + dispatch_async_f(dispatch_get_main_queue(), (void*)1, apple_rarch_exited); + return 0; + } +#else rarch_init_msg_queue(); int init_ret; if ((init_ret = rarch_main_init(argc, argv))) return init_ret; #endif +#endif #ifdef HAVE_MENU +#ifdef IOS + char* system_directory = ios_get_rarch_system_directory(); + strlcpy(g_extern.savestate_dir, system_directory, sizeof(g_extern.savestate_dir)); + strlcpy(g_extern.savefile_dir, system_directory, sizeof(g_extern.savefile_dir)); + free(system_directory); +#endif + menu_init(); #ifdef RARCH_CONSOLE @@ -236,6 +325,11 @@ int rarch_main(int argc, char *argv[]) #if defined(RARCH_CONSOLE) || defined(__QNX__) g_extern.lifecycle_mode_state |= (1ULL << MODE_MENU); #else +#ifdef __APPLE__ + // This needs to be here to tell the GUI thread that the emulator loop has stopped, + // the (void*)1 makes it display the 'Failed to load game' message. + dispatch_async_f(dispatch_get_main_queue(), (void*)1, apple_rarch_exited); +#endif return 1; #endif } @@ -251,7 +345,15 @@ int rarch_main(int argc, char *argv[]) driver.video_poke->set_aspect_ratio(driver.video_data, g_settings.video.aspect_ratio_idx); #endif - while ((g_extern.is_paused && !g_extern.is_oneshot) ? rarch_main_idle_iterate() : rarch_main_iterate()); + while ((g_extern.is_paused && !g_extern.is_oneshot) ? rarch_main_idle_iterate() : rarch_main_iterate()) + { +#ifdef __APPLE__ + process_events(); +#endif + + if (!(g_extern.lifecycle_mode_state & (1ULL << MODE_GAME))) + break; + } g_extern.lifecycle_mode_state &= ~(1ULL << MODE_GAME); } else if (g_extern.lifecycle_mode_state & (1ULL << MODE_MENU)) @@ -263,7 +365,15 @@ int rarch_main(int argc, char *argv[]) if (driver.audio_data) audio_stop_func(); - while (!g_extern.system.shutdown && menu_iterate()); + while (!g_extern.system.shutdown && menu_iterate()) + { +#ifdef __APPLE__ + process_events(); +#endif + + if (!(g_extern.lifecycle_mode_state & (1ULL << MODE_MENU))) + break; + } driver_set_nonblock_state(driver.nonblock_state); @@ -323,9 +433,7 @@ int rarch_main(int argc, char *argv[]) rarch_main_clear_state(); -#ifdef __QNX__ - bps_shutdown(); -#endif + system_shutdown(); // FIXME - should this be 1 for RARCH_CONSOLE? return 0; diff --git a/frontend/frontend_objc.c b/frontend/frontend_objc.c index 1bb13d8472..e69de29bb2 100644 --- a/frontend/frontend_objc.c +++ b/frontend/frontend_objc.c @@ -1,190 +0,0 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2010-2013 - Hans-Kristian Arntzen - * Copyright (C) 2011-2013 - Daniel De Matteis - * - * RetroArch is free software: you can redistribute it and/or modify it under the terms - * of the GNU General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with RetroArch. - * If not, see . - */ - -#include -#include - -#include "../general.h" -#include "../conf/config_file.h" -#include "../file.h" - -#ifdef __APPLE__ -#include "../apple/RetroArch/rarch_wrapper.h" -#endif - -#ifdef HAVE_RGUI -#include "../frontend/menu/rgui.h" -#endif - -static pthread_mutex_t apple_event_queue_lock = PTHREAD_MUTEX_INITIALIZER; - -static struct -{ - void (*function)(void*); - void* userdata; -} apple_event_queue[16]; - -static uint32_t apple_event_queue_size; - -void apple_frontend_post_event(void (*fn)(void*), void* userdata) -{ - pthread_mutex_lock(&apple_event_queue_lock); - - if (apple_event_queue_size < 16) - { - apple_event_queue[apple_event_queue_size].function = fn; - apple_event_queue[apple_event_queue_size].userdata = userdata; - apple_event_queue_size ++; - } - - pthread_mutex_unlock(&apple_event_queue_lock); -} - -static void process_events() -{ - pthread_mutex_lock(&apple_event_queue_lock); - - for (int i = 0; i < apple_event_queue_size; i ++) - apple_event_queue[i].function(apple_event_queue[i].userdata); - - apple_event_queue_size = 0; - - pthread_mutex_unlock(&apple_event_queue_lock); -} - -static void apple_free_main_wrap(struct rarch_main_wrap* wrap) -{ - if (wrap) - { - free((char*)wrap->libretro_path); - free((char*)wrap->rom_path); - free((char*)wrap->sram_path); - free((char*)wrap->state_path); - free((char*)wrap->config_path); - } - - free(wrap); -} - -void* rarch_main_apple(void* args) -{ - struct rarch_main_wrap* argdata = (struct rarch_main_wrap*)args; - int init_ret = rarch_main_init_wrap(argdata); - apple_free_main_wrap(argdata); - - if (init_ret) - { - rarch_main_clear_state(); - dispatch_async_f(dispatch_get_main_queue(), (void*)1, apple_rarch_exited); - return 0; - } - -#ifdef HAVE_RGUI - -#ifdef IOS - char* system_directory = ios_get_rarch_system_directory(); - strlcpy(g_extern.savestate_dir, system_directory, sizeof(g_extern.savestate_dir)); - strlcpy(g_extern.savefile_dir, system_directory, sizeof(g_extern.savefile_dir)); - free(system_directory); -#endif - - menu_init(); - g_extern.lifecycle_mode_state |= 1ULL << MODE_GAME; - - // If we started a ROM directly from command line, - // push it to ROM history. - if (!g_extern.libretro_dummy) - menu_rom_history_push_current(); - - for (;;) - { - if (g_extern.system.shutdown) - break; - else if (g_extern.lifecycle_mode_state & (1ULL << MODE_LOAD_GAME)) - { - load_menu_game_prepare(); - - // If ROM load fails, we exit RetroArch. On console it might make more sense to go back to menu though ... - if (load_menu_game()) - g_extern.lifecycle_mode_state |= (1ULL << MODE_GAME); - else - { -#ifdef RARCH_CONSOLE - g_extern.lifecycle_mode_state |= (1ULL << MODE_MENU); -#else - // This needs to be here to tell the GUI thread that the emulator loop has stopped, - // the (void*)1 makes it display the 'Failed to load game' message. - dispatch_async_f(dispatch_get_main_queue(), (void*)1, apple_rarch_exited); - return 1; -#endif - } - - g_extern.lifecycle_mode_state &= ~(1ULL << MODE_LOAD_GAME); - } - else if (g_extern.lifecycle_mode_state & (1ULL << MODE_GAME)) - { - while ((g_extern.is_paused && !g_extern.is_oneshot) ? rarch_main_idle_iterate() : rarch_main_iterate()) - { - process_events(); - - if (!(g_extern.lifecycle_mode_state & (1ULL << MODE_GAME))) - break; - } - - g_extern.lifecycle_mode_state &= ~(1ULL << MODE_GAME); - } - else if (g_extern.lifecycle_mode_state & (1ULL << MODE_MENU)) - { - g_extern.lifecycle_mode_state |= 1ULL << MODE_MENU_PREINIT; - while (!g_extern.system.shutdown && menu_iterate()) - { - process_events(); - - if (!(g_extern.lifecycle_mode_state & (1ULL << MODE_MENU))) - break; - } - - g_extern.lifecycle_mode_state &= ~(1ULL << MODE_MENU); - } - else - break; - } - - g_extern.system.shutdown = false; - - menu_free(); - - if (g_extern.config_save_on_exit && *g_extern.config_path) - config_save_file(g_extern.config_path); - - if (g_extern.main_is_init) - rarch_main_deinit(); -#else - while ((g_extern.is_paused && !g_extern.is_oneshot) ? rarch_main_idle_iterate() : rarch_main_iterate()); - rarch_main_deinit(); -#endif - - rarch_deinit_msg_queue(); - -#ifdef PERF_TEST - rarch_perf_log(); -#endif - - rarch_main_clear_state(); - - dispatch_async_f(dispatch_get_main_queue(), 0, apple_rarch_exited); - return 0; -} diff --git a/griffin/griffin.c b/griffin/griffin.c index f7504d8844..3206fd7aad 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -447,8 +447,6 @@ MAIN #include "../frontend/frontend_xenon.c" #elif defined(ANDROID) #include "../frontend/frontend_android.c" -#elif defined(IOS) || defined(OSX) -#include "../frontend/frontend_objc.c" #else #include "../frontend/frontend.c" #endif