1
0
mirror of https://github.com/libretro/RetroArch synced 2024-07-03 00:38:44 +00:00

(steam) Initial integration with Steam API w/ mist (#13710)

This commit is contained in:
Mats 2022-03-09 15:05:07 +01:00 committed by GitHub
parent de22e06862
commit 249241d7cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 1000 additions and 1 deletions

View File

@ -2457,6 +2457,13 @@ ifeq ($(ANDROID), 1)
OBJ += play_feature_delivery/play_feature_delivery.o
endif
### Steam integration using mist
ifeq ($(HAVE_MIST), 1)
INCLUDE_DIRS += -I$(MIST_PATH)/include
LDFLAGS += -L$(MIST_PATH) -lmist
OBJ += steam/steam.o tasks/task_steam.o
endif
##################################
### Classic Platform specifics ###
###############WIP################

View File

@ -666,6 +666,9 @@ static const bool menu_show_core_updater = false;
#else
static const bool menu_show_core_updater = true;
#endif
#ifdef HAVE_MIST
static const bool menu_show_core_manager_steam = true;
#endif
static const bool menu_show_legacy_thumbnail_updater = false;
static const bool menu_show_sublabels = true;
static const bool menu_dynamic_wallpaper_enable = true;

View File

@ -1862,6 +1862,9 @@ static struct config_bool_setting *populate_settings_bool(
SETTING_BOOL("menu_show_online_updater", &settings->bools.menu_show_online_updater, true, menu_show_online_updater, false);
SETTING_BOOL("menu_show_core_updater", &settings->bools.menu_show_core_updater, true, menu_show_core_updater, false);
SETTING_BOOL("menu_show_legacy_thumbnail_updater", &settings->bools.menu_show_legacy_thumbnail_updater, true, menu_show_legacy_thumbnail_updater, false);
#ifdef HAVE_MIST
SETTING_BOOL("menu_show_core_manager_steam", &settings->bools.menu_show_core_manager_steam, true, menu_show_core_manager_steam, false);
#endif
SETTING_BOOL("filter_by_current_core", &settings->bools.filter_by_current_core, true, DEFAULT_FILTER_BY_CURRENT_CORE, false);
SETTING_BOOL("rgui_show_start_screen", &settings->bools.menu_show_start_screen, false, false /* TODO */, false);
SETTING_BOOL("menu_navigation_wraparound_enable", &settings->bools.menu_navigation_wraparound_enable, true, true, false);

View File

@ -659,6 +659,9 @@ typedef struct settings
bool menu_horizontal_animation;
bool menu_scroll_fast;
bool menu_show_online_updater;
#ifdef HAVE_MIST
bool menu_show_core_manager_steam;
#endif
bool menu_show_core_updater;
bool menu_show_load_core;
bool menu_show_load_content;

View File

@ -620,6 +620,16 @@ MSG_HASH(
MENU_ENUM_LABEL_CORE_MANAGER_LIST,
"core_manager_list"
)
#ifdef HAVE_MIST
MSG_HASH(
MENU_ENUM_LABEL_CORE_STEAM_INSTALL,
"core_steam_install"
)
MSG_HASH(
MENU_ENUM_LABEL_CORE_STEAM_UNINSTALL,
"core_steam_uninstall"
)
#endif
MSG_HASH(
MENU_ENUM_LABEL_CPU_ARCHITECTURE,
"system_information_cpu_architecture"
@ -884,6 +894,12 @@ MSG_HASH(
MENU_ENUM_LABEL_DEFERRED_CORE_INFORMATION_LIST,
"deferred_core_information_list"
)
#ifdef HAVE_MIST
MSG_HASH(
MENU_ENUM_LABEL_DEFERRED_CORE_INFORMATION_STEAM_LIST,
"deferred_core_information_steam_list"
)
#endif
MSG_HASH(
MENU_ENUM_LABEL_DEFERRED_CORE_UPDATER_LIST,
"core_updater"
@ -892,6 +908,12 @@ MSG_HASH(
MENU_ENUM_LABEL_DEFERRED_CORE_MANAGER_LIST,
"deferred_core_manager_list"
)
#ifdef HAVE_MIST
MSG_HASH(
MENU_ENUM_LABEL_DEFERRED_CORE_MANAGER_STEAM_LIST,
"deferred_core_manager_steam_list"
)
#endif
MSG_HASH(
MENU_ENUM_LABEL_DEFERRED_CURSOR_MANAGER_LIST,
"deferred_cursor_manager_list"

View File

@ -3203,7 +3203,51 @@ MSG_HASH(
MENU_ENUM_SUBLABEL_CORE_MANAGER_LIST,
"Perform offline maintenance tasks on installed cores (backup, restore, delete, etc.) and view core information."
)
#ifdef HAVE_MIST
MSG_HASH(
MENU_ENUM_LABEL_VALUE_CORE_MANAGER_STEAM_LIST,
"Manage Cores"
)
MSG_HASH(
MENU_ENUM_SUBLABEL_CORE_MANAGER_STEAM_LIST,
"Install or uninstall cores distributed through Steam."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_CORE_STEAM_INSTALL,
"Install core"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_CORE_STEAM_UNINSTALL,
"Uninstall core"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_MENU_SHOW_CORE_MANAGER_STEAM,
"Show 'Manage cores'"
)
MSG_HASH(
MENU_ENUM_SUBLABEL_MENU_SHOW_CORE_MANAGER_STEAM,
"Show the 'Manage cores' option in the Main Menu."
)
MSG_HASH(
MSG_CORE_STEAM_INSTALLING,
"Installing core: "
)
MSG_HASH(
MSG_CORE_STEAM_UNINSTALLED,
"The core will uninstall when quitting RetroArch."
)
MSG_HASH(
MSG_CORE_STEAM_CURRENTLY_DOWNLOADING,
"The core is currently downloading"
)
#endif
/* Settings > Configuration */
MSG_HASH(

View File

@ -271,6 +271,11 @@ GENERIC_DEFERRED_PUSH(deferred_push_core_delete_backup_list, DISPLAYLIST_
GENERIC_DEFERRED_PUSH(deferred_push_core_manager_list, DISPLAYLIST_CORE_MANAGER_LIST)
#ifdef HAVE_MIST
GENERIC_DEFERRED_PUSH(deferred_push_core_manager_steam_list, DISPLAYLIST_CORE_MANAGER_STEAM_LIST)
GENERIC_DEFERRED_PUSH(deferred_push_core_information_steam_list, DISPLAYLIST_CORE_INFORMATION_STEAM_LIST)
#endif
GENERIC_DEFERRED_PUSH(deferred_push_file_browser_select_sideload_core, DISPLAYLIST_FILE_BROWSER_SELECT_SIDELOAD_CORE)
static int deferred_push_cursor_manager_list_deferred(
@ -891,6 +896,10 @@ static int menu_cbs_init_bind_deferred_push_compare_label(
{MENU_ENUM_LABEL_DEFERRED_CORE_RESTORE_BACKUP_LIST, deferred_push_core_restore_backup_list},
{MENU_ENUM_LABEL_DEFERRED_CORE_DELETE_BACKUP_LIST, deferred_push_core_delete_backup_list},
{MENU_ENUM_LABEL_DEFERRED_CORE_MANAGER_LIST, deferred_push_core_manager_list},
#ifdef HAVE_MIST
{MENU_ENUM_LABEL_DEFERRED_CORE_MANAGER_STEAM_LIST, deferred_push_core_manager_steam_list},
{MENU_ENUM_LABEL_DEFERRED_CORE_INFORMATION_STEAM_LIST, deferred_push_core_information_steam_list},
#endif
{MENU_ENUM_LABEL_SIDELOAD_CORE_LIST, deferred_push_file_browser_select_sideload_core},
{MENU_ENUM_LABEL_DEFERRED_ARCHIVE_ACTION_DETECT_CORE, deferred_archive_action_detect_core},
{MENU_ENUM_LABEL_DEFERRED_ARCHIVE_ACTION, deferred_archive_action},
@ -1318,6 +1327,11 @@ static int menu_cbs_init_bind_deferred_push_compare_label(
case MENU_ENUM_LABEL_DEFERRED_CORE_MANAGER_LIST:
BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_core_manager_list);
break;
#ifdef HAVE_MIST
case MENU_ENUM_LABEL_DEFERRED_CORE_MANAGER_STEAM_LIST:
BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_core_manager_steam_list);
break;
#endif
case MENU_ENUM_LABEL_SIDELOAD_CORE_LIST:
BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_file_browser_select_sideload_core);
break;

View File

@ -59,6 +59,10 @@
#include "../../cheevos/cheevos_menu.h"
#endif
#ifdef HAVE_MIST
#include "../../steam/steam.h"
#endif
#ifndef BIND_ACTION_GET_VALUE
#define BIND_ACTION_GET_VALUE(cbs, name) (cbs)->action_get_value = (name)
#endif
@ -519,6 +523,48 @@ static void menu_action_setting_disp_set_label_core_manager_entry(
}
}
#ifdef HAVE_MIST
static void menu_action_setting_disp_set_label_core_manager_steam_entry(
file_list_t* list,
unsigned *w, unsigned type, unsigned i,
const char *label,
char *s, size_t len,
const char *path,
char *s2, size_t len2)
{
steam_core_dlc_list_t *core_dlc_list = NULL;
steam_core_dlc_t *core_dlc = NULL;
bool dlc_installed = false;
*s = '\0';
*w = 0;
if (MIST_IS_ERROR(steam_get_core_dlcs(&core_dlc_list, true))) return;
strlcpy(s2, path, len2);
core_dlc = steam_get_core_dlc_by_name(core_dlc_list, path);
if (core_dlc == NULL) return;
MistResult result = mist_steam_apps_is_dlc_installed(core_dlc->app_id, &dlc_installed);
if (MIST_IS_ERROR(result))
{
RARCH_ERR("[Steam]: Failed to get dlc install status (%d-%d)\n", MIST_UNPACK_RESULT(result));
return;
}
if (dlc_installed)
{
s[0] = '[';
s[1] = '#';
s[2] = ']';
s[3] = '\0';
*w = (unsigned)STRLEN_CONST("[#]");
}
}
#endif
static void menu_action_setting_disp_set_label_contentless_core(
file_list_t* list,
unsigned *w, unsigned type, unsigned i,
@ -1931,6 +1977,12 @@ static int menu_cbs_init_bind_get_string_representation_compare_label(
BIND_ACTION_GET_VALUE(cbs,
menu_action_setting_disp_set_label_core_manager_entry);
break;
#ifdef HAVE_MIST
case MENU_ENUM_LABEL_CORE_MANAGER_STEAM_ENTRY:
BIND_ACTION_GET_VALUE(cbs,
menu_action_setting_disp_set_label_core_manager_steam_entry);
break;
#endif
case MENU_ENUM_LABEL_CONTENTLESS_CORE:
BIND_ACTION_GET_VALUE(cbs,
menu_action_setting_disp_set_label_contentless_core);

View File

@ -104,6 +104,10 @@
#include "../../switch_performance_profiles.h"
#endif
#ifdef HAVE_MIST
#include "../../steam/steam.h"
#endif
enum
{
ACTION_OK_LOAD_PRESET = 0,
@ -320,6 +324,10 @@ static enum msg_hash_enums action_ok_dl_to_enum(unsigned lbl)
return MENU_ENUM_LABEL_DEFERRED_CORE_SETTINGS_LIST;
case ACTION_OK_DL_CORE_INFORMATION_LIST:
return MENU_ENUM_LABEL_DEFERRED_CORE_INFORMATION_LIST;
#ifdef HAVE_MIST
case ACTION_OK_DL_CORE_INFORMATION_STEAM_LIST:
return MENU_ENUM_LABEL_DEFERRED_CORE_INFORMATION_STEAM_LIST;
#endif
case ACTION_OK_DL_CORE_RESTORE_BACKUP_LIST:
return MENU_ENUM_LABEL_DEFERRED_CORE_RESTORE_BACKUP_LIST;
case ACTION_OK_DL_CORE_DELETE_BACKUP_LIST:
@ -480,6 +488,10 @@ static enum msg_hash_enums action_ok_dl_to_enum(unsigned lbl)
return MENU_ENUM_LABEL_DEFERRED_MANUAL_CONTENT_SCAN_LIST;
case ACTION_OK_DL_CORE_MANAGER_LIST:
return MENU_ENUM_LABEL_DEFERRED_CORE_MANAGER_LIST;
#ifdef HAVE_MIST
case ACTION_OK_DL_CORE_MANAGER_STEAM_LIST:
return MENU_ENUM_LABEL_DEFERRED_CORE_MANAGER_STEAM_LIST;
#endif
case ACTION_OK_DL_CORE_OPTION_OVERRIDE_LIST:
return MENU_ENUM_LABEL_DEFERRED_CORE_OPTION_OVERRIDE_LIST;
default:
@ -1487,6 +1499,9 @@ int generic_action_ok_displaylist_push(const char *path,
case ACTION_OK_DL_DRIVER_SETTINGS_LIST:
case ACTION_OK_DL_CORE_SETTINGS_LIST:
case ACTION_OK_DL_CORE_INFORMATION_LIST:
#ifdef HAVE_MIST
case ACTION_OK_DL_CORE_INFORMATION_STEAM_LIST:
#endif
case ACTION_OK_DL_VIDEO_SETTINGS_LIST:
case ACTION_OK_DL_VIDEO_HDR_SETTINGS_LIST:
case ACTION_OK_DL_VIDEO_SYNCHRONIZATION_SETTINGS_LIST:
@ -1565,6 +1580,9 @@ int generic_action_ok_displaylist_push(const char *path,
case ACTION_OK_DL_CDROM_INFO_LIST:
case ACTION_OK_DL_MANUAL_CONTENT_SCAN_LIST:
case ACTION_OK_DL_CORE_MANAGER_LIST:
#ifdef HAVE_MIST
case ACTION_OK_DL_CORE_MANAGER_STEAM_LIST:
#endif
case ACTION_OK_DL_CORE_OPTION_OVERRIDE_LIST:
ACTION_OK_DL_LBL(action_ok_dl_to_enum(action_type), DISPLAYLIST_GENERIC);
break;
@ -5747,6 +5765,9 @@ DEFAULT_ACTION_OK_FUNC(action_ok_push_video_output_settings_list, ACTION_OK_DL_V
DEFAULT_ACTION_OK_FUNC(action_ok_push_configuration_settings_list, ACTION_OK_DL_CONFIGURATION_SETTINGS_LIST)
DEFAULT_ACTION_OK_FUNC(action_ok_push_core_settings_list, ACTION_OK_DL_CORE_SETTINGS_LIST)
DEFAULT_ACTION_OK_FUNC(action_ok_push_core_information_list, ACTION_OK_DL_CORE_INFORMATION_LIST)
#ifdef HAVE_MIST
DEFAULT_ACTION_OK_FUNC(action_ok_push_core_information_steam_list, ACTION_OK_DL_CORE_INFORMATION_STEAM_LIST)
#endif
DEFAULT_ACTION_OK_FUNC(action_ok_push_core_restore_backup_list, ACTION_OK_DL_CORE_RESTORE_BACKUP_LIST)
DEFAULT_ACTION_OK_FUNC(action_ok_push_core_delete_backup_list, ACTION_OK_DL_CORE_DELETE_BACKUP_LIST)
DEFAULT_ACTION_OK_FUNC(action_ok_push_audio_settings_list, ACTION_OK_DL_AUDIO_SETTINGS_LIST)
@ -5784,6 +5805,9 @@ DEFAULT_ACTION_OK_FUNC(action_ok_pl_thumbnails_updater_list, ACTION_OK_DL_PL_THU
DEFAULT_ACTION_OK_FUNC(action_ok_push_manual_content_scan_list, ACTION_OK_DL_MANUAL_CONTENT_SCAN_LIST)
DEFAULT_ACTION_OK_FUNC(action_ok_manual_content_scan_dat_file, ACTION_OK_DL_MANUAL_CONTENT_SCAN_DAT_FILE)
DEFAULT_ACTION_OK_FUNC(action_ok_push_core_manager_list, ACTION_OK_DL_CORE_MANAGER_LIST)
#ifdef HAVE_MIST
DEFAULT_ACTION_OK_FUNC(action_ok_push_core_manager_steam_list, ACTION_OK_DL_CORE_MANAGER_STEAM_LIST)
#endif
DEFAULT_ACTION_OK_FUNC(action_ok_push_core_option_override_list, ACTION_OK_DL_CORE_OPTION_OVERRIDE_LIST)
DEFAULT_ACTION_OK_FUNC(action_ok_push_core_options_list, ACTION_OK_DL_CORE_OPTIONS_LIST)
@ -7718,6 +7742,42 @@ static int action_ok_playlist_refresh(const char *path,
return 0;
}
#ifdef HAVE_MIST
static int action_ok_core_steam_install(
const char *path,
const char *label, unsigned type, size_t idx, size_t entry_idx)
{
steam_core_dlc_list_t *core_dlc_list = NULL;
steam_core_dlc_t *core_dlc = NULL;
if (MIST_IS_ERROR(steam_get_core_dlcs(&core_dlc_list, true))) return 0;
core_dlc = steam_get_core_dlc_by_name(core_dlc_list, label);
if (core_dlc == NULL) return 0;
steam_install_core_dlc(core_dlc);
return 0;
}
static int action_ok_core_steam_uninstall(
const char *path,
const char *label, unsigned type, size_t idx, size_t entry_idx)
{
steam_core_dlc_list_t *core_dlc_list = NULL;
steam_core_dlc_t *core_dlc = NULL;
if (MIST_IS_ERROR(steam_get_core_dlcs(&core_dlc_list, true))) return 0;
core_dlc = steam_get_core_dlc_by_name(core_dlc_list, label);
if (core_dlc == NULL) return 0;
steam_uninstall_core_dlc(core_dlc);
return 0;
}
#endif
static int is_rdb_entry(enum msg_hash_enums enum_idx)
{
switch (enum_idx)
@ -7994,6 +8054,9 @@ static int menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t *cbs,
{MENU_ENUM_LABEL_CORE_SETTINGS, action_ok_push_core_settings_list},
{MENU_ENUM_LABEL_CORE_INFORMATION, action_ok_push_core_information_list},
{MENU_ENUM_LABEL_CORE_MANAGER_ENTRY, action_ok_push_core_information_list},
#ifdef HAVE_MIST
{MENU_ENUM_LABEL_CORE_MANAGER_STEAM_ENTRY, action_ok_push_core_information_steam_list},
#endif
{MENU_ENUM_LABEL_CORE_RESTORE_BACKUP_LIST, action_ok_push_core_restore_backup_list},
{MENU_ENUM_LABEL_CORE_DELETE_BACKUP_LIST, action_ok_push_core_delete_backup_list},
{MENU_ENUM_LABEL_CONFIGURATION_SETTINGS, action_ok_push_configuration_settings_list},
@ -8114,6 +8177,11 @@ static int menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t *cbs,
{MENU_ENUM_LABEL_SCREEN_RESOLUTION, action_ok_video_resolution},
{MENU_ENUM_LABEL_PLAYLIST_MANAGER_DEFAULT_CORE, action_ok_playlist_default_core},
{MENU_ENUM_LABEL_CORE_MANAGER_LIST, action_ok_push_core_manager_list},
#ifdef HAVE_MIST
{MENU_ENUM_LABEL_CORE_MANAGER_STEAM_LIST, action_ok_push_core_manager_steam_list},
{MENU_ENUM_LABEL_CORE_STEAM_INSTALL, action_ok_core_steam_install},
{MENU_ENUM_LABEL_CORE_STEAM_UNINSTALL, action_ok_core_steam_uninstall},
#endif
{MENU_ENUM_LABEL_EXPLORE_TAB, action_ok_push_default},
{MENU_ENUM_LABEL_CONTENTLESS_CORES_TAB, action_ok_push_default},
};

View File

@ -525,6 +525,10 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_switch_installed_cores_pfd, MENU_
#endif
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_sideload_core_list, MENU_ENUM_SUBLABEL_SIDELOAD_CORE_LIST)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_core_manager_list, MENU_ENUM_SUBLABEL_CORE_MANAGER_LIST)
#ifdef HAVE_MIST
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_core_manager_steam_list, MENU_ENUM_SUBLABEL_CORE_MANAGER_STEAM_LIST)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_menu_show_core_manager_steam, MENU_ENUM_SUBLABEL_MENU_SHOW_CORE_MANAGER_STEAM)
#endif
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_load_disc, MENU_ENUM_SUBLABEL_LOAD_DISC)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_dump_disc, MENU_ENUM_SUBLABEL_DUMP_DISC)
#ifdef HAVE_LAKKA
@ -3739,6 +3743,14 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
case MENU_ENUM_LABEL_CORE_MANAGER_LIST:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_core_manager_list);
break;
#ifdef HAVE_MIST
case MENU_ENUM_LABEL_CORE_MANAGER_STEAM_LIST:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_core_manager_steam_list);
break;
case MENU_ENUM_LABEL_MENU_SHOW_CORE_MANAGER_STEAM:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_show_core_manager_steam);
break;
#endif
case MENU_ENUM_LABEL_VIDEO_POST_FILTER_RECORD:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_post_filter_record);
break;

View File

@ -491,6 +491,16 @@ error:
return 0;
}
#ifdef HAVE_MIST
static int action_get_core_information_steam_list(
const char *path, const char *label, unsigned menu_type,
char *s, size_t len)
{
snprintf(s, len, "%s - %s", msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CORE_INFORMATION), path);
return 1;
}
#endif
static int action_get_title_dropdown_input_description_common(
const char *input_name, unsigned port, char *s, size_t len)
{
@ -758,6 +768,9 @@ DEFAULT_TITLE_SEARCH_FILTER_MACRO(action_get_title_deferred_contentless_cores_li
DEFAULT_TITLE_SEARCH_FILTER_MACRO(action_get_core_updater_list, MENU_ENUM_LABEL_VALUE_CORE_UPDATER_LIST)
DEFAULT_TITLE_SEARCH_FILTER_MACRO(action_get_core_manager_list, MENU_ENUM_LABEL_VALUE_CORE_MANAGER_LIST)
#ifdef HAVE_MIST
DEFAULT_TITLE_SEARCH_FILTER_MACRO(action_get_core_manager_steam_list, MENU_ENUM_LABEL_VALUE_CORE_MANAGER_STEAM_LIST)
#endif
DEFAULT_TITLE_SEARCH_FILTER_MACRO(action_get_core_cheat_options_list, MENU_ENUM_LABEL_VALUE_CORE_CHEAT_OPTIONS)
DEFAULT_FILL_TITLE_SEARCH_FILTER_MACRO(action_get_title_video_shader_preset, MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_TWO)
@ -934,6 +947,9 @@ static int menu_cbs_init_bind_title_compare_label(menu_file_list_cbs_t *cbs,
{MENU_ENUM_LABEL_DEFERRED_REMAPPINGS_PORT_LIST, action_get_title_remap_port},
{MENU_ENUM_LABEL_DEFERRED_CORE_SETTINGS_LIST, action_get_core_settings_list},
{MENU_ENUM_LABEL_DEFERRED_CORE_INFORMATION_LIST, action_get_core_information_list},
#ifdef HAVE_MIST
{MENU_ENUM_LABEL_DEFERRED_CORE_INFORMATION_STEAM_LIST, action_get_core_information_steam_list},
#endif
{MENU_ENUM_LABEL_DEFERRED_CORE_RESTORE_BACKUP_LIST, action_get_title_deferred_core_restore_backup_list},
{MENU_ENUM_LABEL_DEFERRED_CORE_DELETE_BACKUP_LIST, action_get_title_deferred_core_delete_backup_list},
{MENU_ENUM_LABEL_DEFERRED_DUMP_DISC_LIST, action_get_dump_disc_list},
@ -1142,6 +1158,10 @@ static int menu_cbs_init_bind_title_compare_label(menu_file_list_cbs_t *cbs,
action_get_core_updater_list},
{MENU_ENUM_LABEL_DEFERRED_CORE_MANAGER_LIST,
action_get_core_manager_list},
#ifdef HAVE_MIST
{MENU_ENUM_LABEL_DEFERRED_CORE_MANAGER_STEAM_LIST,
action_get_core_manager_steam_list},
#endif
{MENU_ENUM_LABEL_CONFIGURATIONS_LIST,
action_get_configurations_list},
{MENU_ENUM_LABEL_ADD_CONTENT_LIST,
@ -1463,6 +1483,11 @@ static int menu_cbs_init_bind_title_compare_label(menu_file_list_cbs_t *cbs,
case MENU_ENUM_LABEL_DEFERRED_CORE_MANAGER_LIST:
BIND_ACTION_GET_TITLE(cbs, action_get_core_manager_list);
break;
#ifdef HAVE_MIST
case MENU_ENUM_LABEL_DEFERRED_CORE_MANAGER_STEAM_LIST:
BIND_ACTION_GET_TITLE(cbs, action_get_core_manager_steam_list);
break;
#endif
case MENU_ENUM_LABEL_ADD_CONTENT_LIST:
BIND_ACTION_GET_TITLE(cbs, action_get_add_content_list);
break;
@ -1546,6 +1571,11 @@ static int menu_cbs_init_bind_title_compare_label(menu_file_list_cbs_t *cbs,
case MENU_ENUM_LABEL_DEFERRED_CORE_INFORMATION_LIST:
BIND_ACTION_GET_TITLE(cbs, action_get_core_information_list);
break;
#ifdef HAVE_MIST
case MENU_ENUM_LABEL_DEFERRED_CORE_INFORMATION_STEAM_LIST:
BIND_ACTION_GET_TITLE(cbs, action_get_core_information_steam_list);
break;
#endif
case MENU_ENUM_LABEL_DEFERRED_CORE_RESTORE_BACKUP_LIST:
BIND_ACTION_GET_TITLE(cbs, action_get_title_deferred_core_restore_backup_list);
break;

View File

@ -9337,6 +9337,16 @@ static int materialui_list_push(void *data, void *userdata,
false);
}
#endif
#endif
#ifdef HAVE_MIST
if (settings->bools.menu_show_core_manager_steam)
{
MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(
info->list,
MENU_ENUM_LABEL_CORE_MANAGER_STEAM_LIST,
PARSE_ACTION,
false);
}
#endif
if (settings->uints.menu_content_show_add_entry ==
MENU_ADD_CONTENT_ENTRY_DISPLAY_MAIN_TAB)

View File

@ -7990,6 +7990,16 @@ static int ozone_list_push(void *data, void *userdata,
false);
}
#endif
#endif
#ifdef HAVE_MIST
if (settings->bools.menu_show_core_manager_steam && !settings->bools.kiosk_mode_enable)
{
MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(
info->list,
MENU_ENUM_LABEL_CORE_MANAGER_STEAM_LIST,
PARSE_ACTION,
false);
}
#endif
if (!settings->bools.menu_content_show_settings && !string_is_empty(settings->paths.menu_content_show_settings_password))
{

View File

@ -7036,6 +7036,9 @@ static int xmb_list_push(void *data, void *userdata,
#endif
#if defined(HAVE_NETWORKING) && defined(HAVE_ONLINE_UPDATER)
bool menu_show_online_updater = settings->bools.menu_show_online_updater;
#endif
#if defined(HAVE_MIST)
bool menu_show_core_manager_steam = settings->bools.menu_show_core_manager_steam;
#endif
bool menu_content_show_settings = settings->bools.menu_content_show_settings;
const char *menu_content_show_settings_password =
@ -7200,6 +7203,16 @@ static int xmb_list_push(void *data, void *userdata,
false);
}
#endif
#endif
#ifdef HAVE_MIST
if (menu_show_core_manager_steam && !kiosk_mode_enable)
{
MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(
info->list,
MENU_ENUM_LABEL_CORE_MANAGER_STEAM_LIST,
PARSE_ACTION,
false);
}
#endif
if ( !menu_content_show_settings &&
!string_is_empty(menu_content_show_settings_password))

View File

@ -117,6 +117,9 @@ enum
ACTION_OK_DL_CHEAT_SEARCH_SETTINGS_LIST,
ACTION_OK_DL_CORE_SETTINGS_LIST,
ACTION_OK_DL_CORE_INFORMATION_LIST,
#ifdef HAVE_MIST
ACTION_OK_DL_CORE_INFORMATION_STEAM_LIST,
#endif
ACTION_OK_DL_INPUT_HOTKEY_BINDS_LIST,
ACTION_OK_DL_RECORDING_SETTINGS_LIST,
ACTION_OK_DL_PLAYLIST_SETTINGS_LIST,
@ -151,6 +154,9 @@ enum
ACTION_OK_DL_CURSOR_MANAGER_LIST,
ACTION_OK_DL_CORE_UPDATER_LIST,
ACTION_OK_DL_CORE_MANAGER_LIST,
#ifdef HAVE_MIST
ACTION_OK_DL_CORE_MANAGER_STEAM_LIST,
#endif
ACTION_OK_DL_THUMBNAILS_UPDATER_LIST,
ACTION_OK_DL_PL_THUMBNAILS_UPDATER_LIST,
ACTION_OK_DL_BROWSE_URL_LIST,

View File

@ -123,6 +123,10 @@
#include "../misc/cpufreq/cpufreq.h"
#include "../input/input_remapping.h"
#ifdef HAVE_MIST
#include "../steam/steam.h"
#endif
/* Spacers used for '<content> - <core name>' labels
* in playlists */
#define PL_LABEL_SPACER_DEFAULT " | "
@ -985,6 +989,91 @@ static unsigned menu_displaylist_parse_core_manager_list(
return count;
}
#ifdef HAVE_MIST
static unsigned menu_displaylist_parse_core_manager_steam_list(
menu_displaylist_info_t *info,
settings_t *settings)
{
MistResult result;
steam_core_dlc_list_t *dlc_list;
steam_core_dlc_t *dlc_info;
size_t i;
unsigned count = 0;
result = steam_get_core_dlcs(&dlc_list, false);
if (MIST_IS_ERROR(result)) goto error;
for (i = 0; i < dlc_list->count; i++)
{
dlc_info = steam_core_dlc_list_get(dlc_list, i);
if (menu_entries_append_enum(info->list,
dlc_info->name,
"",
MENU_ENUM_LABEL_CORE_MANAGER_STEAM_ENTRY,
MENU_SETTING_ACTION_CORE_MANAGER_STEAM_OPTIONS,
0, 0))
count++;
}
return count;
error:
/* TODO: Send error notification */
RARCH_ERR("[Steam] Error enumerating core dlcs for core manager (%d-%d)\n", MIST_UNPACK_RESULT(result));
return count;
}
static unsigned menu_displaylist_parse_core_information_steam(
menu_displaylist_info_t *info,
settings_t *settings)
{
unsigned count = 0;
MistResult result;
steam_core_dlc_list_t *dlc_list;
steam_core_dlc_t *core_dlc = NULL;
bool installed = false;
result = steam_get_core_dlcs(&dlc_list, false);
if (MIST_IS_ERROR(result)) goto error;
/* Get the core dlc information */
core_dlc = steam_get_core_dlc_by_name(dlc_list, info->path);
if (core_dlc == NULL) return count;
/* Check if installed */
result = mist_steam_apps_is_dlc_installed(core_dlc->app_id, &installed);
if (MIST_IS_ERROR(result)) goto error;
if (installed)
{
if (menu_entries_append_enum(info->list,
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CORE_STEAM_UNINSTALL),
core_dlc->name,
MENU_ENUM_LABEL_CORE_STEAM_UNINSTALL,
MENU_SETTING_ACTION_CORE_STEAM_UNINSTALL,
0, 0))
count++;
}
else
{
if (menu_entries_append_enum(info->list,
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CORE_STEAM_INSTALL),
core_dlc->name,
MENU_ENUM_LABEL_CORE_STEAM_INSTALL,
MENU_SETTING_ACTION_CORE_STEAM_INSTALL,
0, 0))
count++;
}
return count;
error:
/* TODO: Send error notification */
RARCH_ERR("[Steam] Error getting core information (%d-%d)\n", MIST_UNPACK_RESULT(result));
return count;
}
#endif
static unsigned menu_displaylist_parse_core_option_dropdown_list(
menu_displaylist_info_t *info)
{
@ -8328,9 +8417,14 @@ unsigned menu_displaylist_build_list(
#ifdef HAVE_LAKKA
{MENU_ENUM_LABEL_MENU_SHOW_EJECT_DISC, PARSE_ONLY_BOOL, true },
#endif
#ifdef HAVE_ONLINE_UPDATER
{MENU_ENUM_LABEL_MENU_SHOW_ONLINE_UPDATER, PARSE_ONLY_BOOL, true },
{MENU_ENUM_LABEL_MENU_SHOW_CORE_UPDATER, PARSE_ONLY_BOOL, true },
{MENU_ENUM_LABEL_MENU_SHOW_LEGACY_THUMBNAIL_UPDATER, PARSE_ONLY_BOOL, true },
#endif
#ifdef HAVE_MIST
{MENU_ENUM_LABEL_MENU_SHOW_CORE_MANAGER_STEAM, PARSE_ONLY_BOOL, true },
#endif
{MENU_ENUM_LABEL_MENU_SHOW_INFORMATION, PARSE_ONLY_BOOL, true },
{MENU_ENUM_LABEL_MENU_SHOW_CONFIGURATIONS, PARSE_ONLY_BOOL, true },
{MENU_ENUM_LABEL_MENU_SHOW_HELP, PARSE_ONLY_BOOL, true },
@ -11778,6 +11872,42 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type,
info->need_push = true;
}
break;
#ifdef HAVE_MIST
case DISPLAYLIST_CORE_MANAGER_STEAM_LIST:
menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list);
count = menu_displaylist_parse_core_manager_steam_list(info, settings);
info->need_navigation_clear = true;
info->need_refresh = false;
info->need_push = true;
/* No core dlcs were found */
if (count == 0)
if (menu_entries_append_enum(info->list,
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_ENTRIES_TO_DISPLAY),
msg_hash_to_str(MENU_ENUM_LABEL_NO_ENTRIES_TO_DISPLAY),
MENU_ENUM_LABEL_NO_ENTRIES_TO_DISPLAY,
FILE_TYPE_NONE, 0, 0))
count++;
break;
case DISPLAYLIST_CORE_INFORMATION_STEAM_LIST:
menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list);
info->need_navigation_clear = true;
info->need_refresh = false;
info->need_push = true;
count = menu_displaylist_parse_core_information_steam(info, settings);
if (count == 0)
if (menu_entries_append_enum(info->list,
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_ENTRIES_TO_DISPLAY),
msg_hash_to_str(MENU_ENUM_LABEL_NO_ENTRIES_TO_DISPLAY),
MENU_ENUM_LABEL_NO_ENTRIES_TO_DISPLAY,
FILE_TYPE_NONE, 0, 0))
count++;
break;
#endif
case DISPLAYLIST_CONTENTLESS_CORES:
{
size_t contentless_core_ptr =
@ -12362,7 +12492,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type,
#endif
#endif
#ifdef HAVE_COMPRESSION
#if defined(HAVE_COMPRESSION) && !defined(HAVE_MIST)
if (menu_entries_append_enum(info->list,
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DOWNLOAD_CORE_SYSTEM_FILES),
msg_hash_to_str(MENU_ENUM_LABEL_DOWNLOAD_CORE_SYSTEM_FILES),
@ -12716,6 +12846,13 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type,
MENU_ENUM_LABEL_ONLINE_UPDATER,
PARSE_ACTION, false) == 0)
count++;
#endif
#ifdef HAVE_MIST
if (settings->bools.menu_show_core_manager_steam)
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(info->list,
MENU_ENUM_LABEL_CORE_MANAGER_STEAM_LIST,
PARSE_ACTION, false) == 0)
count++;
#endif
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(info->list,
MENU_ENUM_LABEL_SETTINGS, PARSE_ACTION, false) == 0)

