diff --git a/360/frontend-xdk/menu.cpp b/360/frontend-xdk/menu.cpp index 249ecfc48e..e9b9168cb0 100644 --- a/360/frontend-xdk/menu.cpp +++ b/360/frontend-xdk/menu.cpp @@ -546,23 +546,8 @@ HRESULT CRetroArchFileBrowser::OnNotifyPress( HXUIOBJ hObjPressed, BOOL& bHandle const char *strbuffer = rarch_convert_wchar_to_const_char((const wchar_t *)m_romlist.GetText(index)); if(path_file_exists(browser->current_dir.list->elems[index].data)) { - char rom_path_temp[PATH_MAX]; - char dir_path_temp[PATH_MAX]; - struct retro_system_info info; - retro_get_system_info(&info); - bool block_zip_extract = info.block_extract; - snprintf(path_temp, sizeof(path_temp), "%s\\%s", filebrowser_get_current_dir(browser), strbuffer); - - if((strstr(strbuffer, ".zip") || strstr(strbuffer, ".ZIP")) && !block_zip_extract) - { - rarch_extract_directory(dir_path_temp, path_temp, sizeof(dir_path_temp)); - rarch_extract_zipfile(rom_path_temp, dir_path_temp); - } - else - { - rarch_console_load_game(path_temp); - } + rarch_console_load_game_wrap(path_temp, S_DELAY_45); } else if(browser->current_dir.list->elems[index].attr.b) { diff --git a/console/console_settings.c b/console/console_settings.c index 1ebb221b6b..c9f01e0f65 100644 --- a/console/console_settings.c +++ b/console/console_settings.c @@ -230,6 +230,9 @@ void rarch_settings_msg(unsigned setting, unsigned delay) case ZIP_EXTRACT_TO_CURRENT_DIR: snprintf(str, sizeof(str), "INFO - ZIP file successfully extracted to current directory."); break; + case ZIP_EXTRACT_TO_CURRENT_DIR_AND_LOAD_FIRST_FILE: + snprintf(str, sizeof(str), "INFO - ZIP file successfully extracted, now loading first file."); + break; #ifdef HAVE_HDD_CACHE_PARTITION case ZIP_EXTRACT_TO_CACHE_DIR: snprintf(str, sizeof(str), "INFO - ZIP file successfully extracted to cache partition."); diff --git a/console/libretro_mgmt.c b/console/libretro_mgmt.c index 87844ef4e3..64af4adc22 100644 --- a/console/libretro_mgmt.c +++ b/console/libretro_mgmt.c @@ -152,3 +152,19 @@ void rarch_configure_libretro(const input_driver_t *input, const char *path_pref rarch_config_load(default_paths.config_file, path_prefix, extension, find_libretro_file); init_libretro_sym(); } + +bool rarch_manage_libretro_extension_supported(const char *filename) +{ + bool ext_supported = false; + struct string_list *ext_list = NULL; + const char *file_ext = path_get_extension(filename); + const char *ext = rarch_console_get_rom_ext(); + + if (ext) + ext_list = string_split(ext, "|"); + + if (ext_list && string_list_find_elem(ext_list, file_ext)) + ext_supported = true; + + return ext_supported; +} diff --git a/console/libretro_mgmt.h b/console/libretro_mgmt.h index 07e486e8df..589152fc63 100644 --- a/console/libretro_mgmt.h +++ b/console/libretro_mgmt.h @@ -30,5 +30,6 @@ enum void rarch_manage_libretro_set_first_file(char *first_file, size_t size_of_first_file, const char *libretro_path, const char * exe_ext); void rarch_configure_libretro(const input_driver_t *input, const char *path_prefix, const char * extension); +bool rarch_manage_libretro_extension_supported(const char *filename); #endif diff --git a/console/retroarch_rom_ext.c b/console/retroarch_rom_ext.c index d49fa84a83..37849ff97c 100644 --- a/console/retroarch_rom_ext.c +++ b/console/retroarch_rom_ext.c @@ -22,17 +22,72 @@ #endif #include "../general.h" +#include "../file.h" #include "console_settings.h" - +#include "retroarch_console.h" #include "retroarch_rom_ext.h" -void rarch_console_load_game(const char *path) +#ifdef HAVE_ZLIB +#include "retroarch_rzlib.h" +#endif + +static void rarch_console_load_game(const char *path) { snprintf(g_console.rom_path, sizeof(g_console.rom_path), path); rarch_settings_change(S_START_RARCH); } +void rarch_console_load_game_wrap(const char *path, unsigned delay) +{ + const char *game_to_load; + char first_file[PATH_MAX]; + char rom_path_temp[PATH_MAX]; + char dir_path_temp[PATH_MAX]; + struct retro_system_info info; + bool block_zip_extract = false; + + retro_get_system_info(&info); + block_zip_extract = info.block_extract; + + snprintf(rom_path_temp, sizeof(rom_path_temp), path); + +#ifdef HAVE_ZLIB + bool extract_zip_cond = (strstr(rom_path_temp, ".zip") || strstr(rom_path_temp, ".ZIP")) + && !block_zip_extract; + bool extract_zip_and_load_game_cond = (extract_zip_cond && + g_console.zip_extract_mode == ZIP_EXTRACT_TO_CURRENT_DIR_AND_LOAD_FIRST_FILE && first_file); + bool load_game = (extract_zip_and_load_game_cond) || (!extract_zip_cond); +#else + bool extract_zip_cond = false; + bool extract_zip_and_load_game_cond = false; + bool load_game = !extract_zip_cond; +#endif + +#ifdef HAVE_ZLIB + if(extract_zip_cond) + { + rarch_extract_directory(dir_path_temp, rom_path_temp, sizeof(dir_path_temp)); + rarch_extract_zipfile(rom_path_temp, dir_path_temp, first_file, sizeof(first_file)); + } +#endif + +#ifdef HAVE_ZLIB + if(extract_zip_and_load_game_cond) + game_to_load = first_file; + else +#endif + game_to_load = path; + + if(load_game) + { + rarch_console_load_game(game_to_load); + + if (g_console.info_msg_enable) + rarch_settings_msg(S_MSG_LOADING_ROM, delay); + } +} + const char *rarch_console_get_rom_ext(void) { const char *retval = NULL; diff --git a/console/retroarch_rom_ext.h b/console/retroarch_rom_ext.h index 92a56a5e32..b0e3fe7721 100644 --- a/console/retroarch_rom_ext.h +++ b/console/retroarch_rom_ext.h @@ -17,7 +17,7 @@ #ifndef RARCH_ROM_EXT_H__ #define RARCH_ROM_EXT_H__ -void rarch_console_load_game(const char *path); +void rarch_console_load_game_wrap(const char *path, unsigned delay); // Get rom extensions for current library. // Returns NULL if library doesn't have any preferences in particular. diff --git a/console/retroarch_rzlib.c b/console/retroarch_rzlib.c index fe73feca5c..ff49cb519d 100644 --- a/console/retroarch_rzlib.c +++ b/console/retroarch_rzlib.c @@ -22,7 +22,7 @@ #include "retroarch_rzlib.h" -static int rarch_extract_currentfile_in_zip(unzFile uf, const char *current_dir) +static int rarch_extract_currentfile_in_zip(unzFile uf, const char *current_dir, char *slash, char *write_filename, size_t write_filename_size) { char filename_inzip[PATH_MAX]; FILE *file_out = NULL; @@ -46,16 +46,15 @@ static int rarch_extract_currentfile_in_zip(unzFile uf, const char *current_dir) return UNZ_INTERNALERROR; } - char write_filename[PATH_MAX]; - switch(g_console.zip_extract_mode) { case ZIP_EXTRACT_TO_CURRENT_DIR: - snprintf(write_filename, sizeof(write_filename), "%s/%s", current_dir, filename_inzip); + case ZIP_EXTRACT_TO_CURRENT_DIR_AND_LOAD_FIRST_FILE: + snprintf(write_filename, write_filename_size, "%s%s%s", current_dir, slash, filename_inzip); break; #ifdef HAVE_HDD_CACHE_PARTITION case ZIP_EXTRACT_TO_CACHE_DIR: - snprintf(write_filename, sizeof(write_filename), "%s%s", default_paths.cache_dir, filename_inzip); + snprintf(write_filename, write_filename_size, "%s%s", default_paths.cache_dir, filename_inzip); break; #endif } @@ -113,8 +112,9 @@ static int rarch_extract_currentfile_in_zip(unzFile uf, const char *current_dir) return err; } -int rarch_extract_zipfile(const char *zip_path, const char *current_dir) +int rarch_extract_zipfile(const char *zip_path, const char *current_dir, char *first_file, size_t first_file_size) { + bool found_first_file = false; unzFile uf = unzOpen(zip_path); unz_global_info gi; @@ -124,8 +124,28 @@ int rarch_extract_zipfile(const char *zip_path, const char *current_dir) for (unsigned i = 0; i < gi.number_entry; i++) { - if (rarch_extract_currentfile_in_zip(uf, current_dir) != UNZ_OK) + static char write_filename[PATH_MAX]; + char slash[6]; +#ifdef _XBOX + snprintf(slash, sizeof(slash), "\0"); +#else + snprintf(slash, sizeof(slash), "/"); +#endif + if (rarch_extract_currentfile_in_zip(uf, current_dir, slash, write_filename, sizeof(write_filename)) != UNZ_OK) + { + RARCH_ERR("Failed to extract current file from ZIP archive.\n"); break; + } + else + { + if(!found_first_file) + { + found_first_file = rarch_manage_libretro_extension_supported(write_filename); + + if(found_first_file) + snprintf(first_file, first_file_size, write_filename); + } + } if ((i + 1) < gi.number_entry) { diff --git a/console/retroarch_rzlib.h b/console/retroarch_rzlib.h index 98fd52c7bb..74ab32d866 100644 --- a/console/retroarch_rzlib.h +++ b/console/retroarch_rzlib.h @@ -24,9 +24,10 @@ enum { ZIP_EXTRACT_TO_CURRENT_DIR, + ZIP_EXTRACT_TO_CURRENT_DIR_AND_LOAD_FIRST_FILE, ZIP_EXTRACT_TO_CACHE_DIR }; -int rarch_extract_zipfile(const char *zip_path, const char *current_dir); +int rarch_extract_zipfile(const char *zip_path, const char *current_dir, char *first_file, size_t first_file_size); #endif diff --git a/file.h b/file.h index 467f5b75a8..29d8e51887 100644 --- a/file.h +++ b/file.h @@ -60,9 +60,12 @@ struct string_list struct string_list *dir_list_new(const char *dir, const char *ext, bool include_dirs); void dir_list_sort(struct string_list *list, bool dir_first); void dir_list_free(struct string_list *list); +bool string_list_find_elem(const struct string_list *list, const char *elem); +struct string_list *string_split(const char *str, const char *delim); bool path_is_directory(const char *path); bool path_file_exists(const char *path); +const char *path_get_extension(const char *path); // Path-name operations. // If any of these operation are detected to overflow, the application will be terminated. diff --git a/file_path.c b/file_path.c index e5338bae97..854f79969f 100644 --- a/file_path.c +++ b/file_path.c @@ -103,7 +103,7 @@ static bool string_list_append(struct string_list *list, const char *elem, union return true; } -static struct string_list *string_split(const char *str, const char *delim) +struct string_list *string_split(const char *str, const char *delim) { char *copy = NULL; const char *tmp = NULL; @@ -138,7 +138,7 @@ error: return NULL; } -static bool string_list_find_elem(const struct string_list *list, const char *elem) +bool string_list_find_elem(const struct string_list *list, const char *elem) { if (!list) return false; @@ -152,7 +152,7 @@ static bool string_list_find_elem(const struct string_list *list, const char *el return false; } -static const char *path_get_extension(const char *path) +const char *path_get_extension(const char *path) { const char *ext = strrchr(path, '.'); if (ext) diff --git a/ps3/frontend/menu.c b/ps3/frontend/menu.c index cf92b7e27f..664e668f6d 100644 --- a/ps3/frontend/menu.c +++ b/ps3/frontend/menu.c @@ -230,6 +230,10 @@ static void set_setting_label(menu * menu_obj, unsigned currentsetting) snprintf(items_generalsettings[currentsetting].setting_text, sizeof(items_generalsettings[currentsetting].setting_text), "Current dir"); snprintf(items_generalsettings[currentsetting].comment, sizeof(items_generalsettings[currentsetting].comment), "INFO - [ZIP Extract Mode] is set to 'Current dir'.\nZIP files are extracted to the current directory."); break; + case ZIP_EXTRACT_TO_CURRENT_DIR_AND_LOAD_FIRST_FILE: + snprintf(items_generalsettings[currentsetting].setting_text, sizeof(items_generalsettings[currentsetting].setting_text), "Current dir and load first file"); + snprintf(items_generalsettings[currentsetting].comment, sizeof(items_generalsettings[currentsetting].comment), "INFO - [ZIP Extract Mode] is set to 'Current dir and load first file'.\nZIP files are extracted to the current directory, and the first game is automatically loaded."); + break; case ZIP_EXTRACT_TO_CACHE_DIR: snprintf(items_generalsettings[currentsetting].setting_text, sizeof(items_generalsettings[currentsetting].setting_text), "Cache dir"); snprintf(items_generalsettings[currentsetting].comment, sizeof(items_generalsettings[currentsetting].comment), "INFO - [ZIP Extract Mode] is set to 'Cache dir'.\nZIP files are extracted to the cache directory (dev_hdd1)."); @@ -1365,9 +1369,15 @@ static void producesettingentry(menu * menu_obj, unsigned switchvalue) g_settings.rewind_enable = false; break; case SETTING_ZIP_EXTRACT: - if((input_state & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) || (input_state & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) || (input_state & (1 << RETRO_DEVICE_ID_JOYPAD_B))) + if((input_state & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT))) { - g_console.zip_extract_mode = g_console.zip_extract_mode == ZIP_EXTRACT_TO_CURRENT_DIR ? ZIP_EXTRACT_TO_CACHE_DIR : ZIP_EXTRACT_TO_CURRENT_DIR; + if(g_console.zip_extract_mode > 0) + g_console.zip_extract_mode--; + } + if((input_state & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) || (input_state & (1 << RETRO_DEVICE_ID_JOYPAD_B))) + { + if(g_console.zip_extract_mode < ZIP_EXTRACT_TO_CACHE_DIR) + g_console.zip_extract_mode++; } if(input_state & (1 << RETRO_DEVICE_ID_JOYPAD_START)) { @@ -1697,26 +1707,7 @@ static void menu_romselect_iterate(filebrowser_t *filebrowser, menu_romselect_ac filebrowser_iterate(filebrowser, FILEBROWSER_ACTION_OK); } else - { - char rom_path_temp[PATH_MAX]; - char dir_path_temp[PATH_MAX]; - struct retro_system_info info; - retro_get_system_info(&info); - bool block_zip_extract = info.block_extract; - - snprintf(rom_path_temp, sizeof(rom_path_temp), filebrowser_get_current_path(filebrowser)); - - if((strstr(rom_path_temp, ".zip") || strstr(rom_path_temp, ".ZIP")) && !block_zip_extract) - { - rarch_extract_directory(dir_path_temp, rom_path_temp, sizeof(dir_path_temp)); - rarch_extract_zipfile(rom_path_temp, dir_path_temp); - } - else - { - rarch_console_load_game(filebrowser_get_current_path(filebrowser)); - rarch_settings_msg(S_MSG_LOADING_ROM, S_DELAY_45); - } - } + rarch_console_load_game_wrap(filebrowser_get_current_path(filebrowser), S_DELAY_45); break; case MENU_ROMSELECT_ACTION_GOTO_SETTINGS: menu_stack_increment(); diff --git a/wii/frontend/rgui.c b/wii/frontend/rgui.c index c99368c9fe..aa3e2337ec 100644 --- a/wii/frontend/rgui.c +++ b/wii/frontend/rgui.c @@ -480,8 +480,7 @@ const char *rgui_iterate(rgui_handle_t *rgui, rgui_action_t action) else { snprintf(rgui->path_buf, sizeof(rgui->path_buf), "%s/%s", dir, path); - rarch_console_load_game(rgui->path_buf); - rarch_settings_msg(S_MSG_LOADING_ROM, S_DELAY_1); + rarch_console_load_game_wrap(rgui->path_buf, S_DELAY_1); found = true; } break; diff --git a/xbox1/frontend/RetroLaunch/MenuMain.cpp b/xbox1/frontend/RetroLaunch/MenuMain.cpp index eed2cad4f9..62617bafd3 100644 --- a/xbox1/frontend/RetroLaunch/MenuMain.cpp +++ b/xbox1/frontend/RetroLaunch/MenuMain.cpp @@ -213,9 +213,9 @@ void CMenuMain::ProcessInput() } } - // Press A to launch, selected rom filename is saved into T:\\tmp.retro + // Press A to launch if (trigger_state & (1 << RETRO_DEVICE_ID_JOYPAD_B) || trigger_state & (1 << RETRO_DEVICE_ID_JOYPAD_START)) - rarch_console_load_game(g_romList.GetRomAt(m_romListSelectedRom)->GetFileName().c_str()); + rarch_console_load_game_wrap(g_romList.GetRomAt(m_romListSelectedRom)->GetFileName().c_str(), S_DELAY_1); if (trigger_state & (1 << RETRO_DEVICE_ID_JOYPAD_R3)) {