diff --git a/frontend/frontend_salamander.c b/frontend/frontend_salamander.c index 900bfb4562..ef54bf473d 100644 --- a/frontend/frontend_salamander.c +++ b/frontend/frontend_salamander.c @@ -31,6 +31,9 @@ frontend_ctx_driver_t *frontend_ctx; #include "platform/platform_ps3.c" #elif defined(GEKKO) #include "platform/platform_gx.c" +#ifdef HW_RVL +#include "platform/platform_wii.c" +#endif #elif defined(_XBOX) #include "platform/platform_xdk.c" #elif defined(PSP) @@ -102,10 +105,10 @@ int main(int argc, char *argv[]) if (system_ctx_init() != 0) return 0; - frontend_ctx->init(); + frontend_ctx->init(args); get_environment_settings(argc, argv, args); salamander_init_settings(); - frontend_ctx->deinit(); + frontend_ctx->deinit(args); frontend_ctx->exitspawn(); return 1; diff --git a/frontend/platform/platform_gx.c b/frontend/platform/platform_gx.c index 3cf9cb01f7..c0958d0198 100644 --- a/frontend/platform/platform_gx.c +++ b/frontend/platform/platform_gx.c @@ -43,6 +43,7 @@ #include #include #include +extern void system_exec_wii(const char *path, bool should_load_game); #endif #include #include @@ -74,12 +75,12 @@ static void salamander_init_settings(void) //try to find CORE executable char core_executable[1024]; - snprintf(core_executable, sizeof(core_executable), "%s/CORE.dol", default_paths.core_dir); + fill_pathname_join(core_executable, default_paths.core_dir, "CORE.dol", sizeof(core_executable)); if(path_file_exists(core_executable)) { //Start CORE executable - snprintf(default_paths.libretro_path, sizeof(default_paths.libretro_path), core_executable); + strlcpy(default_paths.libretro_path, core_executable, sizeof(default_paths.libretro_path)); RARCH_LOG("Start [%s].\n", default_paths.libretro_path); } else @@ -93,7 +94,7 @@ static void salamander_init_settings(void) { config_get_array(conf, "libretro_path", tmp_str, sizeof(tmp_str)); config_file_free(conf); - snprintf(default_paths.libretro_path, sizeof(default_paths.libretro_path), tmp_str); + strlcpy(default_paths.libretro_path, tmp_str, sizeof(default_paths.libretro_path)); } } @@ -249,7 +250,7 @@ static void get_environment_settings(int argc, char *argv[], void *args) snprintf(default_paths.sram_dir, sizeof(default_paths.savestate_dir), "%s/savefiles", default_paths.port_dir); snprintf(default_paths.savestate_dir, sizeof(default_paths.savestate_dir), "%s/savestates", default_paths.port_dir); strlcpy(default_paths.filesystem_root_dir, "/", sizeof(default_paths.filesystem_root_dir)); - snprintf(default_paths.filebrowser_startup_dir, sizeof(default_paths.filebrowser_startup_dir), default_paths.filesystem_root_dir); + strlcpy(default_paths.filebrowser_startup_dir, default_paths.filesystem_root_dir, sizeof(default_paths.filebrowser_startup_dir)); #ifdef IS_SALAMANDER if (argc > 2 && argv[1] != NULL && argv[2] != NULL) @@ -316,7 +317,7 @@ static void system_exitspawn(void) system_exec(g_settings.libretro, should_load_game); // direct loading failed (out of memory), try to jump to salamander then load the correct core char boot_dol[PATH_MAX]; - snprintf(boot_dol, sizeof(boot_dol), "%s/boot.dol", default_paths.core_dir); + fill_pathname_join(boot_dol, default_paths.core_dir, "boot.dol", sizeof(boot_dol)); system_exec(boot_dol, should_load_game); #endif } @@ -351,8 +352,7 @@ static int system_process_args(int argc, char *argv[], void *args) if (argc > 2 && argv[1] != NULL && argv[2] != NULL) { - snprintf(g_extern.fullpath, sizeof(g_extern.fullpath), - "%s%s", argv[1], argv[2]); + fill_pathname_join(g_extern.fullpath, argv[1], argv[2], sizeof(g_extern.fullpath)); ret = 1; } #endif @@ -360,156 +360,10 @@ static int system_process_args(int argc, char *argv[], void *args) 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); -} -#endif - -// 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) { #ifdef HW_RVL - 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); + system_exec_wii(path, should_load_game); #endif } diff --git a/frontend/platform/platform_ps3.c b/frontend/platform/platform_ps3.c index c14561fbde..a2af27a6e5 100644 --- a/frontend/platform/platform_ps3.c +++ b/frontend/platform/platform_ps3.c @@ -59,8 +59,7 @@ static void find_and_set_first_file(void) if(first_file) { - snprintf(default_paths.libretro_path, sizeof(default_paths.libretro_path), - "%s/%s", default_paths.core_dir, first_file); + fill_pathname_join(default_paths.libretro_path, default_paths.core_dir, first_file, sizeof(default_paths.libretro_path)); RARCH_LOG("libretro_path now set to: %s.\n", default_paths.libretro_path); } else @@ -91,12 +90,12 @@ static void salamander_init_settings(void) //try to find CORE executable char core_executable[1024]; - snprintf(core_executable, sizeof(core_executable), "%s/CORE.SELF", default_paths.core_dir); + fill_pathname_join(core_executable, default_paths.core_dir, "CORE.SELF", sizeof(core_executable)); if(path_file_exists(core_executable)) { //Start CORE executable - snprintf(default_paths.libretro_path, sizeof(default_paths.libretro_path), core_executable); + strlcpy(default_paths.libretro_path, core_executable, sizeof(default_paths.libretro_path)); RARCH_LOG("Start [%s].\n", default_paths.libretro_path); } else @@ -106,7 +105,7 @@ static void salamander_init_settings(void) config_file_t * conf = config_file_new(default_paths.config_path); config_get_array(conf, "libretro_path", tmp_str, sizeof(tmp_str)); config_file_free(conf); - snprintf(default_paths.libretro_path, sizeof(default_paths.libretro_path), tmp_str); + strlcpy(default_paths.libretro_path, tmp_str, sizeof(default_paths.libretro_path)); } if (!config_file_exists || !strcmp(default_paths.libretro_path, "")) @@ -249,15 +248,13 @@ static void get_environment_settings(int argc, char *argv[], void *args) #ifdef HAVE_MULTIMAN if (g_extern.lifecycle_mode_state & (1ULL << MODE_EXTLAUNCH_MULTIMAN)) { - snprintf(contentInfoPath, sizeof(contentInfoPath), "/dev_hdd0/game/%s", EMULATOR_CONTENT_DIR); + fill_pathname_join(contentInfoPath, "/dev_hdd0/game/", EMULATOR_CONTENT_DIR, sizeof(contentInfoPath)); snprintf(default_paths.port_dir, sizeof(default_paths.port_dir), "/dev_hdd0/game/%s/USRDIR", EMULATOR_CONTENT_DIR); } #endif if(ret < 0) - { RARCH_ERR("cellGameContentPermit() Error: 0x%x\n", ret); - } else { RARCH_LOG("cellGameContentPermit() OK.\n"); @@ -265,25 +262,24 @@ static void get_environment_settings(int argc, char *argv[], void *args) RARCH_LOG("usrDirPath : [%s].\n", default_paths.port_dir); } - snprintf(default_paths.core_dir, sizeof(default_paths.core_dir), "%s/cores", default_paths.port_dir); - snprintf(default_paths.savestate_dir, sizeof(default_paths.savestate_dir), "%s/savestates", default_paths.core_dir); - snprintf(default_paths.filesystem_root_dir, sizeof(default_paths.filesystem_root_dir), "/"); - snprintf(default_paths.filebrowser_startup_dir, sizeof(default_paths.filebrowser_startup_dir), default_paths.filesystem_root_dir); - snprintf(default_paths.sram_dir, sizeof(default_paths.sram_dir), "%s/savefiles", default_paths.core_dir); - - snprintf(default_paths.system_dir, sizeof(default_paths.system_dir), "%s/system", default_paths.core_dir); + fill_pathname_join(default_paths.core_dir, default_paths.port_dir, "cores", sizeof(default_paths.core_dir)); + fill_pathname_join(default_paths.savestate_dir, default_paths.core_dir, "savestates", sizeof(default_paths.savestate_dir)); + strlcpy(default_paths.filesystem_root_dir, "/", sizeof(default_paths.filesystem_root_dir)); + strlcpy(default_paths.filebrowser_startup_dir, default_paths.filesystem_root_dir, sizeof(default_paths.filebrowser_startup_dir)); + fill_pathname_join(default_paths.sram_dir, default_paths.core_dir, "savefiles", sizeof(default_paths.sram_dir)); + fill_pathname_join(default_paths.system_dir, default_paths.core_dir, "system", sizeof(default_paths.system_dir)); /* now we fill in all the variables */ - snprintf(default_paths.menu_border_file, sizeof(default_paths.menu_border_file), "%s/borders/Menu/main-menu_1080p.png", default_paths.core_dir); - snprintf(default_paths.border_dir, sizeof(default_paths.border_dir), "%s/borders", default_paths.core_dir); + fill_pathname_join(default_paths.menu_border_file, default_paths.core_dir, "borders/Menu/main-menu_1080p.png", sizeof(default_paths.menu_border_file)); + fill_pathname_join(default_paths.border_dir, default_paths.core_dir, "borders", sizeof(default_paths.border_dir)); #if defined(HAVE_CG) || defined(HAVE_GLSL) - snprintf(g_settings.video.shader_dir, sizeof(g_settings.video.shader_dir), "%s/shaders", default_paths.core_dir); + fill_pathname_join(g_settings.video.shader_dir, default_paths.core_dir, "shaders", sizeof(g_settings.video.shader_dir)); #endif #ifdef IS_SALAMANDER - snprintf(default_paths.config_path, sizeof(default_paths.config_path), "%s/retroarch.cfg", default_paths.port_dir); + fill_pathname_join(default_paths.config_path, default_paths.port_dir, "retroarch.cfg", sizeof(default_paths.config_path)); #else - snprintf(g_extern.config_path, sizeof(g_extern.config_path), "%s/retroarch.cfg", default_paths.port_dir); + fill_pathname_join(g_extern.config_path, default_paths.port_dir, "retroarch.cfg", sizeof(g_extern.config_path)); #endif } } diff --git a/frontend/platform/platform_wii.c b/frontend/platform/platform_wii.c new file mode 100644 index 0000000000..0369c05e3b --- /dev/null +++ b/frontend/platform/platform_wii.c @@ -0,0 +1,148 @@ +#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 +void system_exec_wii(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/griffin/griffin.c b/griffin/griffin.c index 09d2606f0c..460e3cbe5c 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -460,6 +460,9 @@ FRONTEND #include "../frontend/platform/platform_ps3.c" #elif defined(GEKKO) #include "../frontend/platform/platform_gx.c" +#ifdef HW_RVL +#include "../frontend/platform/platform_wii.c" +#endif #elif defined(_XBOX) #include "../frontend/platform/platform_xdk.c" #elif defined(PSP)