diff --git a/frontend/frontend.c b/frontend/frontend.c index bae4dcdbaa..7fa70d6514 100644 --- a/frontend/frontend.c +++ b/frontend/frontend.c @@ -32,15 +32,10 @@ frontend_ctx_driver_t *frontend_ctx; #if defined(__QNX__) #include #elif defined(__CELLOS_LV2__) -#include "platform/platform_ps3_exec.c" #include "platform/platform_ps3.c" #elif defined(GEKKO) -#ifdef HW_RVL -#include "platform/platform_gx_exec.c" -#endif #include "platform/platform_gx.c" #elif defined(_XBOX) -#include "platform/platform_xdk_exec.c" #include "platform/platform_xdk.c" #elif defined(PSP) #include "platform/platform_psp.c" diff --git a/frontend/frontend_context.h b/frontend/frontend_context.h index 0325f90db6..eeaacf2e8e 100644 --- a/frontend/frontend_context.h +++ b/frontend/frontend_context.h @@ -33,6 +33,7 @@ typedef struct frontend_ctx_driver void (*exitspawn)(void); int (*process_args)(int argc, char *argv[]); + void (*exec)(const char *, bool); // Human readable string. const char *ident; diff --git a/frontend/frontend_salamander.c b/frontend/frontend_salamander.c index 5d884b4350..80542bd696 100644 --- a/frontend/frontend_salamander.c +++ b/frontend/frontend_salamander.c @@ -28,15 +28,10 @@ frontend_ctx_driver_t *frontend_ctx; #endif #if defined(__CELLOS_LV2__) -#include "platform/platform_ps3_exec.c" #include "platform/platform_ps3.c" #elif defined(GEKKO) -#ifdef HW_RVL -#include "platform/platform_gx_exec.c" -#endif #include "platform/platform_gx.c" #elif defined(_XBOX) -#include "platform/platform_xdk_exec.c" #include "platform/platform_xdk.c" #elif defined(PSP) #include "platform/platform_psp.c" diff --git a/frontend/platform/platform_gx.c b/frontend/platform/platform_gx.c index 1bacd779f1..9e39b9aee3 100644 --- a/frontend/platform/platform_gx.c +++ b/frontend/platform/platform_gx.c @@ -359,11 +359,167 @@ static int system_process_args(int argc, char *argv[]) return ret; } +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define EXECUTE_ADDR ((uint8_t *) 0x91800000) +#define BOOTER_ADDR ((uint8_t *) 0x93000000) +#define ARGS_ADDR ((uint8_t *) 0x93200000) + +extern uint8_t _binary_wii_app_booter_app_booter_bin_start[]; +extern uint8_t _binary_wii_app_booter_app_booter_bin_end[]; +#define booter_start _binary_wii_app_booter_app_booter_bin_start +#define booter_end _binary_wii_app_booter_app_booter_bin_end + +#include "../../retroarch_logger.h" +#include "../../file.h" + +#ifdef IS_SALAMANDER +char gx_rom_path[PATH_MAX]; +#endif + +#ifdef HW_RVL +static void dol_copy_argv_path(const char *dolpath, const char *argpath) +{ + char tmp[PATH_MAX]; + size_t len, t_len; + struct __argv *argv = (struct __argv *) ARGS_ADDR; + memset(ARGS_ADDR, 0, sizeof(struct __argv)); + char *cmdline = (char *) ARGS_ADDR + sizeof(struct __argv); + argv->argvMagic = ARGV_MAGIC; + argv->commandLine = cmdline; + len = 0; + + // a device-less fullpath + if (dolpath[0] == '/') + { + char *dev = strchr(__system_argv->argv[0], ':'); + t_len = dev - __system_argv->argv[0] + 1; + memcpy(cmdline, __system_argv->argv[0], t_len); + len += t_len; + } + // a relative path + else if (strstr(dolpath, "sd:/") != dolpath && strstr(dolpath, "usb:/") != dolpath && + strstr(dolpath, "carda:/") != dolpath && strstr(dolpath, "cardb:/") != dolpath) + { + fill_pathname_parent_dir(tmp, __system_argv->argv[0], sizeof(tmp)); + t_len = strlen(tmp); + memcpy(cmdline, tmp, t_len); + len += t_len; + } + + t_len = strlen(dolpath); + memcpy(cmdline + len, dolpath, t_len); + len += t_len; + cmdline[len++] = 0; + + // file must be split into two parts, the path and the actual filename + // done to be compatible with loaders + if (argpath && strrchr(argpath, '/') != NULL) + { + // basedir + fill_pathname_parent_dir(tmp, argpath, sizeof(tmp)); + t_len = strlen(tmp); + memcpy(cmdline + len, tmp, t_len); + len += t_len; + cmdline[len++] = 0; + + // filename + char *name = strrchr(argpath, '/') + 1; + t_len = strlen(name); + memcpy(cmdline + len, name, t_len); + len += t_len; + cmdline[len++] = 0; + } + + cmdline[len++] = 0; + argv->length = len; + DCFlushRange(ARGS_ADDR, sizeof(struct __argv) + argv->length); +} + +// WARNING: after we move any data into EXECUTE_ADDR, we can no longer use any +// heap memory and are restricted to the stack only +static void system_exec(const char *path, bool should_load_game) +{ + char game_path[PATH_MAX]; + + RARCH_LOG("Attempt to load executable: [%s] %d.\n", path, sizeof(game_path)); + + // copy heap info into stack so it survives us moving the .dol into MEM2 + if (should_load_game) + { +#ifdef IS_SALAMANDER + strlcpy(game_path, gx_rom_path, sizeof(game_path)); +#else + strlcpy(game_path, g_extern.fullpath, sizeof(game_path)); +#endif + } + + FILE * fp = fopen(path, "rb"); + if (fp == NULL) + { + RARCH_ERR("Could not open DOL file %s.\n", path); + return; + } + + fseek(fp, 0, SEEK_END); + size_t size = ftell(fp); + fseek(fp, 0, SEEK_SET); + + // try to allocate a buffer for it. if we can't, fail + void *dol = malloc(size); + if (!dol) + { + RARCH_ERR("Could not execute DOL file %s.\n", path); + fclose(fp); + return; + } + + fread(dol, 1, size, fp); + fclose(fp); + + fatUnmount("carda:"); + fatUnmount("cardb:"); + fatUnmount("sd:"); + fatUnmount("usb:"); + __io_wiisd.shutdown(); + __io_usbstorage.shutdown(); + + // luckily for us, newlib's memmove doesn't allocate a seperate buffer for + // copying in situations of overlap, so it's safe to do this + memmove(EXECUTE_ADDR, dol, size); + DCFlushRange(EXECUTE_ADDR, size); + + dol_copy_argv_path(path, should_load_game ? game_path : NULL); + + size_t booter_size = booter_end - booter_start; + memcpy(BOOTER_ADDR, booter_start, booter_size); + DCFlushRange(BOOTER_ADDR, booter_size); + + RARCH_LOG("jumping to %08x\n", (unsigned) BOOTER_ADDR); + SYS_ResetSystem(SYS_SHUTDOWN,0,0); + __lwp_thread_stopmultitasking((void (*)(void)) BOOTER_ADDR); +} +#endif + const frontend_ctx_driver_t frontend_ctx_gx = { get_environment_settings, system_init, system_deinit, system_exitspawn, system_process_args, +#ifdef HW_RVL + system_exec, +#else + NULL, +#endif "gx", }; diff --git a/frontend/platform/platform_gx_exec.c b/frontend/platform/platform_gx_exec.c deleted file mode 100644 index 0d1ad4e0be..0000000000 --- a/frontend/platform/platform_gx_exec.c +++ /dev/null @@ -1,165 +0,0 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2010-2013 - Hans-Kristian Arntzen - * Copyright (C) 2011-2013 - Daniel De Matteis - * Copyright (C) 2012-2013 - Michael Lelli - * - * 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 -#include -#include -#include -#include -#include -#include - -#define EXECUTE_ADDR ((uint8_t *) 0x91800000) -#define BOOTER_ADDR ((uint8_t *) 0x93000000) -#define ARGS_ADDR ((uint8_t *) 0x93200000) - -extern uint8_t _binary_wii_app_booter_app_booter_bin_start[]; -extern uint8_t _binary_wii_app_booter_app_booter_bin_end[]; -#define booter_start _binary_wii_app_booter_app_booter_bin_start -#define booter_end _binary_wii_app_booter_app_booter_bin_end - -#include "../../retroarch_logger.h" -#include "../../file.h" - -#ifdef IS_SALAMANDER -char gx_rom_path[PATH_MAX]; -#endif - -static void dol_copy_argv_path(const char *dolpath, const char *argpath) -{ - char tmp[PATH_MAX]; - size_t len, t_len; - struct __argv *argv = (struct __argv *) ARGS_ADDR; - memset(ARGS_ADDR, 0, sizeof(struct __argv)); - char *cmdline = (char *) ARGS_ADDR + sizeof(struct __argv); - argv->argvMagic = ARGV_MAGIC; - argv->commandLine = cmdline; - len = 0; - - // a device-less fullpath - if (dolpath[0] == '/') - { - char *dev = strchr(__system_argv->argv[0], ':'); - t_len = dev - __system_argv->argv[0] + 1; - memcpy(cmdline, __system_argv->argv[0], t_len); - len += t_len; - } - // a relative path - else if (strstr(dolpath, "sd:/") != dolpath && strstr(dolpath, "usb:/") != dolpath && - strstr(dolpath, "carda:/") != dolpath && strstr(dolpath, "cardb:/") != dolpath) - { - fill_pathname_parent_dir(tmp, __system_argv->argv[0], sizeof(tmp)); - t_len = strlen(tmp); - memcpy(cmdline, tmp, t_len); - len += t_len; - } - - t_len = strlen(dolpath); - memcpy(cmdline + len, dolpath, t_len); - len += t_len; - cmdline[len++] = 0; - - // file must be split into two parts, the path and the actual filename - // done to be compatible with loaders - if (argpath && strrchr(argpath, '/') != NULL) - { - // basedir - fill_pathname_parent_dir(tmp, argpath, sizeof(tmp)); - t_len = strlen(tmp); - memcpy(cmdline + len, tmp, t_len); - len += t_len; - cmdline[len++] = 0; - - // filename - char *name = strrchr(argpath, '/') + 1; - t_len = strlen(name); - memcpy(cmdline + len, name, t_len); - len += t_len; - cmdline[len++] = 0; - } - - cmdline[len++] = 0; - argv->length = len; - DCFlushRange(ARGS_ADDR, sizeof(struct __argv) + argv->length); -} - -// WARNING: after we move any data into EXECUTE_ADDR, we can no longer use any -// heap memory and are restricted to the stack only -static void rarch_console_exec(const char *path, bool should_load_game) -{ - char game_path[PATH_MAX]; - - RARCH_LOG("Attempt to load executable: [%s] %d.\n", path, sizeof(game_path)); - - // copy heap info into stack so it survives us moving the .dol into MEM2 - if (should_load_game) - { -#ifdef IS_SALAMANDER - strlcpy(game_path, gx_rom_path, sizeof(game_path)); -#else - strlcpy(game_path, g_extern.fullpath, sizeof(game_path)); -#endif - } - - FILE * fp = fopen(path, "rb"); - if (fp == NULL) - { - RARCH_ERR("Could not open DOL file %s.\n", path); - return; - } - - fseek(fp, 0, SEEK_END); - size_t size = ftell(fp); - fseek(fp, 0, SEEK_SET); - - // try to allocate a buffer for it. if we can't, fail - void *dol = malloc(size); - if (!dol) - { - RARCH_ERR("Could not execute DOL file %s.\n", path); - fclose(fp); - return; - } - - fread(dol, 1, size, fp); - fclose(fp); - - fatUnmount("carda:"); - fatUnmount("cardb:"); - fatUnmount("sd:"); - fatUnmount("usb:"); - __io_wiisd.shutdown(); - __io_usbstorage.shutdown(); - - // luckily for us, newlib's memmove doesn't allocate a seperate buffer for - // copying in situations of overlap, so it's safe to do this - memmove(EXECUTE_ADDR, dol, size); - DCFlushRange(EXECUTE_ADDR, size); - - dol_copy_argv_path(path, should_load_game ? game_path : NULL); - - size_t booter_size = booter_end - booter_start; - memcpy(BOOTER_ADDR, booter_start, booter_size); - DCFlushRange(BOOTER_ADDR, booter_size); - - RARCH_LOG("jumping to %08x\n", (unsigned) BOOTER_ADDR); - SYS_ResetSystem(SYS_SHUTDOWN,0,0); - __lwp_thread_stopmultitasking((void (*)(void)) BOOTER_ADDR); -} diff --git a/frontend/platform/platform_ps3.c b/frontend/platform/platform_ps3.c index 337a2b5f3e..636f777d7b 100644 --- a/frontend/platform/platform_ps3.c +++ b/frontend/platform/platform_ps3.c @@ -385,12 +385,14 @@ static void system_deinit(void) #endif } +static void system_exec(const char *path, bool should_load_game); + static void system_exitspawn(void) { #ifdef HAVE_RARCH_EXEC #ifdef IS_SALAMANDER - rarch_console_exec(default_paths.libretro_path, false); + system_exec(default_paths.libretro_path, false); cellSysmoduleUnloadModule(CELL_SYSMODULE_SYSUTIL_GAME); cellSysmoduleLoadModule(CELL_SYSMODULE_FS); @@ -410,18 +412,68 @@ static void system_exitspawn(void) if (g_extern.lifecycle_mode_state & (1ULL << MODE_EXITSPAWN_START_GAME)) should_load_game = true; - rarch_console_exec(core_launch, should_load_game); + system_exec(core_launch, should_load_game); #endif #endif } +#include + +#include +#include +#include +#include +#include +#include + +#include "../../retroarch_logger.h" + +static void system_exec(const char *path, bool should_load_game) +{ + (void)should_load_game; + + RARCH_LOG("Attempt to load executable: [%s].\n", path); + char spawn_data[256]; + char game_path[256]; + (void)game_path; + for(unsigned int i = 0; i < sizeof(spawn_data); ++i) + spawn_data[i] = i & 0xff; + +#ifndef IS_SALAMANDER + if (should_load_game) + strlcpy(game_path, g_extern.fullpath, sizeof(game_path)); +#endif + + const char * const spawn_argv[] = { +#ifndef IS_SALAMANDER + game_path, +#endif + NULL + }; + + SceNpDrmKey * k_licensee = NULL; + int ret = sceNpDrmProcessExitSpawn2(k_licensee, path, (const char** const)spawn_argv, NULL, (sys_addr_t)spawn_data, 256, 1000, SYS_PROCESS_PRIMARY_STACK_SIZE_1M); + + if(ret < 0) + { + RARCH_WARN("SELF file is not of NPDRM type, trying another approach to boot it...\n"); + sys_game_process_exitspawn(path, (const char** const)spawn_argv, NULL, NULL, 0, 1000, SYS_PROCESS_PRIMARY_STACK_SIZE_1M); + } + + sceNpTerm(); + sys_net_finalize_network(); + cellSysmoduleUnloadModule(CELL_SYSMODULE_SYSUTIL_NP); + cellSysmoduleUnloadModule(CELL_SYSMODULE_NET); +} + const frontend_ctx_driver_t frontend_ctx_ps3 = { get_environment_settings, system_init, system_deinit, system_exitspawn, system_process_args, + system_exec, "ps3", }; diff --git a/frontend/platform/platform_ps3_exec.c b/frontend/platform/platform_ps3_exec.c deleted file mode 100644 index 49007225de..0000000000 --- a/frontend/platform/platform_ps3_exec.c +++ /dev/null @@ -1,64 +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 -#include -#include -#include -#include - -#include "../../retroarch_logger.h" - -static void rarch_console_exec(const char *path, bool should_load_game) -{ - (void)should_load_game; - - RARCH_LOG("Attempt to load executable: [%s].\n", path); - char spawn_data[256]; - char game_path[256]; - (void)game_path; - for(unsigned int i = 0; i < sizeof(spawn_data); ++i) - spawn_data[i] = i & 0xff; - -#ifndef IS_SALAMANDER - if (should_load_game) - strlcpy(game_path, g_extern.fullpath, sizeof(game_path)); -#endif - - const char * const spawn_argv[] = { -#ifndef IS_SALAMANDER - game_path, -#endif - NULL - }; - - SceNpDrmKey * k_licensee = NULL; - int ret = sceNpDrmProcessExitSpawn2(k_licensee, path, (const char** const)spawn_argv, NULL, (sys_addr_t)spawn_data, 256, 1000, SYS_PROCESS_PRIMARY_STACK_SIZE_1M); - - if(ret < 0) - { - RARCH_WARN("SELF file is not of NPDRM type, trying another approach to boot it...\n"); - sys_game_process_exitspawn(path, (const char** const)spawn_argv, NULL, NULL, 0, 1000, SYS_PROCESS_PRIMARY_STACK_SIZE_1M); - } - - sceNpTerm(); - sys_net_finalize_network(); - cellSysmoduleUnloadModule(CELL_SYSMODULE_SYSUTIL_NP); - cellSysmoduleUnloadModule(CELL_SYSMODULE_NET); -} diff --git a/frontend/platform/platform_psp.c b/frontend/platform/platform_psp.c index d0a902b253..071ccc1c90 100644 --- a/frontend/platform/platform_psp.c +++ b/frontend/platform/platform_psp.c @@ -112,3 +112,13 @@ static void system_deinit(void) static void system_exitspawn(void) { } + +const frontend_ctx_driver_t frontend_ctx_xdk = { + get_environment_settings, + system_init, + system_deinit, + system_exitspawn, + system_process_args, + NULL, + "psp", +}; diff --git a/frontend/platform/platform_xdk.c b/frontend/platform/platform_xdk.c index 60ec8e63d9..10a29aaeed 100644 --- a/frontend/platform/platform_xdk.c +++ b/frontend/platform/platform_xdk.c @@ -314,11 +314,49 @@ static void system_exitspawn(void) #endif } +#include + +#include + +#include "../../retroarch_logger.h" + +static void system_exec(const char *path, bool should_load_game) +{ + (void)should_load_game; + + RARCH_LOG("Attempt to load executable: [%s].\n", path); +#ifdef IS_SALAMANDER + XLaunchNewImage(path, NULL); +#else +#if defined(_XBOX1) + LAUNCH_DATA ptr; + memset(&ptr, 0, sizeof(ptr)); + if (should_load_game) + { + snprintf((char*)ptr.Data, sizeof(ptr.Data), "%s", g_extern.fullpath); + XLaunchNewImage(path, &ptr); + } + else + XLaunchNewImage(path, NULL); +#elif defined(_XBOX360) + char game_path[1024]; + if (should_load_game) + { + strlcpy(game_path, g_extern.fullpath, sizeof(game_path)); + XSetLaunchData(game_path, MAX_LAUNCH_DATA_SIZE); + } + XLaunchNewImage(path, NULL); +#endif +#endif + +} + const frontend_ctx_driver_t frontend_ctx_xdk = { get_environment_settings, system_init, system_deinit, system_exitspawn, system_process_args, + system_exec, "xdk", }; diff --git a/frontend/platform/platform_xdk_exec.c b/frontend/platform/platform_xdk_exec.c deleted file mode 100644 index 89ae0146a2..0000000000 --- a/frontend/platform/platform_xdk_exec.c +++ /dev/null @@ -1,52 +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 "../../retroarch_logger.h" - -static void rarch_console_exec(const char *path, bool should_load_game) -{ - (void)should_load_game; - - RARCH_LOG("Attempt to load executable: [%s].\n", path); -#ifdef IS_SALAMANDER - XLaunchNewImage(path, NULL); -#else -#if defined(_XBOX1) - LAUNCH_DATA ptr; - memset(&ptr, 0, sizeof(ptr)); - if (should_load_game) - { - snprintf((char*)ptr.Data, sizeof(ptr.Data), "%s", g_extern.fullpath); - XLaunchNewImage(path, &ptr); - } - else - XLaunchNewImage(path, NULL); -#elif defined(_XBOX360) - char game_path[1024]; - if (should_load_game) - { - strlcpy(game_path, g_extern.fullpath, sizeof(game_path)); - XSetLaunchData(game_path, MAX_LAUNCH_DATA_SIZE); - } - XLaunchNewImage(path, NULL); -#endif -#endif - -}