From 3672b4ba40fcbe574b0c15085ea0e9ef4f96efc4 Mon Sep 17 00:00:00 2001 From: Timo Strunk Date: Fri, 19 Sep 2014 20:28:30 +0200 Subject: [PATCH 01/12] Added menu button Y --- frontend/menu/menu_common.c | 2 ++ frontend/menu/menu_common.h | 1 + 2 files changed, 3 insertions(+) diff --git a/frontend/menu/menu_common.c b/frontend/menu/menu_common.c index 42d7df1885..25e2a57ee1 100644 --- a/frontend/menu/menu_common.c +++ b/frontend/menu/menu_common.c @@ -290,6 +290,8 @@ static unsigned input_frame(uint64_t trigger_state) return MENU_ACTION_CANCEL; if (trigger_state & (1ULL << RETRO_DEVICE_ID_JOYPAD_A)) return MENU_ACTION_OK; + if (trigger_state & (1ULL << RETRO_DEVICE_ID_JOYPAD_Y)) + return MENU_ACTION_Y; if (trigger_state & (1ULL << RETRO_DEVICE_ID_JOYPAD_START)) return MENU_ACTION_START; if (trigger_state & (1ULL << RETRO_DEVICE_ID_JOYPAD_SELECT)) diff --git a/frontend/menu/menu_common.h b/frontend/menu/menu_common.h index 1a234bb962..8f699d0d99 100644 --- a/frontend/menu/menu_common.h +++ b/frontend/menu/menu_common.h @@ -87,6 +87,7 @@ typedef enum MENU_ACTION_LEFT, MENU_ACTION_RIGHT, MENU_ACTION_OK, + MENU_ACTION_Y, MENU_ACTION_CANCEL, MENU_ACTION_REFRESH, MENU_ACTION_SELECT, From 7bc369642d18caa35ef5bfed56667f49982a2ced Mon Sep 17 00:00:00 2001 From: Timo Strunk Date: Fri, 19 Sep 2014 20:31:18 +0200 Subject: [PATCH 02/12] Added generic message buffer and open_compressed flag to menu_driver --- frontend/menu/menu_driver.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/frontend/menu/menu_driver.h b/frontend/menu/menu_driver.h index 63dfdfa30c..a55967111b 100644 --- a/frontend/menu/menu_driver.h +++ b/frontend/menu/menu_driver.h @@ -70,6 +70,7 @@ typedef struct uint64_t old_input_state; uint64_t trigger_state; bool do_held; + bool open_compressed; unsigned delay_timer; unsigned delay_count; @@ -90,6 +91,12 @@ typedef struct bool defer_core; char deferred_path[PATH_MAX]; + /* This buffer can be used to display generic OK messages to the user. + * Fill it and call + * file_list_push(driver.menu->menu_stack, "", "message", 0, 0); + */ + char message_contents[PATH_MAX]; + /* Quick jumping indices with L/R. * Rebuilt when parsing directory. */ size_t scroll_indices[2 * (26 + 2) + 1]; From 9c9543e7eb4d6cd8b5e59da55a9b94f221d6dfc8 Mon Sep 17 00:00:00 2001 From: Timo Strunk Date: Fri, 19 Sep 2014 20:31:53 +0200 Subject: [PATCH 03/12] Added toggle button to open zip files in load content and detect core --- frontend/menu/backend/menu_common_backend.c | 88 ++++++++++++++++++++- frontend/menu/disp/shared.h | 12 ++- 2 files changed, 94 insertions(+), 6 deletions(-) diff --git a/frontend/menu/backend/menu_common_backend.c b/frontend/menu/backend/menu_common_backend.c index 9f1a456523..1e51064b5b 100644 --- a/frontend/menu/backend/menu_common_backend.c +++ b/frontend/menu/backend/menu_common_backend.c @@ -56,6 +56,19 @@ static void *get_last_setting(const file_list_t *list, int index, return NULL; } +static int menu_message_toggle(unsigned action) +{ + if (driver.video_data && driver.menu_ctx + && driver.menu_ctx->render_messagebox) + { + driver.menu_ctx->render_messagebox(driver.menu->message_contents); + } + if (action == MENU_ACTION_OK) + menu_entries_pop(driver.menu->menu_stack); + + return 0; +} + static int menu_info_screen_iterate(unsigned action) { char msg[PATH_MAX]; @@ -1625,6 +1638,8 @@ static int menu_custom_bind_iterate_keyboard(void *data, return 0; } + + static void menu_common_load_content(void) { rarch_main_command(RARCH_CMD_LOAD_CONTENT); @@ -1632,6 +1647,36 @@ static void menu_common_load_content(void) driver.menu->msg_force = true; } +static int menu_action_y() +{ + /* Toggle is only available in detect_core_list */ + /* + if (strcmp(menu_label, "detect_core_list")) + { + return 0; + } + */ + if (!driver.menu->open_compressed) + { + snprintf(driver.menu->message_contents, + sizeof(driver.menu->message_contents), + "-- ZipMode switched. --\n" + "Opening Archives as folders\n\n" + " Press OK to continue\n"); + } + else + { + snprintf(driver.menu->message_contents, + sizeof(driver.menu->message_contents), + "-- ZipMode switched. --\n" + "Loading Archives as files\n\n" + " Press OK to continue\n"); + } + driver.menu->open_compressed = !driver.menu->open_compressed; + file_list_push(driver.menu->menu_stack, "", "message", 0, 0); + return 0; +} + static int menu_action_ok(const char *menu_path, const char *menu_label, unsigned menu_type) { @@ -1656,9 +1701,10 @@ static int menu_action_ok(const char *menu_path, RARCH_LOG("type : %d\n", type == MENU_FILE_USE_DIRECTORY); RARCH_LOG("type id : %d\n", type); #endif - - switch (type) + while (true) { + switch (type) + { case MENU_FILE_PLAYLIST_ENTRY: rarch_playlist_load_content(g_extern.history, @@ -1676,7 +1722,6 @@ static int menu_action_ok(const char *menu_path, menu_path, path, driver.menu->deferred_path, sizeof(driver.menu->deferred_path)); - if (ret == -1) { @@ -1711,6 +1756,24 @@ static int menu_action_ok(const char *menu_path, { if (type == MENU_FILE_IN_CARCHIVE) { + if (g_extern.menu.info.need_fullpath) + { + /* Currently files in compressed archives are not supported + * in case of need_fullpath == true.q + */ + snprintf(driver.menu->message_contents, + sizeof(driver.menu->message_contents), + "Opening of files inside archives\n" + "is not possible for this driver.\n" + " \n" + "Extract manually or open as file\n" + " \n" + "(Go back and press Y) \n" + " \n" + " Press OK to continue\n"); + file_list_push(driver.menu->menu_stack, "", "message", 0, 0); + return 0; + } fill_pathname_join_delim(g_extern.fullpath, menu_path, path, '#',sizeof(g_extern.fullpath)); } @@ -1836,6 +1899,15 @@ static int menu_action_ok(const char *menu_path, case MENU_FILE_CARCHIVE: { + if (type == MENU_FILE_CARCHIVE) + if (!driver.menu->open_compressed) + { + /* in case we don't open compressed archives currently + * we just treat it as a PLAIN file, just like before. + */ + type = MENU_FILE_PLAIN; + continue; + } char cat_path[PATH_MAX]; fill_pathname_join(cat_path, menu_path, path, sizeof(cat_path)); menu_entries_push(driver.menu->menu_stack, @@ -1843,7 +1915,9 @@ static int menu_action_ok(const char *menu_path, } return 0; - + + } + break; } if (menu_parse_check(label, type) == 0) @@ -1879,6 +1953,8 @@ static int menu_common_iterate(unsigned action) if (!strcmp(menu_label, "help")) return menu_start_screen_iterate(action); + else if (!strcmp(menu_label, "message")) + return menu_message_toggle(action); else if (!strcmp(menu_label, "info_screen")) return menu_info_screen_iterate(action); else if (menu_common_type_is(menu_label, menu_type) == MENU_SETTINGS) @@ -1985,6 +2061,10 @@ static int menu_common_iterate(unsigned action) ret = menu_action_ok(path, menu_label, menu_type); break; + case MENU_ACTION_Y: + return menu_action_y(); + //break; + case MENU_ACTION_REFRESH: menu_clear_navigation(driver.menu); driver.menu->need_refresh = true; diff --git a/frontend/menu/disp/shared.h b/frontend/menu/disp/shared.h index a2bb28b56d..f21d4a3dd1 100644 --- a/frontend/menu/disp/shared.h +++ b/frontend/menu/disp/shared.h @@ -162,8 +162,16 @@ static void disp_set_label(unsigned *w, unsigned type, unsigned i, } else if (type == MENU_FILE_CARCHIVE) { - strlcpy(type_str, "(COMP)", type_str_size); - *w = 6; + if (driver.menu->open_compressed) + { + strlcpy(type_str, "(COMP)", type_str_size); + *w = 6; + } + else + { + strlcpy(type_str, "(FILE)", type_str_size); + *w = 6; + } } else if (type == MENU_FILE_IN_CARCHIVE) { From d114a80dab316a65c390d6f43a27906ed433c589 Mon Sep 17 00:00:00 2001 From: Timo Strunk Date: Sat, 20 Sep 2014 18:52:23 +0200 Subject: [PATCH 04/12] File.c now autoextracts in case of need_fullpath --- file.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/file.c b/file.c index 024c13ac93..fdf0585d0b 100644 --- a/file.c +++ b/file.c @@ -27,6 +27,7 @@ #include "hash.h" #include "file_extract.h" + #ifdef _WIN32 #ifdef _XBOX #include @@ -387,9 +388,24 @@ static bool load_content(const struct retro_subsystem_info *special, " load it on its own.\n"); if (need_fullpath && path_contains_compressed_file(path)) { - RARCH_ERR("Compressed files are only supported for drivers," - " where need_fullpath is set to false. Exiting.\n"); - rarch_assert(false); + RARCH_LOG("Compressed file in case of need_fullpath." + "Now extracting to temporary directory.\n"); + + /* This is a test implementation, currently it needs as much + * RAM as the file is big. + */ + char new_path[PATH_MAX]; + fill_pathname_join(new_path,g_settings.extraction_directory, + path_basename(path),sizeof(new_path)); + void *buf = NULL; + ssize_t bytes_read = -1; + bytes_read = read_file(path, &buf); + write_file(new_path,buf,bytes_read); + + info[i].path =strdup(new_path); + if(buf) + free(buf); + buf = NULL; } } } From 97ea43994e529f8b0f54a32051aca35727a8fb1a Mon Sep 17 00:00:00 2001 From: Timo Strunk Date: Sat, 20 Sep 2014 19:10:05 +0200 Subject: [PATCH 05/12] Zipfiles open or run half finished --- frontend/menu/backend/menu_common_backend.c | 169 +++++++++++++------- 1 file changed, 113 insertions(+), 56 deletions(-) diff --git a/frontend/menu/backend/menu_common_backend.c b/frontend/menu/backend/menu_common_backend.c index 1e51064b5b..3e35a08004 100644 --- a/frontend/menu/backend/menu_common_backend.c +++ b/frontend/menu/backend/menu_common_backend.c @@ -69,6 +69,104 @@ static int menu_message_toggle(unsigned action) return 0; } + +static int menu_load_or_open_zip_iterate(unsigned action) +{ + char msg[PATH_MAX]; + snprintf(msg, sizeof(msg), + "Opening compressed file\n" + " \n" + + " - OK to open as Folder\n" + " - Cancel/Back to Load \n"); + + if (driver.video_data && driver.menu_ctx && + driver.menu_ctx->render_messagebox) + { + if (*msg && msg[0] != '\0') + driver.menu_ctx->render_messagebox(msg); + } + + if (action == MENU_ACTION_OK) + { + menu_entries_pop(driver.menu->menu_stack); + + const char *menu_path; + const char *menu_label; + unsigned int menu_type; + char const* path; + char const* label; + unsigned int type; + + file_list_get_last(driver.menu->menu_stack, &menu_path, &menu_label, &menu_type); + + if (file_list_get_size(driver.menu->selection_buf) == 0) + return 0; + + file_list_get_at_offset(driver.menu->selection_buf, + driver.menu->selection_ptr, &path, &label, &type); + + char cat_path[PATH_MAX]; + fill_pathname_join(cat_path, menu_path, path, sizeof(cat_path)); + menu_entries_push(driver.menu->menu_stack, + cat_path, menu_label, type, driver.menu->selection_ptr); + } + else if (action == MENU_ACTION_CANCEL) + { + + menu_entries_pop(driver.menu->menu_stack); + + /*const char *menu_path; + const char *menu_label; + unsigned int menu_type; + char const* path; + char const* label; + unsigned int type; + + file_list_get_last(driver.menu->menu_stack, &menu_path, &menu_label, &menu_type); + + if (file_list_get_size(driver.menu->selection_buf) == 0) + return 0; + + file_list_get_at_offset(driver.menu->selection_buf, + driver.menu->selection_ptr, &path, &label, &type); + + char cat_path[PATH_MAX]; + fill_pathname_join(cat_path, menu_path, path, sizeof(cat_path)); + return menu_action_ok(cat_path,menu_label,MENU_FILE_PLAIN); */ +/* + menu_entries_push(driver.menu->menu_stack, + cat_path, menu_label, type, driver.menu->selection_ptr); + + + + menu_entries_pop(driver.menu->menu_stack); + const char *menu_path; + const char *menu_label; + unsigned int menu_type; + char const* path; + char const* label; + unsigned int type; + + file_list_get_last(driver.menu->menu_stack, &menu_path, &menu_label, &menu_type); + printf("BABBA\n"); + return menu_action_ok(menu_path,menu_label,menu_type); + + if (file_list_get_size(driver.menu->selection_buf) == 0) + return 0; + + file_list_get_at_offset(driver.menu->selection_buf, + driver.menu->selection_ptr, &path, &label, &type); + + + char cat_path[PATH_MAX]; + fill_pathname_join(cat_path, menu_path, path, sizeof(cat_path)); + menu_action_ok(driver.menu->menu_stack, + cat_path, menu_label, MENU_FILE_PLAIN, driver.menu->selection_ptr); */ + } + return 0; +} + static int menu_info_screen_iterate(unsigned action) { char msg[PATH_MAX]; @@ -1647,33 +1745,9 @@ static void menu_common_load_content(void) driver.menu->msg_force = true; } -static int menu_action_y() +static int menu_action_y(const char * /*menu_path*/, + const char * /*menu_label*/, unsigned /* menu_type */) { - /* Toggle is only available in detect_core_list */ - /* - if (strcmp(menu_label, "detect_core_list")) - { - return 0; - } - */ - if (!driver.menu->open_compressed) - { - snprintf(driver.menu->message_contents, - sizeof(driver.menu->message_contents), - "-- ZipMode switched. --\n" - "Opening Archives as folders\n\n" - " Press OK to continue\n"); - } - else - { - snprintf(driver.menu->message_contents, - sizeof(driver.menu->message_contents), - "-- ZipMode switched. --\n" - "Loading Archives as files\n\n" - " Press OK to continue\n"); - } - driver.menu->open_compressed = !driver.menu->open_compressed; - file_list_push(driver.menu->menu_stack, "", "message", 0, 0); return 0; } @@ -1716,6 +1790,7 @@ static int menu_action_ok(const char *menu_path, case MENU_FILE_IN_CARCHIVE: #endif case MENU_FILE_PLAIN: + { if (!strcmp(menu_label, "detect_core_list")) { int ret = rarch_defer_core(g_extern.core_info, @@ -1756,24 +1831,6 @@ static int menu_action_ok(const char *menu_path, { if (type == MENU_FILE_IN_CARCHIVE) { - if (g_extern.menu.info.need_fullpath) - { - /* Currently files in compressed archives are not supported - * in case of need_fullpath == true.q - */ - snprintf(driver.menu->message_contents, - sizeof(driver.menu->message_contents), - "Opening of files inside archives\n" - "is not possible for this driver.\n" - " \n" - "Extract manually or open as file\n" - " \n" - "(Go back and press Y) \n" - " \n" - " Press OK to continue\n"); - file_list_push(driver.menu->menu_stack, "", "message", 0, 0); - return 0; - } fill_pathname_join_delim(g_extern.fullpath, menu_path, path, '#',sizeof(g_extern.fullpath)); } @@ -1791,8 +1848,10 @@ static int menu_action_ok(const char *menu_path, return -1; } - return 0; + } + + case MENU_FILE_CONFIG: @@ -1899,15 +1958,11 @@ static int menu_action_ok(const char *menu_path, case MENU_FILE_CARCHIVE: { - if (type == MENU_FILE_CARCHIVE) - if (!driver.menu->open_compressed) - { - /* in case we don't open compressed archives currently - * we just treat it as a PLAIN file, just like before. - */ - type = MENU_FILE_PLAIN; - continue; - } + if (type == MENU_FILE_CARCHIVE && !strcmp(menu_label, "detect_core_list")) + { + file_list_push(driver.menu->menu_stack, "", "load_open_zip", 0, 0); + return 0; + } char cat_path[PATH_MAX]; fill_pathname_join(cat_path, menu_path, path, sizeof(cat_path)); menu_entries_push(driver.menu->menu_stack, @@ -1955,6 +2010,8 @@ static int menu_common_iterate(unsigned action) return menu_start_screen_iterate(action); else if (!strcmp(menu_label, "message")) return menu_message_toggle(action); + else if (!strcmp(menu_label, "load_open_zip")) + return menu_load_or_open_zip_iterate(action); else if (!strcmp(menu_label, "info_screen")) return menu_info_screen_iterate(action); else if (menu_common_type_is(menu_label, menu_type) == MENU_SETTINGS) @@ -2061,9 +2118,9 @@ static int menu_common_iterate(unsigned action) ret = menu_action_ok(path, menu_label, menu_type); break; + case MENU_ACTION_Y: - return menu_action_y(); - //break; + return menu_action_y(path, menu_label, menu_type); case MENU_ACTION_REFRESH: menu_clear_navigation(driver.menu); From 547cdefd1c574eaa2f4023acb0f750d825d50e10 Mon Sep 17 00:00:00 2001 From: Timo Strunk Date: Sat, 20 Sep 2014 20:05:54 +0200 Subject: [PATCH 06/12] Failsafe in case extraction dir is wrong --- file.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/file.c b/file.c index fdf0585d0b..8264902c82 100644 --- a/file.c +++ b/file.c @@ -391,6 +391,13 @@ static bool load_content(const struct retro_subsystem_info *special, RARCH_LOG("Compressed file in case of need_fullpath." "Now extracting to temporary directory.\n"); + if ((!strcmp(g_settings.extraction_directory,"")) || + !path_is_directory(g_settings.extraction_directory)) + { + RARCH_ERR("Tried extracting to extraction directory, but " + "extraction directory was not set or found. Exiting.\n"); + rarch_assert(false); + } /* This is a test implementation, currently it needs as much * RAM as the file is big. */ From 864a5cdc4fbbdbe4c81bc1a3abc2c8b0b35ca514 Mon Sep 17 00:00:00 2001 From: Timo Strunk Date: Sat, 20 Sep 2014 20:06:52 +0200 Subject: [PATCH 07/12] Always interpret files as carchives in case of detect_core_list to allow browsing them. --- frontend/menu/menu_entries.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/frontend/menu/menu_entries.c b/frontend/menu/menu_entries.c index 5cd3ebe8f4..51faa2c4ac 100644 --- a/frontend/menu/menu_entries.c +++ b/frontend/menu/menu_entries.c @@ -759,6 +759,17 @@ int menu_parse_and_resolve(file_list_t *list, file_list_t *menu_list) break; case RARCH_PLAIN_FILE: default: + if (!strcmp(label, "detect_core_list")) + { + if (path_is_compressed_file(str_list->elems[i].data)) + { + /* in case of deferred_core_list we have to interpret + * every archive as an archive to disallow instant loading + */ + file_type = MENU_FILE_CARCHIVE; + break; + } + } file_type = (menu_file_type_t)default_type_plain; break; } From 3575f353bf57c2ab2ebb4bb38f47b0004e4559ce Mon Sep 17 00:00:00 2001 From: Timo Strunk Date: Sat, 20 Sep 2014 20:07:26 +0200 Subject: [PATCH 08/12] Choosing whether to open or load a zip file in detect core should work now --- frontend/menu/backend/menu_common_backend.c | 182 +++++++++----------- frontend/menu/disp/shared.h | 12 +- frontend/menu/menu_driver.h | 1 - 3 files changed, 82 insertions(+), 113 deletions(-) diff --git a/frontend/menu/backend/menu_common_backend.c b/frontend/menu/backend/menu_common_backend.c index 3e35a08004..671953a33e 100644 --- a/frontend/menu/backend/menu_common_backend.c +++ b/frontend/menu/backend/menu_common_backend.c @@ -69,104 +69,6 @@ static int menu_message_toggle(unsigned action) return 0; } - -static int menu_load_or_open_zip_iterate(unsigned action) -{ - char msg[PATH_MAX]; - snprintf(msg, sizeof(msg), - "Opening compressed file\n" - " \n" - - " - OK to open as Folder\n" - " - Cancel/Back to Load \n"); - - if (driver.video_data && driver.menu_ctx && - driver.menu_ctx->render_messagebox) - { - if (*msg && msg[0] != '\0') - driver.menu_ctx->render_messagebox(msg); - } - - if (action == MENU_ACTION_OK) - { - menu_entries_pop(driver.menu->menu_stack); - - const char *menu_path; - const char *menu_label; - unsigned int menu_type; - char const* path; - char const* label; - unsigned int type; - - file_list_get_last(driver.menu->menu_stack, &menu_path, &menu_label, &menu_type); - - if (file_list_get_size(driver.menu->selection_buf) == 0) - return 0; - - file_list_get_at_offset(driver.menu->selection_buf, - driver.menu->selection_ptr, &path, &label, &type); - - char cat_path[PATH_MAX]; - fill_pathname_join(cat_path, menu_path, path, sizeof(cat_path)); - menu_entries_push(driver.menu->menu_stack, - cat_path, menu_label, type, driver.menu->selection_ptr); - } - else if (action == MENU_ACTION_CANCEL) - { - - menu_entries_pop(driver.menu->menu_stack); - - /*const char *menu_path; - const char *menu_label; - unsigned int menu_type; - char const* path; - char const* label; - unsigned int type; - - file_list_get_last(driver.menu->menu_stack, &menu_path, &menu_label, &menu_type); - - if (file_list_get_size(driver.menu->selection_buf) == 0) - return 0; - - file_list_get_at_offset(driver.menu->selection_buf, - driver.menu->selection_ptr, &path, &label, &type); - - char cat_path[PATH_MAX]; - fill_pathname_join(cat_path, menu_path, path, sizeof(cat_path)); - return menu_action_ok(cat_path,menu_label,MENU_FILE_PLAIN); */ -/* - menu_entries_push(driver.menu->menu_stack, - cat_path, menu_label, type, driver.menu->selection_ptr); - - - - menu_entries_pop(driver.menu->menu_stack); - const char *menu_path; - const char *menu_label; - unsigned int menu_type; - char const* path; - char const* label; - unsigned int type; - - file_list_get_last(driver.menu->menu_stack, &menu_path, &menu_label, &menu_type); - printf("BABBA\n"); - return menu_action_ok(menu_path,menu_label,menu_type); - - if (file_list_get_size(driver.menu->selection_buf) == 0) - return 0; - - file_list_get_at_offset(driver.menu->selection_buf, - driver.menu->selection_ptr, &path, &label, &type); - - - char cat_path[PATH_MAX]; - fill_pathname_join(cat_path, menu_path, path, sizeof(cat_path)); - menu_action_ok(driver.menu->menu_stack, - cat_path, menu_label, MENU_FILE_PLAIN, driver.menu->selection_ptr); */ - } - return 0; -} - static int menu_info_screen_iterate(unsigned action) { char msg[PATH_MAX]; @@ -1736,8 +1638,6 @@ static int menu_custom_bind_iterate_keyboard(void *data, return 0; } - - static void menu_common_load_content(void) { rarch_main_command(RARCH_CMD_LOAD_CONTENT); @@ -1745,8 +1645,86 @@ static void menu_common_load_content(void) driver.menu->msg_force = true; } -static int menu_action_y(const char * /*menu_path*/, - const char * /*menu_label*/, unsigned /* menu_type */) +static int menu_load_or_open_zip_iterate(unsigned action) +{ + char msg[PATH_MAX]; + snprintf(msg, sizeof(msg), "Opening compressed file\n" + " \n" + + " - OK to open as Folder\n" + " - Cancel/Back to Load \n"); + + if (driver.video_data && driver.menu_ctx + && driver.menu_ctx->render_messagebox) + { + if (*msg && msg[0] != '\0') + driver.menu_ctx->render_messagebox(msg); + } + + if (action == MENU_ACTION_OK) + { + menu_entries_pop(driver.menu->menu_stack); + + const char *menu_path; + const char *menu_label; + unsigned int menu_type; + char const* path; + char const* label; + unsigned int type; + + file_list_get_last(driver.menu->menu_stack, &menu_path, &menu_label, + &menu_type); + + if (file_list_get_size(driver.menu->selection_buf) == 0) + return 0; + + file_list_get_at_offset(driver.menu->selection_buf, + driver.menu->selection_ptr, &path, &label, &type); + + char cat_path[PATH_MAX]; + fill_pathname_join(cat_path, menu_path, path, sizeof(cat_path)); + menu_entries_push(driver.menu->menu_stack, cat_path, menu_label, type, + driver.menu->selection_ptr); + } + else if (action == MENU_ACTION_CANCEL) + { + menu_entries_pop(driver.menu->menu_stack); + + const char *menu_path; + const char *menu_label; + unsigned int menu_type; + char const* path; + char const* label; + unsigned int type; + + file_list_get_last(driver.menu->menu_stack, &menu_path, &menu_label, + &menu_type); + + if (file_list_get_size(driver.menu->selection_buf) == 0) + return 0; + + file_list_get_at_offset(driver.menu->selection_buf, + driver.menu->selection_ptr, &path, &label, &type); + + int ret = rarch_defer_core(g_extern.core_info, menu_path, path, + driver.menu->deferred_path, sizeof(driver.menu->deferred_path)); + if (ret == -1) + { + rarch_main_command(RARCH_CMD_LOAD_CORE); + menu_common_load_content(); + return -1; + } + else if (ret == 0) + menu_entries_push(driver.menu->menu_stack, + g_settings.libretro_directory, "deferred_core_list", 0, + driver.menu->selection_ptr); + + } + return 0; +} + +static int menu_action_y(const char * menu_path, + const char * menu_label, unsigned menu_type ) { return 0; } diff --git a/frontend/menu/disp/shared.h b/frontend/menu/disp/shared.h index f21d4a3dd1..a2bb28b56d 100644 --- a/frontend/menu/disp/shared.h +++ b/frontend/menu/disp/shared.h @@ -162,16 +162,8 @@ static void disp_set_label(unsigned *w, unsigned type, unsigned i, } else if (type == MENU_FILE_CARCHIVE) { - if (driver.menu->open_compressed) - { - strlcpy(type_str, "(COMP)", type_str_size); - *w = 6; - } - else - { - strlcpy(type_str, "(FILE)", type_str_size); - *w = 6; - } + strlcpy(type_str, "(COMP)", type_str_size); + *w = 6; } else if (type == MENU_FILE_IN_CARCHIVE) { diff --git a/frontend/menu/menu_driver.h b/frontend/menu/menu_driver.h index a55967111b..89a494a378 100644 --- a/frontend/menu/menu_driver.h +++ b/frontend/menu/menu_driver.h @@ -70,7 +70,6 @@ typedef struct uint64_t old_input_state; uint64_t trigger_state; bool do_held; - bool open_compressed; unsigned delay_timer; unsigned delay_count; From adfa00e1935ab278d01160f57b08aa6bc013c199 Mon Sep 17 00:00:00 2001 From: Timo Strunk Date: Sat, 20 Sep 2014 20:42:21 +0200 Subject: [PATCH 09/12] Removed MENU_ACTION_Y, small bugfix with selections in zip select --- frontend/menu/backend/menu_common_backend.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/frontend/menu/backend/menu_common_backend.c b/frontend/menu/backend/menu_common_backend.c index 671953a33e..7c685afed1 100644 --- a/frontend/menu/backend/menu_common_backend.c +++ b/frontend/menu/backend/menu_common_backend.c @@ -1723,12 +1723,6 @@ static int menu_load_or_open_zip_iterate(unsigned action) return 0; } -static int menu_action_y(const char * menu_path, - const char * menu_label, unsigned menu_type ) -{ - return 0; -} - static int menu_action_ok(const char *menu_path, const char *menu_label, unsigned menu_type) { @@ -1938,7 +1932,8 @@ static int menu_action_ok(const char *menu_path, { if (type == MENU_FILE_CARCHIVE && !strcmp(menu_label, "detect_core_list")) { - file_list_push(driver.menu->menu_stack, "", "load_open_zip", 0, 0); + file_list_push(driver.menu->menu_stack, path, "load_open_zip", + 0, driver.menu->selection_ptr); return 0; } char cat_path[PATH_MAX]; @@ -2096,10 +2091,6 @@ static int menu_common_iterate(unsigned action) ret = menu_action_ok(path, menu_label, menu_type); break; - - case MENU_ACTION_Y: - return menu_action_y(path, menu_label, menu_type); - case MENU_ACTION_REFRESH: menu_clear_navigation(driver.menu); driver.menu->need_refresh = true; From 097eb157211937f7adb7b8ef9be5ac6caf9f801e Mon Sep 17 00:00:00 2001 From: Timo Strunk Date: Sun, 21 Sep 2014 10:48:12 +0200 Subject: [PATCH 10/12] Included direct to file extraction into 7z and zip format readers. They are used in case of need_fullpath and archive usage --- decompress/7zip_support.c | 54 +++++++++++++++++++++++--------- decompress/7zip_support.h | 2 +- decompress/zip_support.c | 66 ++++++++++++++++++++++++++++++++------- decompress/zip_support.h | 2 +- file.c | 15 ++------- file_path.c | 22 ++++++++++--- file_path.h | 3 +- 7 files changed, 118 insertions(+), 46 deletions(-) diff --git a/decompress/7zip_support.c b/decompress/7zip_support.c index 7246977307..d0d88626d0 100644 --- a/decompress/7zip_support.c +++ b/decompress/7zip_support.c @@ -30,7 +30,10 @@ #include "../deps/7zip/7zFile.h" #include "../deps/7zip/7zVersion.h" - +/* Undefined at the end of the file + * Don't use outside of this file + */ +#define RARCH_ZIP_SUPPORT_BUFFER_SIZE_MAX 16384 static ISzAlloc g_Alloc = { SzAlloc, SzFree }; @@ -164,9 +167,11 @@ static SRes ConvertUtf16toCharString(const UInt16 *s, char *outstring) } /* Extract the relative path relative_path from a 7z archive - * archive_path and allocate a buf for it to write it in. */ + * archive_path and allocate a buf for it to write it in. + * If optional_outfile is set, extract to that instead and don't alloc buffer. + */ int read_7zip_file(const char * archive_path, - const char *relative_path, void **buf) + const char *relative_path, void **buf, const char* optional_outfile) { CFileInStream archiveStream; CLookToRead lookStream; @@ -245,6 +250,9 @@ int read_7zip_file(const char * archive_path, if (strcmp(infile,relative_path) == 0) { + /* C LZMA SDK does not support chunked extraction - see here: + * sourceforge.net/p/sevenzip/discussion/45798/thread/6fb59aaf/ + * */ file_found = true; res = SzArEx_Extract(&db, &lookStream.s, i,&blockIndex, &outBuffer, &outBufferSize,&offset, &outSizeProcessed, @@ -254,17 +262,33 @@ int read_7zip_file(const char * archive_path, break; /* This goes to the error section. */ } outsize = outSizeProcessed; - *buf = outBuffer+offset; - - /*We could either use the 7Zip allocated buffer, - * or create our own and use it. - * We would however need to realloc anyways, because RetroArch - * expects a \0 at the end, therefore we allocate new, - * copy and free the old one. */ - *buf = malloc(outsize + 1); - - ((char*)(*buf))[outsize] = '\0'; - memcpy(*buf,outBuffer+offset,outsize); + if (optional_outfile != NULL) + { + FILE* outsink = fopen(optional_outfile,"wb"); + if (outsink == NULL) + { + RARCH_ERR("Could not open outfilepath %s in 7zip_extract.\n", + optional_outfile); + IAlloc_Free(&allocImp, outBuffer); + SzArEx_Free(&db, &allocImp); + SzFree(NULL, temp); + File_Close(&archiveStream.file); + return -1; + } + fwrite(outBuffer+offset,1,outsize,outsink); + fclose(outsink); + } + else + { + /*We could either use the 7Zip allocated buffer, + * or create our own and use it. + * We would however need to realloc anyways, because RetroArch + * expects a \0 at the end, therefore we allocate new, + * copy and free the old one. */ + *buf = malloc(outsize + 1); + ((char*)(*buf))[outsize] = '\0'; + memcpy(*buf,outBuffer+offset,outsize); + } IAlloc_Free(&allocImp, outBuffer); break; } @@ -437,3 +461,5 @@ error: string_list_free(ext_list); return NULL; } + +#undef RARCH_ZIP_SUPPORT_BUFFER_SIZE_MAX diff --git a/decompress/7zip_support.h b/decompress/7zip_support.h index 2c425b21ea..4ada4cd333 100644 --- a/decompress/7zip_support.h +++ b/decompress/7zip_support.h @@ -21,7 +21,7 @@ extern "C" { #endif int read_7zip_file(const char * archive_path, - const char *relative_path, void **buf); + const char *relative_path, void **buf, char const* optional_outfileq); struct string_list *compressed_7zip_file_list_new(const char *path, const char* ext); diff --git a/decompress/zip_support.c b/decompress/zip_support.c index ec5b28f2de..f609a03e9a 100644 --- a/decompress/zip_support.c +++ b/decompress/zip_support.c @@ -26,15 +26,22 @@ #include "../deps/rzlib/unzip.h" +/* Undefined at the end of the file + * Don't use outside of this file + */ +#define RARCH_ZIP_SUPPORT_BUFFER_SIZE_MAX 16384 /* Extract the relative path relative_path from a * zip archive archive_path and allocate a buf for it to write it in. */ /* This code is inspired by: * stackoverflow.com/questions/10440113/simple-way-to-unzip-a-zip-file-using-zlib + * + * optional_outfile if not NULL will be used to extract the file. buf will be 0 + * then. */ int read_zip_file(const char * archive_path, - const char *relative_path, void **buf) + const char *relative_path, void **buf, const char* optional_outfile) { ssize_t bytes_read = -1; bool finished_reading = false; @@ -94,22 +101,55 @@ int read_zip_file(const char * archive_path, return -1; } - /* Allocate outbuffer */ - *buf = malloc(file_info.uncompressed_size + 1 ); - - bytes_read = unzReadCurrentFile( zipfile, *buf, file_info.uncompressed_size ); - if (bytes_read != file_info.uncompressed_size) + if (optional_outfile != 0) { - RARCH_ERR( + char read_buffer[RARCH_ZIP_SUPPORT_BUFFER_SIZE_MAX]; + FILE* outsink = fopen(optional_outfile,"wb"); + if (outsink == NULL) + { + RARCH_ERR("Could not open outfilepath %s in zip_extract.\n", + optional_outfile); + unzCloseCurrentFile( zipfile ); + unzClose( zipfile ); + return -1; + } + bytes_read = 0; + do + { + bytes_read = unzReadCurrentFile( zipfile, read_buffer, + RARCH_ZIP_SUPPORT_BUFFER_SIZE_MAX ); + ssize_t fwrite_bytes = fwrite(read_buffer,1,bytes_read,outsink); + if (fwrite_bytes != bytes_read) + { + /* couldn't write all bytes */ + RARCH_ERR("Error writing to %s.\n",optional_outfile); + fclose(outsink); + unzCloseCurrentFile( zipfile ); + unzClose( zipfile ); + return -1; + } + } while(bytes_read > 0) ; + fclose(outsink); + } + else + { + /* Allocate outbuffer */ + *buf = malloc(file_info.uncompressed_size + 1 ); + + bytes_read = unzReadCurrentFile( zipfile, *buf, file_info.uncompressed_size ); + if (bytes_read != file_info.uncompressed_size) + { + RARCH_ERR( "We tried to read %d bytes, but only got %d of file %s in zip %s.\n", (unsigned int) file_info.uncompressed_size, (int)bytes_read, relative_path, archive_path); - free(*buf); - unzCloseCurrentFile( zipfile ); - unzClose( zipfile ); - return -1; + free(*buf); + unzCloseCurrentFile( zipfile ); + unzClose( zipfile ); + return -1; + } + ((char*)(*buf))[file_info.uncompressed_size] = '\0'; } - ((char*)(*buf))[file_info.uncompressed_size] = '\0'; finished_reading = true; } unzCloseCurrentFile( zipfile ); @@ -238,3 +278,5 @@ struct string_list *compressed_zip_file_list_new(const char *path, unzClose( zipfile ); return list; } + +#undef RARCH_ZIP_SUPPORT_BUFFER_SIZE_MAX diff --git a/decompress/zip_support.h b/decompress/zip_support.h index c11d88e891..ede1cb6fef 100644 --- a/decompress/zip_support.h +++ b/decompress/zip_support.h @@ -21,7 +21,7 @@ extern "C" { #endif int read_zip_file(const char * archive_path, - const char *relative_path, void **buf); + const char *relative_path, void **buf, const char* optional_outfile); struct string_list *compressed_zip_file_list_new(const char *path, const char* ext); diff --git a/file.c b/file.c index 8264902c82..c4503629bd 100644 --- a/file.c +++ b/file.c @@ -398,21 +398,12 @@ static bool load_content(const struct retro_subsystem_info *special, "extraction directory was not set or found. Exiting.\n"); rarch_assert(false); } - /* This is a test implementation, currently it needs as much - * RAM as the file is big. - */ + char new_path[PATH_MAX]; fill_pathname_join(new_path,g_settings.extraction_directory, path_basename(path),sizeof(new_path)); - void *buf = NULL; - ssize_t bytes_read = -1; - bytes_read = read_file(path, &buf); - write_file(new_path,buf,bytes_read); - - info[i].path =strdup(new_path); - if(buf) - free(buf); - buf = NULL; + read_compressed_file(path,NULL,new_path); + info[i].path = strdup(new_path); } } } diff --git a/file_path.c b/file_path.c index b9f505075b..729c778bb4 100644 --- a/file_path.c +++ b/file_path.c @@ -92,10 +92,22 @@ bool write_empty_file(const char *path) return true; } -/* Generic compressed file loader. */ +/* Generic compressed file loader. + * Extracts to buf, unless optional_filename != 0 + * Then extracts to optional_filename and leaves buf alone. + */ #ifdef HAVE_COMPRESSION -long read_compressed_file(const char * path, void **buf) +long read_compressed_file(const char * path, void **buf, + const char* optional_filename) { + /* Safety check. + * If optional_filename and optional_filename exists, we simply return 0, + * hoping that optional_filename is the same as requested. + */ + if (optional_filename) + if(path_file_exists(optional_filename)) + return 0; + //We split carchive path and relative path: char archive_path[PATH_MAX]; strlcpy(archive_path,path,sizeof(archive_path)); @@ -123,11 +135,11 @@ long read_compressed_file(const char * path, void **buf) const char* file_ext = path_get_extension(archive_path); #ifdef HAVE_7ZIP if (strcasecmp(file_ext,"7z") == 0) - return read_7zip_file(archive_path,archive_found,buf); + return read_7zip_file(archive_path,archive_found,buf,optional_filename); #endif #ifdef HAVE_ZLIB if (strcasecmp(file_ext,"zip") == 0) - return read_zip_file(archive_path,archive_found,buf); + return read_zip_file(archive_path,archive_found,buf,optional_filename); #endif return -1; } @@ -187,7 +199,7 @@ long read_file(const char *path, void **buf) * */ #ifdef HAVE_COMPRESSION if (path_contains_compressed_file(path)) - return read_compressed_file(path,buf); + return read_compressed_file(path,buf,0); #endif return read_generic_file(path,buf); } diff --git a/file_path.h b/file_path.h index fda31adf29..6277300454 100644 --- a/file_path.h +++ b/file_path.h @@ -43,7 +43,8 @@ enum #ifdef HAVE_COMPRESSION -long read_compressed_file(const char * path, void **buf); +long read_compressed_file(const char * path, void **buf, + const char* optional_filename); #endif long read_file(const char *path, void **buf); From 193f416f8fce3c7230a02b04c8b7dbeeabb1292a Mon Sep 17 00:00:00 2001 From: Timo Strunk Date: Sun, 21 Sep 2014 11:03:32 +0200 Subject: [PATCH 11/12] Zip UI cleanup before pull request --- file.c | 1 - frontend/menu/backend/menu_common_backend.c | 6 ++---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/file.c b/file.c index c4503629bd..5e28fad562 100644 --- a/file.c +++ b/file.c @@ -27,7 +27,6 @@ #include "hash.h" #include "file_extract.h" - #ifdef _WIN32 #ifdef _XBOX #include diff --git a/frontend/menu/backend/menu_common_backend.c b/frontend/menu/backend/menu_common_backend.c index 7c685afed1..947202feaf 100644 --- a/frontend/menu/backend/menu_common_backend.c +++ b/frontend/menu/backend/menu_common_backend.c @@ -1762,7 +1762,7 @@ static int menu_action_ok(const char *menu_path, case MENU_FILE_IN_CARCHIVE: #endif case MENU_FILE_PLAIN: - { + if (!strcmp(menu_label, "detect_core_list")) { int ret = rarch_defer_core(g_extern.core_info, @@ -1820,10 +1820,8 @@ static int menu_action_ok(const char *menu_path, return -1; } + return 0; - } - - case MENU_FILE_CONFIG: From 547e2129ce05948617c53ce3070168828e7233a4 Mon Sep 17 00:00:00 2001 From: Timo Strunk Date: Sun, 21 Sep 2014 17:18:45 +0200 Subject: [PATCH 12/12] Made deferred path correct in case of a compressed file --- retroarch.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/retroarch.c b/retroarch.c index 28a34fdc35..421d75ce24 100644 --- a/retroarch.c +++ b/retroarch.c @@ -3828,6 +3828,14 @@ int rarch_defer_core(core_info_list_t *core_info, const char *dir, fill_pathname_join(deferred_path, dir, path, sizeof_deferred_path); + if (path_is_compressed_file(dir)) + { + /* In case of a compressed archive, we have to join with a hash */ + /* We are going to write at the position of dir: */ + rarch_assert(strlen(dir) < strlen(deferred_path)); + deferred_path[strlen(dir)] = '#'; + } + if (core_info) core_info_list_get_supported_cores(core_info, deferred_path, &info, &supported); @@ -3837,13 +3845,6 @@ int rarch_defer_core(core_info_list_t *core_info, const char *dir, { strlcpy(g_extern.fullpath, deferred_path, sizeof(g_extern.fullpath)); - if (path_is_compressed_file(dir)) - { - /* In case of a compressed archive, we have to join with a hash */ - /* We are going to write at the position of dir: */ - rarch_assert(strlen(dir) < strlen(g_extern.fullpath)); - g_extern.fullpath[strlen(dir)] = '#'; - } if (path_file_exists(info->path)) strlcpy(g_settings.libretro, info->path,