diff --git a/CHANGES.md b/CHANGES.md index a85cc8f7d5..782daae2ed 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -20,6 +20,7 @@ - MENU: User Interface -> Appearance -> 'Menu Font Green/Blue Color' settings now work properly. - MIDI: Add a Linux ALSA driver for MIDI. - NETPLAY: Force fast-save-states when netlay is enabled +- NETPLAY: Allow quick joining subsystem lobbies - PS2: Initial PlayStation2 port. - PS4: Initial PlayStation4 port. - RECORDING: Implement recording options in the menu complete with quality profiles, streaming, and proper file naming diff --git a/content.h b/content.h index eb42714131..5734bb789b 100644 --- a/content.h +++ b/content.h @@ -109,6 +109,9 @@ void content_set_subsystem_info(void); /* Get the path to the last selected subsystem rom */ char* content_get_subsystem_rom(unsigned index); +/* Sets the subsystem by name */ +bool content_set_subsystem_by_name(const char* subsystem_name); + RETRO_END_DECLS #endif diff --git a/discord/discord.c b/discord/discord.c index f1c05b046d..80a74c96e7 100644 --- a/discord/discord.c +++ b/discord/discord.c @@ -187,8 +187,7 @@ static void handle_discord_join_cb(void *task_data, void *user_data, const char RARCH_LOG("[Discord] joining lobby at: %s\n", tmp_hostname); task_push_netplay_crc_scan(room->gamecrc, - room->gamename, tmp_hostname, room->corename); - + room->gamename, tmp_hostname, room->corename, room->subsystem_name); } finish: diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index 6dfe24b437..b6b73e2b0c 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -4016,7 +4016,7 @@ static int action_ok_netplay_connect_room(const char *path, task_push_netplay_crc_scan(netplay_room_list[idx - 3].gamecrc, netplay_room_list[idx - 3].gamename, - tmp_hostname, netplay_room_list[idx - 3].corename); + tmp_hostname, netplay_room_list[idx - 3].corename, netplay_room_list[idx - 3].subsystem_name); #else return -1; @@ -4263,6 +4263,9 @@ static void netplay_refresh_rooms_cb(void *task_data, void *user_data, const cha strlcpy(netplay_room_list[i].frontend, host->frontend, sizeof(netplay_room_list[i].frontend)); + strlcpy(netplay_room_list[i].subsystem_name, + host->subsystem_name, + sizeof(netplay_room_list[i].subsystem_name)); netplay_room_list[i].port = host->port; netplay_room_list[i].gamecrc = host->content_crc; diff --git a/menu/cbs/menu_cbs_select.c b/menu/cbs/menu_cbs_select.c index 155d6c105e..baf049bcbb 100644 --- a/menu/cbs/menu_cbs_select.c +++ b/menu/cbs/menu_cbs_select.c @@ -180,7 +180,7 @@ static int action_select_netplay_connect_room(const char *path, task_push_netplay_crc_scan(netplay_room_list[idx - 3].gamecrc, netplay_room_list[idx - 3].gamename, - tmp_hostname, netplay_room_list[idx - 3].corename); + tmp_hostname, netplay_room_list[idx - 3].corename, netplay_room_list[idx - 3].subsystem_name); return 0; } diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index 207f325afb..1bd69f3765 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -26,6 +26,7 @@ #include #include +#include #ifndef BIND_ACTION_SUBLABEL #define BIND_ACTION_SUBLABEL(cbs, name) \ @@ -580,6 +581,31 @@ static int action_bind_sublabel_subsystem_add( return 0; } +static int action_bind_sublabel_subsystem_load( + file_list_t *list, + unsigned type, unsigned i, + const char *label, const char *path, + char *s, size_t len) +{ + unsigned j = 0; + char buf[4096]; + + buf[0] = '\0'; + + for (j = 0; j < content_get_subsystem_rom_id(); j++) + { + strlcat(buf, " ", sizeof(buf)); + strlcat(buf, path_basename(content_get_subsystem_rom(j)), sizeof(buf)); + if (j != content_get_subsystem_rom_id() - 1) + strlcat(buf, "\n", sizeof(buf)); + } + + if (!string_is_empty(buf)) + strlcpy(s, buf, len); + + return 0; +} + static int action_bind_sublabel_remap_kbd_sublabel( file_list_t *list, unsigned type, unsigned i, @@ -692,6 +718,7 @@ static int action_bind_sublabel_netplay_room( const char *core_ver = NULL; const char *frontend = NULL; const char *na = NULL; + const char *subsystem = NULL; /* This offset may cause issues if any entries are added to this menu */ unsigned offset = i - 3; @@ -705,15 +732,54 @@ static int action_bind_sublabel_netplay_room( core_ver = netplay_room_list[offset].coreversion; gamecrc = netplay_room_list[offset].gamecrc; frontend = netplay_room_list[offset].frontend; + subsystem = netplay_room_list[offset].subsystem_name; na = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE); - snprintf(s, len, - "RetroArch: %s (%s)\nCore: %s (%s)\nGame: %s (%08x)", - string_is_empty(ra_version) ? na : ra_version, - string_is_empty(frontend) ? na : frontend, - corename, core_ver, - !string_is_equal(gamename, na) ? gamename : na, - gamecrc); + if (string_is_empty(subsystem) || string_is_equal(subsystem, "N/A")) + { + snprintf(s, len, + "RetroArch: %s (%s)\nCore: %s (%s)\nGame: %s (%08x)", + string_is_empty(ra_version) ? na : ra_version, + string_is_empty(frontend) ? na : frontend, + corename, core_ver, + !string_is_equal(gamename, na) ? gamename : na, + gamecrc); + } + else + { + if (strstr(gamename, "|")) + { + char buf[4096]; + unsigned i = 0; + struct string_list *list = string_split(gamename, "|"); + + buf[0] = '\0'; + for (i = 0; i < list->size; i++) + { + strlcat(buf, " ", sizeof(buf)); + strlcat(buf, list->elems[i].data, sizeof(buf)); + strlcat(buf, "\n", sizeof(buf)); + } + snprintf(s, len, + "RetroArch: %s (%s)\nCore: %s (%s)\nSubsystem: %s\nGames:\n%s", + string_is_empty(ra_version) ? na : ra_version, + string_is_empty(frontend) ? na : frontend, + corename, core_ver, subsystem, + !string_is_equal(gamename, na) ? buf : na + ); + string_list_free(list); + } + else + { + snprintf(s, len, + "RetroArch: %s (%s)\nCore: %s (%s)\nSubsystem: %s\nGame: %s (%08x)", + string_is_empty(ra_version) ? na : ra_version, + string_is_empty(frontend) ? na : frontend, + corename, core_ver, subsystem, + !string_is_equal(gamename, na) ? gamename : na, + gamecrc); + } + } #if 0 strlcpy(s, corename, len); #endif @@ -1175,6 +1241,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_SUBSYSTEM_ADD: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_subsystem_add); break; + case MENU_ENUM_LABEL_SUBSYSTEM_LOAD: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_subsystem_load); + break; case MENU_ENUM_LABEL_DISK_CYCLE_TRAY_STATUS: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_disk_cycle_tray_status); break; diff --git a/network/netplay/netplay_discovery.c b/network/netplay/netplay_discovery.c index 0b347ca548..8fb1d4feac 100644 --- a/network/netplay/netplay_discovery.c +++ b/network/netplay/netplay_discovery.c @@ -68,6 +68,7 @@ struct ad_packet char core_version[NETPLAY_HOST_STR_LEN]; char content[NETPLAY_HOST_LONGSTR_LEN]; char content_crc[NETPLAY_HOST_STR_LEN]; + char subsystem_name[NETPLAY_HOST_STR_LEN]; }; static bool netplay_lan_ad_client(void); @@ -247,6 +248,8 @@ bool netplay_lan_ad_server(netplay_t *netplay) unsigned k = 0; char reply_addr[NETPLAY_HOST_STR_LEN], port_str[6]; struct addrinfo *our_addr, hints = {0}; + struct string_list *subsystem = path_get_subsystem_list(); + char buf[4096]; net_ifinfo_t interfaces; @@ -313,11 +316,36 @@ bool netplay_lan_ad_server(netplay_t *netplay) reply_addr, interfaces.entries[k].host); /* Now build our response */ + buf[0] = '\0'; content_crc = content_get_crc(); memset(&ad_packet_buffer, 0, sizeof(struct ad_packet)); memcpy(&ad_packet_buffer, "RANS", 4); + if (subsystem) + { + unsigned i; + + for (i = 0; i < subsystem->size; i++) + { + strlcat(buf, path_basename(subsystem->elems[i].data), NETPLAY_HOST_LONGSTR_LEN); + if (i < subsystem->size - 1) + strlcat(buf, "|", NETPLAY_HOST_LONGSTR_LEN); + } + strlcpy(ad_packet_buffer.content, buf, + NETPLAY_HOST_LONGSTR_LEN); + strlcpy(ad_packet_buffer.subsystem_name, path_get(RARCH_PATH_SUBSYSTEM), + NETPLAY_HOST_STR_LEN); + } + else + { + strlcpy(ad_packet_buffer.content, !string_is_empty( + path_basename(path_get(RARCH_PATH_BASENAME))) + ? path_basename(path_get(RARCH_PATH_BASENAME)) : "N/A", + NETPLAY_HOST_LONGSTR_LEN); + strlcpy(ad_packet_buffer.subsystem_name, "N/A", NETPLAY_HOST_STR_LEN); + } + strlcpy(ad_packet_buffer.address, interfaces.entries[k].host, NETPLAY_HOST_STR_LEN); ad_packet_buffer.protocol_version = @@ -325,10 +353,6 @@ bool netplay_lan_ad_server(netplay_t *netplay) ad_packet_buffer.port = htonl(netplay->tcp_port); strlcpy(ad_packet_buffer.retroarch_version, PACKAGE_VERSION, NETPLAY_HOST_STR_LEN); - strlcpy(ad_packet_buffer.content, !string_is_empty( - path_basename(path_get(RARCH_PATH_BASENAME))) - ? path_basename(path_get(RARCH_PATH_BASENAME)) : "N/A", - NETPLAY_HOST_LONGSTR_LEN); strlcpy(ad_packet_buffer.nick, netplay->nick, NETPLAY_HOST_STR_LEN); strlcpy(ad_packet_buffer.frontend, frontend, NETPLAY_HOST_STR_LEN); @@ -393,7 +417,7 @@ static bool netplay_lan_ad_client(void) struct timeval tmp_tv = {0}; if (lan_ad_client_fd < 0) - return false; + return false; /* Check for any ad queries */ while (1) @@ -492,6 +516,8 @@ static bool netplay_lan_ad_client(void) NETPLAY_HOST_STR_LEN); strlcpy(host->content, ad_packet_buffer.content, NETPLAY_HOST_LONGSTR_LEN); + strlcpy(host->subsystem_name, ad_packet_buffer.subsystem_name, + NETPLAY_HOST_LONGSTR_LEN); strlcpy(host->frontend, ad_packet_buffer.frontend, NETPLAY_HOST_STR_LEN); diff --git a/network/netplay/netplay_discovery.h b/network/netplay/netplay_discovery.h index 8df1fb5bdd..aeedf60a87 100644 --- a/network/netplay/netplay_discovery.h +++ b/network/netplay/netplay_discovery.h @@ -43,6 +43,7 @@ struct netplay_host char core_version[NETPLAY_HOST_STR_LEN]; char retroarch_version[NETPLAY_HOST_STR_LEN]; char content[NETPLAY_HOST_LONGSTR_LEN]; + char subsystem_name[NETPLAY_HOST_LONGSTR_LEN]; int content_crc; int port; }; @@ -82,6 +83,7 @@ struct netplay_room bool lan; bool fixed; char retroarch_version[PATH_MAX_LENGTH]; + char subsystem_name[PATH_MAX_LENGTH]; char country[PATH_MAX_LENGTH]; struct netplay_room *next; }; diff --git a/network/netplay/netplay_frontend.c b/network/netplay/netplay_frontend.c index f5261d630c..ae0767a7cf 100644 --- a/network/netplay/netplay_frontend.c +++ b/network/netplay/netplay_frontend.c @@ -851,9 +851,9 @@ void netplay_get_architecture(char *frontend_architecture, size_t size) static void netplay_announce(void) { - char buf [4600]; + char buf[4600]; char frontend_architecture[PATH_MAX_LENGTH]; - char url [2048] = "http://lobby.libretro.com/add/"; + char url[2048] = "http://lobby.libretro.com/add/"; char *username = NULL; char *corename = NULL; char *gamename = NULL; @@ -865,6 +865,8 @@ static void netplay_announce(void) uint32_t content_crc = content_get_crc(); struct string_list *subsystem = path_get_subsystem_list(); + buf[0] = '\0'; + if (subsystem) { unsigned i; @@ -875,9 +877,9 @@ static void netplay_announce(void) if (i < subsystem->size - 1) strlcat(buf, "|", sizeof(buf)); } - RARCH_LOG("%s\n", buf); net_http_urlencode(&gamename, buf); net_http_urlencode(&subsystemname, path_get(RARCH_PATH_SUBSYSTEM)); + content_crc = 0; } else { diff --git a/network/netplay/netplay_room_parse.c b/network/netplay/netplay_room_parse.c index c339d37edc..813a765803 100644 --- a/network/netplay/netplay_room_parse.c +++ b/network/netplay/netplay_room_parse.c @@ -288,6 +288,11 @@ static JSON_Parser_HandlerResult JSON_CALL ObjectMemberHandler(JSON_Parser parse pCtx->cur_field = strdup(pValue); pCtx->cur_member = &rooms->cur->frontend; } + else if (string_is_equal(pValue, "subsystem_name")) + { + pCtx->cur_field = strdup(pValue); + pCtx->cur_member = &rooms->cur->subsystem_name; + } } } diff --git a/tasks/task_content.c b/tasks/task_content.c index 79beb659d9..0375595180 100644 --- a/tasks/task_content.c +++ b/tasks/task_content.c @@ -1811,6 +1811,32 @@ void content_set_subsystem(unsigned idx) pending_subsystem_id, pending_subsystem_ident, pending_subsystem_rom_num); } +/* Sets the subsystem by name */ +bool content_set_subsystem_by_name(const char* subsystem_name) +{ + rarch_system_info_t *system = runloop_get_system_info(); + const struct retro_subsystem_info *subsystem; + unsigned i = 0; + + /* Core fully loaded, use the subsystem data */ + if (system->subsystem.data) + subsystem = system->subsystem.data; + /* Core not loaded completely, use the data we peeked on load core */ + else + subsystem = subsystem_data; + + for (i = 0; i < subsystem_current_count; i++, subsystem++) + { + if (string_is_equal(subsystem_name, subsystem->ident)) + { + content_set_subsystem(i); + return true; + } + } + + return false; +} + /* Add a rom to the subsystem rom buffer */ void content_add_subsystem(const char* path) { diff --git a/tasks/task_netplay_find_content.c b/tasks/task_netplay_find_content.c index c6f8301c10..86667219b8 100644 --- a/tasks/task_netplay_find_content.c +++ b/tasks/task_netplay_find_content.c @@ -42,6 +42,7 @@ typedef struct char content_crc[PATH_MAX_LENGTH]; char content_path[PATH_MAX_LENGTH]; char hostname[512]; + char subsystem_name[512]; char core_name[PATH_MAX_LENGTH]; char core_path[PATH_MAX_LENGTH]; char core_extensions[PATH_MAX_LENGTH]; @@ -62,10 +63,32 @@ static void netplay_crc_scan_callback(void *task_data, fflush(stdout); + + if (!string_is_empty(state->subsystem_name) && !string_is_equal(state->subsystem_name, "N/A")) + { + content_ctx_info_t content_info = {0}; + struct string_list *game_list = string_split(state->content_path, "|"); + unsigned i = 0; + + task_push_load_new_core(state->core_path, NULL, + &content_info, CORE_TYPE_PLAIN, NULL, NULL); + content_clear_subsystem(); + if (!content_set_subsystem_by_name(state->subsystem_name)) + RARCH_LOG("[lobby] subsystem not found in implementation\n"); + + for (i = 0; i < game_list->size; i++) + content_add_subsystem(game_list->elems[i].data); + task_push_load_subsystem_with_core_from_menu( + NULL, &content_info, + CORE_TYPE_PLAIN, NULL, NULL); + string_list_free(game_list); + return; + } + #ifdef HAVE_MENU /* regular core with content file */ if (!string_is_empty(state->core_path) && !string_is_empty(state->content_path) - && !state->contentless && !state->current) + && !state->contentless && !state->current) { struct retro_system_info *system = runloop_get_libretro_system_info(); @@ -113,7 +136,7 @@ static void netplay_crc_scan_callback(void *task_data, /* no match found */ else { - RARCH_LOG("Couldn't find a suitable %s\n", + RARCH_LOG("[lobby] couldn't find a suitable %s\n", string_is_empty(state->content_path) ? "content file" : "core"); runloop_msg_queue_push( msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_LOAD_CONTENT_MANUALLY), @@ -163,9 +186,8 @@ static void get_entry(char *entry, int len, const char *path) { */ static void task_netplay_crc_scan_handler(retro_task_t *task) { - size_t i, j; + size_t i, j, k; char entry[PATH_MAX_LENGTH]; - char *filename_match = NULL; bool have_crc = false; netplay_crc_handle_t *state = (netplay_crc_handle_t*)task->state; @@ -212,7 +234,7 @@ static void task_netplay_crc_scan_handler(retro_task_t *task) RARCH_LOG("[lobby] current content crc: %s\n", current); if (string_is_equal(current, state->content_crc)) - { + { RARCH_LOG("[lobby] CRC match %s with currently loaded content\n", current); strlcpy(state->content_path, "N/A", sizeof(state->content_path)); state->found = true; @@ -225,58 +247,52 @@ static void task_netplay_crc_scan_handler(retro_task_t *task) } /* now let's do the search */ - for(i = 0; i < state->lpl_list->size; i++) + if (string_is_empty(state->subsystem_name) || string_is_equal(state->subsystem_name, "N/A")) { - playlist_t *playlist = NULL; - unsigned playlist_size = 0; - const char *lpl_path = state->lpl_list->elems[i].data; + for(i = 0; i < state->lpl_list->size; i++) + { + playlist_t *playlist = NULL; + unsigned playlist_size = 0; + const char *lpl_path = state->lpl_list->elems[i].data; - /* skip files without .lpl file extension */ - if (!strstr(lpl_path, file_path_str(FILE_PATH_LPL_EXTENSION))) - continue; + /* skip files without .lpl file extension */ + if (!strstr(lpl_path, file_path_str(FILE_PATH_LPL_EXTENSION))) + continue; - RARCH_LOG("Searching playlist: %s\n", lpl_path); - playlist = playlist_init(lpl_path, 99999); - playlist_size = playlist_get_size(playlist); + RARCH_LOG("[lobby] searching playlist: %s\n", lpl_path); + playlist = playlist_init(lpl_path, 99999); + playlist_size = playlist_get_size(playlist); - for(j = 0; j < playlist_size; j++) - { - const char *playlist_crc32 = NULL; - const char *playlist_path = NULL; + for(j = 0; j < playlist_size; j++) + { + const char *playlist_crc32 = NULL; + const char *playlist_path = NULL; - playlist_get_index(playlist, j, &playlist_path, NULL, NULL, NULL, NULL, &playlist_crc32); + playlist_get_index(playlist, j, &playlist_path, NULL, NULL, NULL, NULL, &playlist_crc32); - if(have_crc && string_is_equal(playlist_crc32, state->content_crc)) - { - RARCH_LOG("[lobby] CRC match %s\n", playlist_crc32); - strlcpy(state->content_path, playlist_path, sizeof(state->content_path)); - state->found = true; - task_set_data(task, state); - finish_task(task, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_COMPAT_CONTENT_FOUND)); - string_list_free(state->lpl_list); - free(playlist); - return; - } + if(have_crc && string_is_equal(playlist_crc32, state->content_crc)) + { + RARCH_LOG("[lobby] CRC match %s\n", playlist_crc32); + strlcpy(state->content_path, playlist_path, sizeof(state->content_path)); + state->found = true; + task_set_data(task, state); + finish_task(task, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_COMPAT_CONTENT_FOUND)); + string_list_free(state->lpl_list); + playlist_free(playlist); + return; + } - get_entry(entry, sizeof(entry), playlist_path); + get_entry(entry, sizeof(entry), playlist_path); - /* See if the filename is a match. The response depends on whether or not we are doing a CRC - * search. - * - * If we are doing a CRC search, we stow a copy of the filename match in filename_match, which - * we'll use as our match if the CRC search is exhausted without a match. - * - * Otherwise, on match we complete the task and mark it as successful immediately. - */ - if(string_is_empty(filename_match) && - !string_is_empty(entry) && - string_is_equal(entry, state->content_path) && - strstr(state->core_extensions, path_get_extension(playlist_path))) - { - if(have_crc) - filename_match = strdup(playlist_path); - else - { + /* See if the filename is a match. The response depends on whether or not we are doing a CRC + * search. + * Otherwise, on match we complete the task and mark it as successful immediately. + */ + + if(!string_is_empty(entry) && + string_is_equal(entry, state->content_path) && + strstr(state->core_extensions, path_get_extension(playlist_path))) + { RARCH_LOG("[lobby] filename match %s\n", playlist_path); strlcpy(state->content_path, playlist_path, sizeof(state->content_path)); @@ -284,26 +300,88 @@ static void task_netplay_crc_scan_handler(retro_task_t *task) task_set_data(task, state); finish_task(task, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_COMPAT_CONTENT_FOUND)); string_list_free(state->lpl_list); - free(playlist); + playlist_free(playlist); return; } + task_set_progress(task, (int)(j / playlist_size * 100.0)); + } + playlist_free(playlist); + } + } + else + { + bool found[100]; + struct string_list *game_list = string_split(state->content_path, "|"); + + for (i = 0; i < game_list->size; i++) + { + found[i] = false; + + for(j = 0; j < state->lpl_list->size && !found[i]; j++) + { + playlist_t *playlist = NULL; + unsigned playlist_size = 0; + const char *lpl_path = state->lpl_list->elems[j].data; + + /* skip files without .lpl file extension */ + if (!strstr(lpl_path, file_path_str(FILE_PATH_LPL_EXTENSION))) + continue; + + RARCH_LOG("[lobby] searching rom %d/%d (%s) in playlist: %s\n", i + 1, game_list->size, game_list->elems[i].data, lpl_path); + playlist = playlist_init(lpl_path, 99999); + playlist_size = playlist_get_size(playlist); + + + for(k = 0; k < playlist_size && !found[i]; k++) + { + const char *playlist_crc32 = NULL; + const char *playlist_path = NULL; + + playlist_get_index(playlist, k, &playlist_path, NULL, NULL, NULL, NULL, &playlist_crc32); + get_entry(entry, sizeof(entry), playlist_path); + + if(!string_is_empty(entry) && + strstr(game_list->elems[i].data, entry) && + strstr(state->core_extensions, path_get_extension(playlist_path))) + { + RARCH_LOG("[lobby] filename match %s\n", playlist_path); + + if (i == 0) + { + state->content_path[0] = '\0'; + strlcpy(state->content_path, playlist_path, sizeof(state->content_path)); + } + else + { + strlcat(state->content_path, "|", sizeof(state->content_path)); + strlcat(state->content_path, playlist_path, sizeof(state->content_path)); + } + found[i] = true; + } + task_set_progress(task, (int)(j / playlist_size * 100.0)); + } + playlist_free(playlist); } - task_set_progress(task, (int)(j / playlist_size * 100.0)); } - free(playlist); - } + for (i = 0; i < game_list->size; i++) + { + state->found = true; + if (found[i] == false) + { + state->found = false; + break; + } + } - if(filename_match != NULL) - { - RARCH_LOG("[lobby] CRC match failed; falling back to filename match %s\n", filename_match); - - strlcpy(state->content_path, filename_match, sizeof(state->content_path)); - state->found = true; - task_set_data(task, state); - finish_task(task, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_COMPAT_CONTENT_FOUND)); + if (state->found) + { + RARCH_LOG("[lobby] subsystem matching set found %s\n", state->content_path); + task_set_data(task, state); + finish_task(task, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_COMPAT_CONTENT_FOUND)); + } string_list_free(state->lpl_list); - free(filename_match); + string_list_free(game_list); return; } @@ -315,7 +393,7 @@ static void task_netplay_crc_scan_handler(retro_task_t *task) } bool task_push_netplay_crc_scan(uint32_t crc, char* name, - const char *hostname, const char *core_name) + const char *hostname, const char *core_name, const char *subsystem) { unsigned i; union string_list_elem_attr attr; @@ -330,10 +408,11 @@ bool task_push_netplay_crc_scan(uint32_t crc, char* name, if (!task || !state) goto error; - state->content_crc[0] = '\0'; - state->content_path[0] = '\0'; - state->hostname[0] = '\0'; - state->core_name[0] = '\0'; + state->content_crc[0] = '\0'; + state->content_path[0] = '\0'; + state->hostname[0] = '\0'; + state->core_name[0] = '\0'; + state->subsystem_name[0] = '\0'; attr.i = 0; snprintf(state->content_crc, @@ -344,6 +423,8 @@ bool task_push_netplay_crc_scan(uint32_t crc, char* name, name, sizeof(state->content_path)); strlcpy(state->hostname, hostname, sizeof(state->hostname)); + strlcpy(state->subsystem_name, + subsystem, sizeof(state->subsystem_name)); strlcpy(state->core_name, core_name, sizeof(state->core_name)); diff --git a/tasks/tasks_internal.h b/tasks/tasks_internal.h index 16d44d8631..5135c1cf32 100644 --- a/tasks/tasks_internal.h +++ b/tasks/tasks_internal.h @@ -113,7 +113,7 @@ bool task_push_wifi_scan(retro_task_callback_t cb); bool task_push_netplay_lan_scan(retro_task_callback_t cb); bool task_push_netplay_crc_scan(uint32_t crc, char* name, - const char *hostname, const char *corename); + const char *hostname, const char *corename, const char* subsystem); bool task_push_netplay_lan_scan_rooms(retro_task_callback_t cb);