diff --git a/Makefile.wiiu b/Makefile.wiiu index 83bbdb4fa6..835497458f 100644 --- a/Makefile.wiiu +++ b/Makefile.wiiu @@ -98,8 +98,8 @@ LD := $(CXX) ELF2RPL := $(WUT_ROOT)/tools/bin/elf2rpl -INCDIRS := -I. -Ideps/zlib -Ideps/7zip -Ilibretro-common/include -Iwiiu -I$(WUT_ROOT)/include -LIBDIRS := -L. +INCDIRS := -I. -Ideps/zlib -Ideps/7zip -Ilibretro-common/include -Iwiiu -I$(WUT_ROOT)/include -I$(DEVKITPRO)/portlibs/ppc/include +LIBDIRS := -L. -L$(DEVKITPRO)/portlibs/ppc/lib CFLAGS := -mrvl -mcpu=750 -meabi -mhard-float LDFLAGS := @@ -117,7 +117,7 @@ CFLAGS += -ffast-math -Werror=implicit-function-declaration #CFLAGS += -fomit-frame-pointer -mword-relocations #CFLAGS += -Wall CFLAGS += -Dstatic_assert=_Static_assert -CFLAGS += -DWIIU -DMSB_FIRST +CFLAGS += -DWIIU -D__wiiu__ -DMSB_FIRST CFLAGS += -DHAVE_MAIN CFLAGS += -DRARCH_INTERNAL -DRARCH_CONSOLE CFLAGS += -DHAVE_FILTERS_BUILTIN $(DEFINES) @@ -138,7 +138,7 @@ CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions LDFLAGS += -Wl,--gc-sections -LIBS := $(WHOLE_START) -lretro_wiiu $(WHOLE_END) -lm +LIBS := $(WHOLE_START) -lretro_wiiu $(WHOLE_END) -lm -lfat -liosuhax RPX_OBJ = wiiu/system/stubs_rpl.o diff --git a/frontend/drivers/platform_wiiu.c b/frontend/drivers/platform_wiiu.c index f4e886c9ad..fcfc4e68ca 100644 --- a/frontend/drivers/platform_wiiu.c +++ b/frontend/drivers/platform_wiiu.c @@ -50,6 +50,10 @@ #include #include +#include +#include +#include "ios.h" + #include "wiiu_dbg.h" #ifdef HAVE_MENU @@ -58,6 +62,7 @@ //#define WIIU_SD_PATH "/vol/external01/" #define WIIU_SD_PATH "sd:/" +#define WIIU_USB_PATH "usb:/" static enum frontend_fork wiiu_fork_mode = FRONTEND_FORK_NONE; static const char* elf_path_cst = WIIU_SD_PATH "retroarch/retroarch.elf"; @@ -143,6 +148,11 @@ static int frontend_wiiu_parse_drive_list(void *data) MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR, MENU_SETTING_ACTION, 0, 0); + menu_entries_append_enum(list, WIIU_USB_PATH, + msg_hash_to_str(MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR), + MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR, + MENU_SETTING_ACTION, 0, 0); + return 0; } @@ -340,18 +350,80 @@ void __fini(void) (*ctor++)(); } +/* libiosuhax related */ + +//just to be able to call async +void someFunc(void *arg) +{ + (void)arg; +} + +static int mcp_hook_fd = -1; +int MCPHookOpen() +{ + //take over mcp thread + mcp_hook_fd = IOS_Open("/dev/mcp", 0); + if(mcp_hook_fd < 0) + return -1; + IOS_IoctlAsync(mcp_hook_fd, 0x62, (void*)0, 0, (void*)0, 0, someFunc, (void*)0); + //let wupserver start up + retro_sleep(1000); + if(IOSUHAX_Open("/dev/mcp") < 0) + { + IOS_Close(mcp_hook_fd); + mcp_hook_fd = -1; + return -1; + } + return 0; +} + +void MCPHookClose() +{ + if(mcp_hook_fd < 0) + return; + //close down wupserver, return control to mcp + IOSUHAX_Close(); + //wait for mcp to return + retro_sleep(1000); + IOS_Close(mcp_hook_fd); + mcp_hook_fd = -1; +} + /* HBL elf entry point */ int __entry_menu(int argc, char **argv) { InitFunctionPointers(); memoryInitialize(); - mount_sd_fat("sd"); + + int iosuhaxMount = 0; + int res = IOSUHAX_Open(NULL); + if(res < 0) + res = MCPHookOpen(); + + if(res < 0) + mount_sd_fat("sd"); + else + { + iosuhaxMount = 1; + fatInitDefault(); + } __init(); int ret = main(argc, argv); __fini(); - unmount_sd_fat("sd"); + if(iosuhaxMount) + { + fatUnmount("sd:"); + fatUnmount("usb:"); + if(mcp_hook_fd >= 0) + MCPHookClose(); + else + IOSUHAX_Close(); + } + else + unmount_sd_fat("sd"); + memoryRelease(); return ret; } @@ -361,13 +433,36 @@ __attribute__((noreturn)) void _start(int argc, char **argv) { memoryInitialize(); - mount_sd_fat("sd"); + + int iosuhaxMount = 0; + int res = IOSUHAX_Open(NULL); + if(res < 0) + res = MCPHookOpen(); + + if(res < 0) + mount_sd_fat("sd"); + else + { + iosuhaxMount = 1; + fatInitDefault(); + } __init(); int ret = main(argc, argv); __fini(); - unmount_sd_fat("sd"); + if(iosuhaxMount) + { + fatUnmount("sd:"); + fatUnmount("usb:"); + if(mcp_hook_fd >= 0) + MCPHookClose(); + else + IOSUHAX_Close(); + } + else + unmount_sd_fat("sd"); + memoryRelease(); SYSRelaunchTitle(argc, argv); exit(ret); diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index 45c3da9286..9adb36cfae 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -119,6 +119,105 @@ static char *lakka_get_project(void) } #endif +static void cb_net_generic_subdir(void *task_data, void *user_data, const char *err) +{ + char subdir_path[PATH_MAX_LENGTH]; + http_transfer_data_t *data = (http_transfer_data_t*)task_data; + menu_file_transfer_t *state = (menu_file_transfer_t*)user_data; + + subdir_path[0] = '\0'; + + if (!data || err) + goto finish; + + memcpy(subdir_path, data->data, data->len * sizeof(char)); + subdir_path[data->len] = '\0'; + +finish: + if (!err && !strstr(subdir_path, file_path_str(FILE_PATH_INDEX_DIRS_URL))) + { + char parent_dir[PATH_MAX_LENGTH]; + + parent_dir[0] = '\0'; + + fill_pathname_parent_dir(parent_dir, + state->path, sizeof(parent_dir)); + + generic_action_ok_displaylist_push(parent_dir, NULL, + subdir_path, 0, 0, 0, ACTION_OK_DL_CORE_CONTENT_DIRS_SUBDIR_LIST); + } + + if (err) + RARCH_ERR("%s: %s\n", msg_hash_to_str(MSG_DOWNLOAD_FAILED), err); + + if (data) + { + if (data->data) + free(data->data); + free(data); + } +} + +/* defined in menu_cbs_deferred_push */ +static void cb_net_generic(void *task_data, void *user_data, const char *err) +{ + bool refresh = false; + http_transfer_data_t *data = (http_transfer_data_t*)task_data; + menu_file_transfer_t *state = (menu_file_transfer_t*)user_data; + + if (core_buf) + free(core_buf); + + + core_buf = NULL; + core_len = 0; + + if (!data || err) + goto finish; + + core_buf = (char*)malloc((data->len+1) * sizeof(char)); + + if (!core_buf) + goto finish; + + memcpy(core_buf, data->data, data->len * sizeof(char)); + core_buf[data->len] = '\0'; + core_len = data->len; + +finish: + refresh = true; + menu_entries_ctl(MENU_ENTRIES_CTL_UNSET_REFRESH, &refresh); + + if (err) + RARCH_ERR("%s: %s\n", msg_hash_to_str(MSG_DOWNLOAD_FAILED), err); + + if (data) + { + if (data->data) + free(data->data); + free(data); + } + + if (!err && !strstr(state->path, file_path_str(FILE_PATH_INDEX_DIRS_URL))) + { + char parent_dir[PATH_MAX_LENGTH]; + menu_file_transfer_t *transf = NULL; + + parent_dir[0] = '\0'; + + fill_pathname_parent_dir(parent_dir, + state->path, sizeof(parent_dir)); + strlcat(parent_dir, file_path_str(FILE_PATH_INDEX_DIRS_URL), sizeof(parent_dir)); + + transf = (menu_file_transfer_t*)calloc(1, sizeof(*transf)); + strlcpy(transf->path, parent_dir, sizeof(transf->path)); + + task_push_http_transfer(parent_dir, true, "index_dirs", cb_net_generic_subdir, transf); + } +} +#endif + + int generic_action_ok_displaylist_push(const char *path, const char *new_path, const char *label, unsigned type, size_t idx, size_t entry_idx, @@ -778,105 +877,6 @@ int generic_action_ok_displaylist_push(const char *path, return menu_cbs_exit(); } -static void cb_net_generic_subdir(void *task_data, void *user_data, const char *err) -{ - char subdir_path[PATH_MAX_LENGTH]; - http_transfer_data_t *data = (http_transfer_data_t*)task_data; - menu_file_transfer_t *state = (menu_file_transfer_t*)user_data; - - subdir_path[0] = '\0'; - - if (!data || err) - goto finish; - - memcpy(subdir_path, data->data, data->len * sizeof(char)); - subdir_path[data->len] = '\0'; - -finish: - if (!err && !strstr(subdir_path, file_path_str(FILE_PATH_INDEX_DIRS_URL))) - { - char parent_dir[PATH_MAX_LENGTH]; - - parent_dir[0] = '\0'; - - fill_pathname_parent_dir(parent_dir, - state->path, sizeof(parent_dir)); - - generic_action_ok_displaylist_push(parent_dir, NULL, - subdir_path, 0, 0, 0, ACTION_OK_DL_CORE_CONTENT_DIRS_SUBDIR_LIST); - } - - if (err) - RARCH_ERR("%s: %s\n", msg_hash_to_str(MSG_DOWNLOAD_FAILED), err); - - if (data) - { - if (data->data) - free(data->data); - free(data); - } -} - -/* defined in menu_cbs_deferred_push */ -static void cb_net_generic(void *task_data, void *user_data, const char *err) -{ - bool refresh = false; - http_transfer_data_t *data = (http_transfer_data_t*)task_data; - menu_file_transfer_t *state = (menu_file_transfer_t*)user_data; - - if (core_buf) - free(core_buf); - - - core_buf = NULL; - core_len = 0; - - if (!data || err) - goto finish; - - core_buf = (char*)malloc((data->len+1) * sizeof(char)); - - if (!core_buf) - goto finish; - - memcpy(core_buf, data->data, data->len * sizeof(char)); - core_buf[data->len] = '\0'; - core_len = data->len; - -finish: - refresh = true; - menu_entries_ctl(MENU_ENTRIES_CTL_UNSET_REFRESH, &refresh); - - if (err) - RARCH_ERR("%s: %s\n", msg_hash_to_str(MSG_DOWNLOAD_FAILED), err); - - if (data) - { - if (data->data) - free(data->data); - free(data); - } - - if (!err && !strstr(state->path, file_path_str(FILE_PATH_INDEX_DIRS_URL))) - { - char parent_dir[PATH_MAX_LENGTH]; - menu_file_transfer_t *transf = NULL; - - parent_dir[0] = '\0'; - - fill_pathname_parent_dir(parent_dir, - state->path, sizeof(parent_dir)); - strlcat(parent_dir, file_path_str(FILE_PATH_INDEX_DIRS_URL), sizeof(parent_dir)); - - transf = (menu_file_transfer_t*)calloc(1, sizeof(*transf)); - strlcpy(transf->path, parent_dir, sizeof(transf->path)); - - task_push_http_transfer(parent_dir, true, "index_dirs", cb_net_generic_subdir, transf); - } -} -#endif - - static int generic_action_ok_file_load(const char *corepath, const char *fullpath, enum rarch_core_type action_type, enum content_mode_load content_enum_idx) { diff --git a/wiiu/ios.h b/wiiu/ios.h new file mode 100644 index 0000000000..5bc1f43de2 --- /dev/null +++ b/wiiu/ios.h @@ -0,0 +1,10 @@ + +#ifndef _IOS_H_ +#define _IOS_H_ + +int IOS_Open(char *path, unsigned int mode); +int IOS_Close(int fd); +int IOS_Ioctl(int fd, unsigned int request, void *input_buffer, unsigned int input_buffer_len, void *output_buffer, unsigned int output_buffer_len); +int IOS_IoctlAsync(int fd, unsigned int request, void *input_buffer, unsigned int input_buffer_len, void *output_buffer, unsigned int output_buffer_len, void *cb, void *cbarg); + +#endif diff --git a/wiiu/system/imports.h b/wiiu/system/imports.h index 5dd058c516..144d4518fb 100644 --- a/wiiu/system/imports.h +++ b/wiiu/system/imports.h @@ -71,6 +71,11 @@ IMPORT(FSGetMountSource); IMPORT(FSMount); IMPORT(FSUnmount); +IMPORT(IOS_Open); +IMPORT(IOS_Close); +IMPORT(IOS_Ioctl); +IMPORT(IOS_IoctlAsync); + IMPORT_END(); /* nsysnet */