X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git;a=blobdiff_plain;f=frontend%2Flibretro.c;h=e22ef5b3af44089f5fcccb0129f5e8695519fead;hp=e7153ac6693407f1f4ccc3ca5d70b717d9fb6ef6;hb=23ea11bd19868d36b8c06134184bf45c9308d26e;hpb=6e921e1d669037004dab55cbe5e704a70d04c718 diff --git a/frontend/libretro.c b/frontend/libretro.c index e7153ac6..e22ef5b3 100644 --- a/frontend/libretro.c +++ b/frontend/libretro.c @@ -13,9 +13,11 @@ #include "../libpcsxcore/psxcounters.h" #include "../libpcsxcore/psxmem_map.h" #include "../libpcsxcore/new_dynarec/new_dynarec.h" +#include "../libpcsxcore/cdrom.h" +#include "../libpcsxcore/cdriso.h" #include "../libpcsxcore/cheat.h" #include "../plugins/dfsound/out.h" -#include "../plugins/gpulib/cspace.h" +#include "cspace.h" #include "main.h" #include "plugin.h" #include "plugin_lib.h" @@ -35,6 +37,7 @@ static bool vout_can_dupe; static int samples_sent, samples_to_send; static int plugins_opened; +static int is_pal_mode; /* memory card data */ extern char Mcd1Data[MCD_SIZE]; @@ -182,6 +185,7 @@ void pl_frame_limit(void) void pl_timing_prepare(int is_pal) { + is_pal_mode = is_pal; } void plat_trigger_vibrate(int is_strong) @@ -254,7 +258,7 @@ void retro_get_system_info(struct retro_system_info *info) void retro_get_system_av_info(struct retro_system_av_info *info) { memset(info, 0, sizeof(*info)); - info->timing.fps = 60; + info->timing.fps = is_pal_mode ? 50 : 60; info->timing.sample_rate = 44100; info->geometry.base_width = 320; info->geometry.base_height = 240; @@ -361,6 +365,7 @@ bool retro_unserialize(const void *data, size_t size) return ret == 0 ? true : false; } +/* cheats */ void retro_cheat_reset(void) { ClearAllCheats(); @@ -386,8 +391,132 @@ void retro_cheat_set(unsigned index, bool enabled, const char *code) Cheats[index].Enabled = enabled; } +/* multidisk support */ +static bool disk_ejected; +static unsigned int disk_current_index; +static struct disks_state { + char *fname; + int internal_index; // for multidisk eboots +} disks[8]; + +static bool disk_set_eject_state(bool ejected) +{ + // weird PCSX API.. + SetCdOpenCaseTime(ejected ? -1 : (time(NULL) + 2)); + LidInterrupt(); + + disk_ejected = ejected; + return true; +} + +static bool disk_get_eject_state(void) +{ + /* can't be controlled by emulated software */ + return disk_ejected; +} + +static unsigned int disk_get_image_index(void) +{ + return disk_current_index; +} + +static bool disk_set_image_index(unsigned int index) +{ + if (index >= sizeof(disks) / sizeof(disks[0])) + return false; + + CdromId[0] = '\0'; + CdromLabel[0] = '\0'; + + if (disks[index].fname == NULL) { + SysPrintf("missing disk #%u\n", index); + CDR_shutdown(); + + // RetroArch specifies "no disk" with index == count, + // so don't fail here.. + disk_current_index = index; + return true; + } + + SysPrintf("switching to disk %u: \"%s\" #%d\n", index, + disks[index].fname, disks[index].internal_index); + + cdrIsoMultidiskSelect = disks[index].internal_index; + set_cd_image(disks[index].fname); + if (ReloadCdromPlugin() < 0) { + SysPrintf("failed to load cdr plugin\n"); + return false; + } + if (CDR_open() < 0) { + SysPrintf("failed to open cdr plugin\n"); + return false; + } + + if (!disk_ejected) { + SetCdOpenCaseTime(time(NULL) + 2); + LidInterrupt(); + } + + disk_current_index = index; + return true; +} + +static unsigned int disk_get_num_images(void) +{ + unsigned int count = 0; + size_t i; + + for (i = 0; i < sizeof(disks) / sizeof(disks[0]); i++) + if (disks[i].fname != NULL) + count++; + + return count; +} + +static bool disk_replace_image_index(unsigned index, + const struct retro_game_info *info) +{ + char *old_fname; + bool ret = true; + + if (index >= sizeof(disks) / sizeof(disks[0])) + return false; + + old_fname = disks[index].fname; + disks[index].fname = NULL; + disks[index].internal_index = 0; + + if (info != NULL) { + disks[index].fname = strdup(info->path); + if (index == disk_current_index) + ret = disk_set_image_index(index); + } + + if (old_fname != NULL) + free(old_fname); + + return ret; +} + +static bool disk_add_image_index(void) +{ + // TODO?? + return true; +} + +static struct retro_disk_control_callback disk_control = { + .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, +}; + bool retro_load_game(const struct retro_game_info *info) { + size_t i; #ifdef FRONTEND_SUPPORTS_RGB565 enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_RGB565; if (environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt)) { @@ -395,12 +524,28 @@ bool retro_load_game(const struct retro_game_info *info) } #endif + if (info == NULL || info->path == NULL) { + SysPrintf("info->path required\n"); + return false; + } + if (plugins_opened) { ClosePlugins(); plugins_opened = 0; } - set_cd_image(info->path); + 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_current_index = 0; + disks[0].fname = strdup(info->path); + + set_cd_image(disks[0].fname); /* have to reload after set_cd_image for correct cdr plugin */ if (LoadPlugins() == -1) { @@ -432,6 +577,12 @@ bool retro_load_game(const struct retro_game_info *info) } emu_on_new_cd(0); + // multidisk images + for (i = 1; i < sizeof(disks) / sizeof(disks[0]) && i < cdrIsoMultidiskCount; i++) { + disks[i].fname = strdup(info->path); + disks[i].internal_index = i; + } + return true; } @@ -446,7 +597,7 @@ void retro_unload_game(void) unsigned retro_get_region(void) { - return RETRO_REGION_NTSC; + return is_pal_mode ? RETRO_REGION_PAL : RETRO_REGION_NTSC; } void *retro_get_memory_data(unsigned id) @@ -501,7 +652,7 @@ void retro_run(void) stop = 0; psxCpu->Execute(); - samples_to_send += 44100 / 60; + samples_to_send += is_pal_mode ? 44100 / 50 : 44100 / 60; video_cb((vout_fb_dirty || !vout_can_dupe) ? vout_buf : NULL, vout_width, vout_height, vout_width * 2); @@ -549,6 +700,7 @@ void retro_init(void) environ_cb(RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL, &level); environ_cb(RETRO_ENVIRONMENT_GET_CAN_DUPE, &vout_can_dupe); + environ_cb(RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE, &disk_control); /* Set how much slower PSX CPU runs * 100 (so that 200 is 2 times) * we have to do this because cache misses and some IO penalties