View File

@ -103,6 +103,10 @@ enum menu_displaylist_ctl_state
DISPLAYLIST_CORES_COLLECTION_SUPPORTED,
DISPLAYLIST_CORES_UPDATER,
DISPLAYLIST_CORE_MANAGER_LIST,
#ifdef HAVE_MIST
DISPLAYLIST_CORE_MANAGER_STEAM_LIST,
DISPLAYLIST_CORE_INFORMATION_STEAM_LIST,
#endif
DISPLAYLIST_THUMBNAILS_UPDATER,
DISPLAYLIST_PL_THUMBNAILS_UPDATER,
DISPLAYLIST_LAKKA,

View File

@ -131,6 +131,11 @@ enum menu_settings_type
MENU_SETTING_ACTION_CORE_INPUT_REMAPPING_OPTIONS,
MENU_SETTING_ACTION_CORE_CHEAT_OPTIONS,
MENU_SETTING_ACTION_CORE_MANAGER_OPTIONS,
#ifdef HAVE_MIST
MENU_SETTING_ACTION_CORE_MANAGER_STEAM_OPTIONS,
MENU_SETTING_ACTION_CORE_STEAM_INSTALL,
MENU_SETTING_ACTION_CORE_STEAM_UNINSTALL,
#endif
MENU_SETTING_ACTION_CORE_DISK_OPTIONS,
MENU_SETTING_ACTION_CORE_SHADER_OPTIONS,
MENU_SETTING_ACTION_SAVESTATE,

