diff options
author | Twinaphex | 2020-01-23 16:09:53 +0100 |
---|---|---|
committer | GitHub | 2020-01-23 16:09:53 +0100 |
commit | 9017270187ac21fdb2cb61b2a3ae97d24887d4a2 (patch) | |
tree | a6053672b23a1213211fc97a55e0274e8650a73b /frontend | |
parent | 2ca9045dfca7302d26965abe3e85846a1770dd8f (diff) | |
parent | 144493e88e8d2dc22ea9db26c56a0a492db9f5f3 (diff) | |
download | pcsx_rearmed-9017270187ac21fdb2cb61b2a3ae97d24887d4a2.tar.gz pcsx_rearmed-9017270187ac21fdb2cb61b2a3ae97d24887d4a2.tar.bz2 pcsx_rearmed-9017270187ac21fdb2cb61b2a3ae97d24887d4a2.zip |
Merge pull request #375 from jdgleaver/disk-control-v1
Add disk control interface v1 support
Diffstat (limited to 'frontend')
-rw-r--r-- | frontend/libretro.c | 285 |
1 files changed, 251 insertions, 34 deletions
diff --git a/frontend/libretro.c b/frontend/libretro.c index ab85421..64e4145 100644 --- a/frontend/libretro.c +++ b/frontend/libretro.c @@ -848,15 +848,72 @@ void retro_cheat_set(unsigned index, bool enabled, const char *code) Cheats[index].Enabled = enabled; } +// just in case, maybe a win-rt port in the future? +#ifdef _WIN32 +#define SLASH '\\' +#else +#define SLASH '/' +#endif + +#ifndef PATH_MAX +#define PATH_MAX 4096 +#endif + /* multidisk support */ +static unsigned int disk_initial_index; +static char disk_initial_path[PATH_MAX]; static bool disk_ejected; static unsigned int disk_current_index; static unsigned int disk_count; static struct disks_state { char *fname; + char *flabel; int internal_index; // for multidisk eboots } disks[8]; +static void get_disk_label(char *disk_label, const char *disk_path, size_t len) +{ + const char *base = NULL; + + if (!disk_path || (*disk_path == '\0')) + return; + + base = strrchr(disk_path, SLASH); + if (!base) + base = disk_path; + + if (*base == SLASH) + base++; + + strncpy(disk_label, base, len - 1); + disk_label[len - 1] = '\0'; + + char *ext = strrchr(disk_label, '.'); + if (ext) + *ext = '\0'; +} + +static void disk_init(void) +{ + size_t i; + + disk_ejected = false; + disk_current_index = 0; + disk_count = 0; + + for (i = 0; i < sizeof(disks) / sizeof(disks[0]); i++) { + if (disks[i].fname != NULL) { + free(disks[i].fname); + disks[i].fname = NULL; + } + if (disks[i].flabel != NULL) { + free(disks[i].flabel); + disks[i].flabel = NULL; + } + disks[i].internal_index = 0; + } +} + static bool disk_set_eject_state(bool ejected) { // weird PCSX API.. @@ -927,18 +984,29 @@ static unsigned int disk_get_num_images(void) static bool disk_replace_image_index(unsigned index, const struct retro_game_info *info) { - char *old_fname; - bool ret = true; + char *old_fname = NULL; + char *old_flabel = NULL; + bool ret = true; if (index >= sizeof(disks) / sizeof(disks[0])) return false; - old_fname = disks[index].fname; - disks[index].fname = NULL; + old_fname = disks[index].fname; + old_flabel = disks[index].flabel; + + disks[index].fname = NULL; + disks[index].flabel = NULL; disks[index].internal_index = 0; if (info != NULL) { + char disk_label[PATH_MAX]; + disk_label[0] = '\0'; + disks[index].fname = strdup(info->path); + + get_disk_label(disk_label, info->path, PATH_MAX); + disks[index].flabel = strdup(disk_label); + if (index == disk_current_index) ret = disk_set_image_index(index); } @@ -946,6 +1014,9 @@ static bool disk_replace_image_index(unsigned index, if (old_fname != NULL) free(old_fname); + if (old_flabel != NULL) + free(old_flabel); + return ret; } @@ -958,6 +1029,64 @@ static bool disk_add_image_index(void) return true; } +static bool disk_set_initial_image(unsigned index, const char *path) +{ + if (index >= sizeof(disks) / sizeof(disks[0])) + return false; + + if (!path || (*path == '\0')) + return false; + + disk_initial_index = index; + + strncpy(disk_initial_path, path, sizeof(disk_initial_path) - 1); + disk_initial_path[sizeof(disk_initial_path) - 1] = '\0'; + + return true; +} + +static bool disk_get_image_path(unsigned index, char *path, size_t len) +{ + const char *fname = NULL; + + if (len < 1) + return false; + + if (index >= sizeof(disks) / sizeof(disks[0])) + return false; + + fname = disks[index].fname; + + if (!fname || (*fname == '\0')) + return false; + + strncpy(path, fname, len - 1); + path[len - 1] = '\0'; + + return true; +} + +static bool disk_get_image_label(unsigned index, char *label, size_t len) +{ + const char *flabel = NULL; + + if (len < 1) + return false; + + if (index >= sizeof(disks) / sizeof(disks[0])) + return false; + + flabel = disks[index].flabel; + + if (!flabel || (*flabel == '\0')) + return false; + + strncpy(label, flabel, len - 1); + label[len - 1] = '\0'; + + return true; +} + static struct retro_disk_control_callback disk_control = { .set_eject_state = disk_set_eject_state, .get_eject_state = disk_get_eject_state, @@ -968,16 +1097,18 @@ static struct retro_disk_control_callback disk_control = { .add_image_index = disk_add_image_index, }; -// just in case, maybe a win-rt port in the future? -#ifdef _WIN32 -#define SLASH '\\' -#else -#define SLASH '/' -#endif - -#ifndef PATH_MAX -#define PATH_MAX 4096 -#endif +static struct retro_disk_control_ext_callback disk_control_ext = { + .set_eject_state = disk_set_eject_state, + .get_eject_state = disk_get_eject_state, + .get_image_index = disk_get_image_index, + .set_image_index = disk_set_image_index, + .get_num_images = disk_get_num_images, + .replace_image_index = disk_replace_image_index, + .add_image_index = disk_add_image_index, + .set_initial_image = disk_set_initial_image, + .get_image_path = disk_get_image_path, + .get_image_label = disk_get_image_label, +}; static char base_dir[1024]; @@ -1001,8 +1132,16 @@ static bool read_m3u(const char *file) if (line[0] != '\0') { + char disk_label[PATH_MAX]; + disk_label[0] = '\0'; + snprintf(name, sizeof(name), "%s%c%s", base_dir, SLASH, line); - disks[disk_count++].fname = strdup(name); + disks[disk_count].fname = strdup(name); + + get_disk_label(disk_label, name, PATH_MAX); + disks[disk_count].flabel = strdup(disk_label); + + disk_count++; } } @@ -1073,6 +1212,7 @@ static void set_retro_memmap(void) bool retro_load_game(const struct retro_game_info *info) { size_t i; + unsigned int cd_index = 0; bool is_m3u = (strcasestr(info->path, ".m3u") != NULL); struct retro_input_descriptor desc[] = { @@ -1269,15 +1409,8 @@ bool retro_load_game(const struct retro_game_info *info) plugins_opened = 0; } - for (i = 0; i < sizeof(disks) / sizeof(disks[0]); i++) { - if (disks[i].fname != NULL) { - free(disks[i].fname); - disks[i].fname = NULL; - } - disks[i].internal_index = 0; - } + disk_init(); - disk_current_index = 0; extract_directory(base_dir, info->path, sizeof(base_dir)); if (is_m3u) { @@ -1286,11 +1419,30 @@ bool retro_load_game(const struct retro_game_info *info) return false; } } else { + char disk_label[PATH_MAX]; + disk_label[0] = '\0'; + disk_count = 1; disks[0].fname = strdup(info->path); + + get_disk_label(disk_label, info->path, PATH_MAX); + disks[0].flabel = strdup(disk_label); + } + + /* If this is an M3U file, attempt to set the + * initial disk image */ + if (is_m3u && + (disk_initial_index > 0) && + (disk_initial_index < disk_count)) { + const char *fname = disks[disk_initial_index].fname; + + if (fname && (*fname != '\0')) + if (strcmp(disk_initial_path, fname) == 0) + cd_index = disk_initial_index; } - set_cd_image(disks[0].fname); + set_cd_image(disks[cd_index].fname); + disk_current_index = cd_index; /* have to reload after set_cd_image for correct cdr plugin */ if (LoadPlugins() == -1) { @@ -1306,6 +1458,69 @@ bool retro_load_game(const struct retro_game_info *info) return false; } + /* Handle multi-disk images (i.e. PBP) + * > Cannot do this until after OpenPlugins() is + * called (since this sets the value of + * cdrIsoMultidiskCount) */ + if (!is_m3u && (cdrIsoMultidiskCount > 1)) { + disk_count = cdrIsoMultidiskCount < 8 ? cdrIsoMultidiskCount : 8; + + /* Small annoyance: We need to change the label + * of disk 0, so have to clear existing entries */ + if (disks[0].fname != NULL) + free(disks[0].fname); + disks[0].fname = NULL; + + if (disks[0].flabel != NULL) + free(disks[0].flabel); + disks[0].flabel = NULL; + + for (i = 0; i < sizeof(disks) / sizeof(disks[0]) && i < cdrIsoMultidiskCount; i++) { + char disk_name[PATH_MAX]; + char disk_label[PATH_MAX]; + disk_name[0] = '\0'; + disk_label[0] = '\0'; + + disks[i].fname = strdup(info->path); + + get_disk_label(disk_name, info->path, PATH_MAX); + snprintf(disk_label, sizeof(disk_label), "%s #%u", disk_name, (unsigned)i + 1); + disks[i].flabel = strdup(disk_label); + + disks[i].internal_index = i; + } + + /* This is not an M3U file, so initial disk + * image has not yet been set - attempt to + * do so now */ + if ((disk_initial_index > 0) && + (disk_initial_index < disk_count)) { + const char *fname = disks[disk_initial_index].fname; + + if (fname && (*fname != '\0')) + if (strcmp(disk_initial_path, fname) == 0) + cd_index = disk_initial_index; + } + + if (cd_index > 0) { + CdromId[0] = '\0'; + CdromLabel[0] = '\0'; + + cdrIsoMultidiskSelect = disks[cd_index].internal_index; + disk_current_index = cd_index; + set_cd_image(disks[cd_index].fname); + + if (ReloadCdromPlugin() < 0) { + log_cb(RETRO_LOG_INFO, "failed to reload cdr plugins\n"); + return false; + } + if (CDR_open() < 0) { + log_cb(RETRO_LOG_INFO, "failed to open cdr plugin\n"); + return false; + } + } + } + plugin_call_rearmed_cbs(); dfinput_activate(); @@ -1322,15 +1537,6 @@ bool retro_load_game(const struct retro_game_info *info) } emu_on_new_cd(0); - // multidisk images - if (!is_m3u) { - disk_count = cdrIsoMultidiskCount < 8 ? cdrIsoMultidiskCount : 8; - for (i = 1; i < sizeof(disks) / sizeof(disks[0]) && i < cdrIsoMultidiskCount; i++) { - disks[i].fname = strdup(info->path); - disks[i].internal_index = i; - } - } - set_retro_memmap(); return true; @@ -2411,6 +2617,7 @@ static void loadPSXBios(void) void retro_init(void) { + unsigned dci_version = 0; struct retro_rumble_interface rumble; int ret; @@ -2456,7 +2663,13 @@ void retro_init(void) loadPSXBios(); environ_cb(RETRO_ENVIRONMENT_GET_CAN_DUPE, &vout_can_dupe); - environ_cb(RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE, &disk_control); + + disk_initial_index = 0; + disk_initial_path[0] = '\0'; + if (environ_cb(RETRO_ENVIRONMENT_GET_DISK_CONTROL_INTERFACE_VERSION, &dci_version) && (dci_version >= 1)) + environ_cb(RETRO_ENVIRONMENT_SET_DISK_CONTROL_EXT_INTERFACE, &disk_control_ext); + else + environ_cb(RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE, &disk_control); rumble_cb = NULL; if (environ_cb(RETRO_ENVIRONMENT_GET_RUMBLE_INTERFACE, &rumble)) @@ -2501,6 +2714,10 @@ void retro_deinit(void) deinit_vita_mmap(); #endif libretro_supports_bitmasks = false; + + /* Have to reset disks struct, otherwise + * fnames/flabels will leak memory */ + disk_init(); } #ifdef VITA |