View File

@ -9202,6 +9202,16 @@ static bool setting_append_list(
parent_group);
#endif
#ifdef HAVE_MIST
CONFIG_ACTION(
list, list_info,
MENU_ENUM_LABEL_CORE_MANAGER_STEAM_LIST,
MENU_ENUM_LABEL_VALUE_CORE_MANAGER_STEAM_LIST,
&group_info,
&subgroup_info,
parent_group);
#endif
CONFIG_ACTION(
list, list_info,
MENU_ENUM_LABEL_SETTINGS,
@ -17868,6 +17878,23 @@ static bool setting_append_list(
SD_FLAG_NONE);
#endif
#ifdef HAVE_MIST
CONFIG_BOOL(
list, list_info,
&settings->bools.menu_show_core_manager_steam,
MENU_ENUM_LABEL_MENU_SHOW_CORE_MANAGER_STEAM,
MENU_ENUM_LABEL_VALUE_MENU_SHOW_CORE_MANAGER_STEAM,
menu_show_core_manager_steam,
MENU_ENUM_LABEL_VALUE_OFF,
MENU_ENUM_LABEL_VALUE_ON,
&group_info,
&subgroup_info,
parent_group,
general_write_handler,
general_read_handler,
SD_FLAG_NONE);
#endif
CONFIG_BOOL(
list, list_info,
&settings->bools.settings_show_drivers,

View File

@ -746,6 +746,9 @@ enum msg_hash_enums
MENU_ENUM_LABEL_SYSTEM_INFO_CONTROLLER_ENTRY,
MENU_ENUM_LABEL_CORE_INFO_ENTRY,
MENU_ENUM_LABEL_CORE_MANAGER_ENTRY,
#ifdef HAVE_MIST
MENU_ENUM_LABEL_CORE_MANAGER_STEAM_ENTRY,
#endif
MENU_ENUM_LABEL_PLAYLIST_ENTRY,
MENU_LABEL(START_VIDEO_PROCESSOR),
@ -1573,6 +1576,9 @@ enum msg_hash_enums
MENU_ENUM_LABEL_DEFERRED_CORE_LIST,
MENU_ENUM_LABEL_DEFERRED_CORE_UPDATER_LIST,
MENU_ENUM_LABEL_DEFERRED_CORE_MANAGER_LIST,
#ifdef HAVE_MIST
MENU_ENUM_LABEL_DEFERRED_CORE_MANAGER_STEAM_LIST,
#endif
MENU_ENUM_LABEL_DEFERRED_THUMBNAILS_UPDATER_LIST,
MENU_ENUM_LABEL_DEFERRED_PL_THUMBNAILS_UPDATER_LIST,
MENU_ENUM_LABEL_DEFERRED_RECORDING_SETTINGS_LIST,
@ -1640,6 +1646,9 @@ enum msg_hash_enums
MENU_ENUM_LABEL_DEFERRED_AUDIO_MIXER_SETTINGS_LIST,
MENU_ENUM_LABEL_DEFERRED_CORE_SETTINGS_LIST,
MENU_ENUM_LABEL_DEFERRED_CORE_INFORMATION_LIST,
#ifdef HAVE_MIST
MENU_ENUM_LABEL_DEFERRED_CORE_INFORMATION_STEAM_LIST,
#endif
MENU_ENUM_LABEL_DEFERRED_CORE_RESTORE_BACKUP_LIST,
MENU_ENUM_LABEL_DEFERRED_CORE_DELETE_BACKUP_LIST,
MENU_ENUM_LABEL_DEFERRED_CORE_OPTION_OVERRIDE_LIST,
@ -2251,6 +2260,15 @@ enum msg_hash_enums
MENU_LABEL(START_CORE),
MENU_LABEL(CORE_UPDATER_LIST),
MENU_LABEL(CORE_MANAGER_LIST),
#ifdef HAVE_MIST
MENU_LABEL(CORE_MANAGER_STEAM_LIST),
MENU_LABEL(CORE_STEAM_INSTALL),
MENU_LABEL(CORE_STEAM_UNINSTALL),
MENU_LABEL(MENU_SHOW_CORE_MANAGER_STEAM),
MSG_CORE_STEAM_INSTALLING,
MSG_CORE_STEAM_UNINSTALLED,
MSG_CORE_STEAM_CURRENTLY_DOWNLOADING,
#endif
MENU_LABEL(CORE_UPDATER_AUTO_EXTRACT_ARCHIVE),
MENU_LABEL(CORE_UPDATER_SHOW_EXPERIMENTAL_CORES),
MENU_LABEL(CORE_UPDATER_AUTO_BACKUP),

View File

@ -595,7 +595,25 @@ if [ "$HAVE_STEAM" = 'yes' ]; then
add_opt UPDATE_CORES no
die : 'Notice: Steam build enabled, disabling:'
die : '* Core info cache.'
die : '* Core updater.'
die : '* Online updater.'
# Keep base directory relative to installation on Linux just like it is on Windows
if [ "$OS" = "Linux" ]; then
add_define MAKEFILE UNIX_CWD_ENV 1
fi
fi
if [ "$HAVE_MIST" = 'yes' ]; then
if [ "$HAVE_STEAM" != 'yes' ]; then
die 1 'Error: mist builds requires steam to be enabled'
fi
if [ ! -d "$MIST_PATH" ]; then
die 1 'Error: MIST_PATH must be pointing to the location of mist artifacts'
fi
add_define MAKEFILE MIST_PATH "$MIST_PATH"
fi
check_enabled CXX SLANG slang 'The C++ compiler is' false

View File

@ -189,6 +189,7 @@ HAVE_METAL=no # Metal support (macOS-only)
C89_METAL=no
HAVE_NETWORK_VIDEO=no
HAVE_STEAM=no # Enable Steam build
HAVE_MIST=no # Enable Steam build w/ mist
HAVE_ODROIDGO2=no # ODROID-GO Advance rotation support (requires librga)
HAVE_LIBSHAKE=no # libShake haptic feedback support
HAVE_CHECK=no # check support for unit tests

View File

@ -106,6 +106,10 @@
#include "network/discord.h"
#endif
#ifdef HAVE_MIST
#include "steam/steam.h"
#endif
#include "config.def.h"
#include "runloop.h"
@ -3740,6 +3744,10 @@ void main_exit(void *args)
play_feature_delivery_deinit();
#endif
#if defined(HAVE_MIST)
steam_deinit();
#endif
#if defined(_WIN32) && !defined(_XBOX) && !defined(__WINRT__)
CoUninitialize();
#endif
@ -3788,6 +3796,10 @@ int rarch_main(int argc, char *argv[], void *data)
play_feature_delivery_init();
#endif
#if defined(HAVE_MIST)
steam_init();
#endif
libretro_free_system_info(&runloop_st->system.info);
command_event(CMD_EVENT_HISTORY_DEINIT, NULL);
rarch_favorites_deinit();
@ -3850,6 +3862,10 @@ int rarch_main(int argc, char *argv[], void *data)
task_queue_check();
#ifdef HAVE_MIST
steam_poll();
#endif
#ifdef HAVE_QT
app_exit = ui_companion_qt.application->exiting;
#endif

325
steam/steam.c Normal file
View File

@ -0,0 +1,325 @@
#include <ctype.h>
#include <mist.h>
#include <stdio.h>
#include <string.h>
#include "../menu/menu_entries.h"
#include "../retroarch.h"
#include "../runloop.h"
#include "verbosity.h"
#include "steam.h"
static bool mist_initialized = false;
static steam_core_dlc_list_t *mist_dlc_list = NULL;
void str_to_lower(char *str)
{
for (size_t i = 0; str[i] != '\0'; i++)
{
str[i] = tolower(str[i]);
}
}
void steam_init(void)
{
MistResult result;
result = mist_subprocess_init();
if (MIST_IS_SUCCESS(result))
mist_initialized = true;
else
RARCH_ERR("[Steam]: Failed to initialize mist subprocess (%d-%d)\n", MIST_UNPACK_RESULT(result));
}
void steam_poll(void)
{
MistResult result;
MistCallbackMsg callback;
steam_core_dlc_list_t *core_dlc_list;
bool has_callback = false;
static bool has_poll_errored = false;
result = mist_poll();
if (MIST_IS_ERROR(result))
{
if(has_poll_errored) return;
RARCH_ERR("[Steam]: Error polling (%d-%d)\n", MIST_UNPACK_RESULT(result));
has_poll_errored = true;
}
result = mist_next_callback(&has_callback, &callback);
if(MIST_IS_ERROR(result)) return;
while (has_callback && MIST_IS_SUCCESS(result))
{
switch (callback.callback)
{
/* Reload core info and Steam Core DLC mappings */
case MistCallback_DlcInstalled:
steam_get_core_dlcs(&core_dlc_list, true);
command_event(CMD_EVENT_CORE_INFO_INIT, NULL);
break;
}
result = mist_next_callback(&has_callback, &callback);
}
}
steam_core_dlc_list_t *steam_core_dlc_list_new(size_t count)
{
steam_core_dlc_list_t *core_dlc_list = (steam_core_dlc_list_t*)
malloc(sizeof(*core_dlc_list));
core_dlc_list->list = (steam_core_dlc_t*)
malloc(count * sizeof(*core_dlc_list->list));
core_dlc_list->count = 0; /* This is incremented inside the setup function */
return core_dlc_list;
}
void steam_core_dlc_list_free(steam_core_dlc_list_t *list)
{
if (list == NULL) return;
for (size_t i = 0; list->count > i; i++)
{
if (list->list[i].name != NULL)
free(list->list[i].name);
if (list->list[i].name_lower != NULL)
free(list->list[i].name_lower);
}
free(list->list);
free(list);
}
steam_core_dlc_t *steam_core_dlc_list_get(steam_core_dlc_list_t *list, size_t i)
{
if (!list || (i >= list->count))
return NULL;
return &list->list[i];
}
/* Sort the dlc cores alphabetically based on their name */
static int dlc_core_qsort_cmp(const void *a_, const void *b_)
{
const steam_core_dlc_t *a = (const steam_core_dlc_t*)a_;
const steam_core_dlc_t *b = (const steam_core_dlc_t*)b_;
return strcasecmp(a->name, b->name);
}
/* Find core info for dlcs
* TODO: This currently only uses core info for cores that are installed */
core_info_t* steam_find_core_info_for_dlc(const char* name)
{
size_t name_len = strlen(name);
core_info_list_t *core_info_list = NULL;
core_info_get_list(&core_info_list);
if (core_info_list == NULL) return NULL;
for (int i = 0; core_info_list->count > i; i++)
{
core_info_t *core_info = core_info_get(core_info_list, i);
char core_info_name[256] = {0};
/* Find the opening parenthesis for the core name */
char *start = strchr(core_info->display_name, '(');
if (start == NULL) continue;
/* Skip the first parenthesis and copy it to the stack */
strncpy(core_info_name, start + 1, sizeof(core_info_name) - 1);
/* Null terminate at the closing parenthesis. */
char *end = strchr((const char*)&core_info_name, ')');
if (end == NULL) continue;
else *end = '\0';
/* Make it lowercase */
str_to_lower((char*)&core_info_name);
/* Check if it matches */
if (strcasecmp(core_info_name, name) == 0)
return core_info;
}
return NULL;
}
/* Generate a list with core dlcs
* Needs to be called after initializion because it uses core info */
MistResult steam_generate_core_dlcs_list(steam_core_dlc_list_t **list)
{
MistResult result;
int count;
steam_core_dlc_list_t *dlc_list = NULL;
MistDlcData dlc_data;
result = mist_steam_apps_get_dlc_count(&count);
if (MIST_IS_ERROR(result)) goto error;
dlc_list = steam_core_dlc_list_new(count);
for (int i = 0; count > i; i++)
{
steam_core_dlc_t core_dlc;
result = mist_steam_apps_get_dlc_data_by_index(i, &dlc_data);
if (MIST_IS_ERROR(result)) goto error;
core_dlc.app_id = dlc_data.app_id;
/* Strip away the "RetroArch - " prefix if present */
if (strncmp(dlc_data.name, "RetroArch - ", sizeof("RetroArch - ") - 1) == 0)
core_dlc.name = strdup(dlc_data.name + sizeof("RetroArch - ") - 1);
else
core_dlc.name = strdup(dlc_data.name);
/* Make a lower case version */
core_dlc.name_lower = strdup(core_dlc.name);
str_to_lower(core_dlc.name_lower);
core_dlc.core_info = steam_find_core_info_for_dlc(core_dlc.name_lower);
dlc_list->list[i] = core_dlc;
dlc_list->count++;
}
/* Sort the list */
qsort(dlc_list->list, dlc_list->count,
sizeof(steam_core_dlc_t), dlc_core_qsort_cmp);
*list = dlc_list;
return MistResult_Success;
error:
if (dlc_list != NULL) steam_core_dlc_list_free(dlc_list);
return result;
}
MistResult steam_get_core_dlcs(steam_core_dlc_list_t **list, bool cached) {
MistResult result;
steam_core_dlc_list_t *new_list = NULL;
if (cached && mist_dlc_list != NULL)
{
*list = mist_dlc_list;
return MistResult_Success;
}
result = steam_generate_core_dlcs_list(&new_list);
if (MIST_IS_ERROR(result)) return result;
if (mist_dlc_list != NULL) steam_core_dlc_list_free(mist_dlc_list);
mist_dlc_list = new_list;
*list = new_list;
return MistResult_Success;
}
steam_core_dlc_t* steam_get_core_dlc_by_name(steam_core_dlc_list_t *list, const char *name) {
steam_core_dlc_t *core_info;
for (int i = 0; list->count > i; i++)
{
core_info = steam_core_dlc_list_get(list, i);
if (strcasecmp(core_info->name, name) == 0) return core_info;
}
return NULL;
}
void steam_install_core_dlc(steam_core_dlc_t *core_dlc)
{
MistResult result;
char msg[PATH_MAX_LENGTH] = { 0 };
bool downloading = false;
bool installed = false;
uint64_t bytes_downloaded = 0;
uint64_t bytes_total = 0;
/* Check if the core is already being downloaded */
result = mist_steam_apps_get_dlc_download_progress(core_dlc->app_id, &downloading, &bytes_downloaded, &bytes_total);
if (MIST_IS_ERROR(result)) goto error;
/* Check if the core is already installed */
result = mist_steam_apps_is_dlc_installed(core_dlc->app_id, &installed);
if (MIST_IS_ERROR(result)) goto error;
if (downloading || installed)
{
runloop_msg_queue_push(msg_hash_to_str(MSG_CORE_STEAM_CURRENTLY_DOWNLOADING), 1, 180, true, NULL,
MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_ERROR);
return;
}
result = mist_steam_apps_install_dlc(core_dlc->app_id);
if (MIST_IS_ERROR(result)) goto error;
task_push_steam_core_dlc_install(core_dlc->app_id, core_dlc->name);
return;
error:
snprintf(msg, sizeof(msg), "%s: (%d-%d)",
msg_hash_to_str(MSG_ERROR),
MIST_UNPACK_RESULT(result));
runloop_msg_queue_push(msg, 1, 180, true, NULL,
MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_ERROR);
RARCH_ERR("[Steam]: Error installing DLC %d (%d-%d)\n", core_dlc->app_id, MIST_UNPACK_RESULT(result));
return;
}
void steam_uninstall_core_dlc(steam_core_dlc_t *core_dlc)
{
char msg[PATH_MAX_LENGTH] = { 0 };
MistResult result = mist_steam_apps_uninstall_dlc(core_dlc->app_id);
if (MIST_IS_ERROR(result)) goto error;
runloop_msg_queue_push(msg_hash_to_str(MSG_CORE_STEAM_UNINSTALLED), 1, 180, true, NULL,
MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
bool refresh = false;
return;
error:
snprintf(msg, sizeof(msg), "%s: (%d-%d)",
msg_hash_to_str(MSG_ERROR),
MIST_UNPACK_RESULT(result));
runloop_msg_queue_push(msg, 1, 180, true, NULL,
MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_ERROR);
RARCH_ERR("[Steam]: Error uninstalling DLC %d (%d-%d)\n", core_dlc->app_id, MIST_UNPACK_RESULT(result));
return;
}
void steam_deinit(void)
{
MistResult result;
result = mist_subprocess_deinit();
/* Free the cached dlc list */
if (mist_dlc_list != NULL) steam_core_dlc_list_free(mist_dlc_list);
if (MIST_IS_SUCCESS(result))
mist_initialized = false;
else
RARCH_ERR("[Steam]: Failed to deinitialize mist subprocess (%d-%d)\n", MIST_UNPACK_RESULT(result));
}

43
steam/steam.h Normal file
View File

@ -0,0 +1,43 @@
#ifndef __RARCH_STEAM_H
#define __RARCH_STEAM_H
#include <mist.h>
#include "core_info.h"
#define MIST_UNPACK_RESULT(result) MIST_RESULT_CODE(result), MIST_ERROR(result)
struct steam_core_dlc {
AppId app_id;
char* name;
char* name_lower;
core_info_t* core_info; /* NOTE: This will be NULL if no core info was found for the name */
};
typedef struct steam_core_dlc steam_core_dlc_t;
typedef struct
{
steam_core_dlc_t *list;
size_t count;
} steam_core_dlc_list_t;
void steam_init(void);
void steam_deinit(void);
void steam_poll(void);
MistResult steam_generate_core_dlcs_list(steam_core_dlc_list_t **list);
MistResult steam_get_core_dlcs(steam_core_dlc_list_t **list, bool cached);
steam_core_dlc_t *steam_core_dlc_list_get(steam_core_dlc_list_t *list, size_t i);
steam_core_dlc_t* steam_get_core_dlc_by_name(steam_core_dlc_list_t *list, const char *name);
void steam_core_dlc_list_free(steam_core_dlc_list_t *list); /* NOTE: This should not be called manually with lists from steam_get_core_dlcs */
void steam_install_core_dlc(steam_core_dlc_t *core_dlc);
void steam_uninstall_core_dlc(steam_core_dlc_t *core_dlc);
/* Located in tasks/task_steam.c */
void task_push_steam_core_dlc_install(AppId app_id, const char *name);
#endif /* __RARCH_STEAM_H */

108
tasks/task_steam.c Normal file
View File

@ -0,0 +1,108 @@
#include <compat/strl.h>
#include "tasks_internal.h"
#include "../menu/menu_entries.h"
#include "../runloop.h"
#include "../steam/steam.h"
typedef struct steam_core_dlc_install_state {
AppId app_id;
char *name;
bool has_downloaded;
} steam_core_dlc_install_state_t;
static void task_steam_core_dlc_install_handler(retro_task_t *task)
{
char msg[PATH_MAX_LENGTH] = { 0 };
steam_core_dlc_install_state_t *state = NULL;
MistResult result = MistResult_Success;
bool downloading = false;
uint64_t bytes_downloaded = 0;
uint64_t bytes_total = 0;
int8_t progress;
if (!task)
goto task_finished;
state = (steam_core_dlc_install_state_t*)task->state;
if (!state)
goto task_finished;
if (task_get_cancelled(task))
goto task_finished;
result = mist_steam_apps_get_dlc_download_progress(state->app_id, &downloading, &bytes_downloaded, &bytes_total);
if(MIST_IS_ERROR(result)) goto task_finished;
if(!downloading)
{
if(state->has_downloaded) goto task_finished;
}
else
state->has_downloaded = true;
// Min bytes total to avoid division by zero at start
if(bytes_total < 1) bytes_total = 1;
progress = (int8_t)((bytes_downloaded * 100) / bytes_total);
if(progress < 0) progress = 0;
if(progress > 100) progress = 100;
task_set_progress(task, progress);
return;
task_finished:
if (task) task_set_finished(task, true);
/* If finished successfully */
if(MIST_IS_SUCCESS(result))
{
/* Invalidate the core dlc cache */
steam_core_dlc_list_t *list;
steam_get_core_dlcs(&list, false);
strlcpy(msg, msg_hash_to_str(MSG_CORE_INSTALLED),
sizeof(msg));
strlcat(msg, state->name,
sizeof(msg));
runloop_msg_queue_push(msg, 1, 180, true, NULL,
MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_ERROR);
}
/* Cleanup */
if (state)
{
free(state->name);
free(state);
}
}
void task_push_steam_core_dlc_install(
AppId app_id,
const char *name)
{
char task_title[PATH_MAX_LENGTH];
retro_task_t *task = task_init();
steam_core_dlc_install_state_t* state = (steam_core_dlc_install_state_t*)calloc(1,
sizeof(steam_core_dlc_install_state_t));
state->app_id = app_id;
state->name = strdup(name);
state->has_downloaded = false;
strlcpy(task_title, msg_hash_to_str(MSG_CORE_STEAM_INSTALLING),
sizeof(task_title));
strlcat(task_title, name,
sizeof(task_title));
task->handler = task_steam_core_dlc_install_handler;
task->state = state;
task->mute = false;
task->title = strdup(task_title);
task->progress = 0;
task->callback = NULL;
task_queue_push(task);
}