X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git;a=blobdiff_plain;f=frontend%2Flibretro.c;h=8c5075ff8673bb18b5aedb8e0dd0688215b4778d;hp=9e73fc7a8b1bc798187037b89dff5de8ca739ba9;hb=e3f8313f11b8b52e6e21b4ad980327e1edbfce7e;hpb=b40a83db932d2c2a250e68a06e88a334509968ec diff --git a/frontend/libretro.c b/frontend/libretro.c index 9e73fc7a..8c5075ff 100644 --- a/frontend/libretro.c +++ b/frontend/libretro.c @@ -5,9 +5,11 @@ * See the COPYING file in the top-level directory. */ +#define _GNU_SOURCE 1 // strcasestr #include #include #include +#include #include "../libpcsxcore/misc.h" #include "../libpcsxcore/psxcounters.h" @@ -17,6 +19,7 @@ #include "../libpcsxcore/cdriso.h" #include "../libpcsxcore/cheat.h" #include "../plugins/dfsound/out.h" +#include "../plugins/dfinput/externals.h" #include "cspace.h" #include "main.h" #include "plugin.h" @@ -34,6 +37,7 @@ static void *vout_buf; static int vout_width, vout_height; static int vout_doffs_old, vout_fb_dirty; static bool vout_can_dupe; +static bool duping_enable; static int samples_sent, samples_to_send; static int plugins_opened; @@ -49,6 +53,10 @@ int in_a1[2] = { 127, 127 }, in_a2[2] = { 127, 127 }; int in_keystate; int in_enable_vibration; +/* PSX max resolution is 640x512, but with enhancement it's 1024x512 */ +#define VOUT_MAX_WIDTH 1024 +#define VOUT_MAX_HEIGHT 512 + static void init_memcard(char *mcd_data) { unsigned off = 0; @@ -230,7 +238,29 @@ void out_register_libretro(struct out_driver *drv) } /* libretro */ -void retro_set_environment(retro_environment_t cb) { environ_cb = cb; } +void retro_set_environment(retro_environment_t cb) +{ + static const struct retro_variable vars[] = { + { "frameskip", "Frameskip; 0|1|2|3" }, + { "region", "Region; Auto|NTSC|PAL" }, + { "pad1type", "Pad 1 Type; standard|analog" }, +#ifndef DRC_DISABLE + { "rearmed_drc", "Dynamic recompiler; enabled|disabled" }, +#endif +#ifdef __ARM_NEON__ + { "neon_interlace_enable", "Enable interlacing mode(s); disabled|enabled" }, + { "neon_enhancement_enable", "Enhanced resolution (slow); disabled|enabled" }, + { "neon_enhancement_no_main", "Enhanced resolution speed hack; disabled|enabled" }, +#endif + { "pcsx_rearmed_duping_enable", "Frame duping; on|off" }, + { NULL, NULL }, + }; + + environ_cb = cb; + + cb(RETRO_ENVIRONMENT_SET_VARIABLES, (void*)vars); +} + void retro_set_video_refresh(retro_video_refresh_t cb) { video_cb = cb; } void retro_set_audio_sample(retro_audio_sample_t cb) { (void)cb; } void retro_set_audio_sample_batch(retro_audio_sample_batch_t cb) { audio_batch_cb = cb; } @@ -262,8 +292,8 @@ void retro_get_system_av_info(struct retro_system_av_info *info) info->timing.sample_rate = 44100; info->geometry.base_width = 320; info->geometry.base_height = 240; - info->geometry.max_width = 640; - info->geometry.max_height = 512; + info->geometry.max_width = VOUT_MAX_WIDTH; + info->geometry.max_height = VOUT_MAX_HEIGHT; info->geometry.aspect_ratio = 4.0 / 3.0; } @@ -394,6 +424,7 @@ void retro_cheat_set(unsigned index, bool enabled, const char *code) /* multidisk support */ static bool disk_ejected; static unsigned int disk_current_index; +static unsigned int disk_count; static struct disks_state { char *fname; int internal_index; // for multidisk eboots @@ -463,14 +494,7 @@ static bool disk_set_image_index(unsigned int index) 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; + return disk_count; } static bool disk_replace_image_index(unsigned index, @@ -500,7 +524,10 @@ static bool disk_replace_image_index(unsigned index, static bool disk_add_image_index(void) { - // TODO?? + if (disk_count >= 8) + return false; + + disk_count++; return true; } @@ -527,12 +554,11 @@ static bool read_m3u(const char *file) { char line[PATH_MAX]; char name[PATH_MAX]; - size_t i = 0; FILE *f = fopen(file, "r"); if (!f) return false; - while (fgets(line, sizeof(line), f) && i < sizeof(disks) / sizeof(disks[0])) { + while (fgets(line, sizeof(line), f) && disk_count < sizeof(disks) / sizeof(disks[0])) { if (line[0] == '#') continue; char *carrige_return = strchr(line, '\r'); @@ -545,12 +571,12 @@ static bool read_m3u(const char *file) if (line[0] != '\0') { snprintf(name, sizeof(name), "%s%c%s", base_dir, SLASH, line); - disks[i++].fname = strdup(name); + disks[disk_count++].fname = strdup(name); } } fclose(f); - return (i != 0); + return (disk_count != 0); } static void extract_directory(char *buf, const char *path, size_t size) @@ -572,11 +598,180 @@ static void extract_directory(char *buf, const char *path, size_t size) } } +#ifdef __QNX__ +/* Blackberry QNX doesn't have strcasestr */ + +/* + * Find the first occurrence of find in s, ignore case. + */ +char * +strcasestr(const char *s, const char*find) +{ + char c, sc; + size_t len; + + if ((c = *find++) != 0) { + c = tolower((unsigned char)c); + len = strlen(find); + do { + do { + if ((sc = *s++) == 0) + return (NULL); + } while ((char)tolower((unsigned char)sc) != c); + } while (strncasecmp(s, find, len) != 0); + s--; + } + return ((char *)s); +} +#endif + bool retro_load_game(const struct retro_game_info *info) { size_t i; bool is_m3u = (strcasestr(info->path, ".m3u") != NULL); + struct retro_input_descriptor desc[] = { + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "Cross" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "Circle" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Triangle" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Square" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L1" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "L2" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3, "L3" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R1" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "R2" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "R3" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" }, + + { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" }, + { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" }, + { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" }, + { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" }, + { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "Cross" }, + { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "Circle" }, + { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Triangle" }, + { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Square" }, + { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L1" }, + { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "L2" }, + { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3, "L3" }, + { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R1" }, + { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "R2" }, + { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "R3" }, + { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" }, + { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" }, + + { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" }, + { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" }, + { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" }, + { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" }, + { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "Cross" }, + { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "Circle" }, + { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Triangle" }, + { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Square" }, + { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L1" }, + { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "L2" }, + { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3, "L3" }, + { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R1" }, + { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "R2" }, + { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "R3" }, + { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" }, + { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" }, + + { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" }, + { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" }, + { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" }, + { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" }, + { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "Cross" }, + { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "Circle" }, + { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Triangle" }, + { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Square" }, + { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L1" }, + { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "L2" }, + { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3, "L3" }, + { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R1" }, + { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "R2" }, + { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "R3" }, + { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" }, + { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" }, + + { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" }, + { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" }, + { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" }, + { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" }, + { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "Cross" }, + { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "Circle" }, + { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Triangle" }, + { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Square" }, + { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L1" }, + { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "L2" }, + { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3, "L3" }, + { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R1" }, + { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "R2" }, + { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "R3" }, + { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" }, + { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" }, + + { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" }, + { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" }, + { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" }, + { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" }, + { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "Cross" }, + { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "Circle" }, + { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Triangle" }, + { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Square" }, + { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L1" }, + { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "L2" }, + { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3, "L3" }, + { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R1" }, + { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "R2" }, + { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "R3" }, + { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" }, + { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" }, + + { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" }, + { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" }, + { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" }, + { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" }, + { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "Cross" }, + { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "Circle" }, + { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Triangle" }, + { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Square" }, + { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L1" }, + { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "L2" }, + { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3, "L3" }, + { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R1" }, + { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "R2" }, + { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "R3" }, + { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" }, + { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" }, + + { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" }, + { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" }, + { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" }, + { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" }, + { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "Cross" }, + { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "Circle" }, + { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Triangle" }, + { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Square" }, + { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L1" }, + { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "L2" }, + { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3, "L3" }, + { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R1" }, + { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "R2" }, + { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "R3" }, + { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" }, + { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" }, + + { 0 }, + }; + + environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, desc); + #ifdef FRONTEND_SUPPORTS_RGB565 enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_RGB565; if (environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt)) { @@ -610,9 +805,10 @@ bool retro_load_game(const struct retro_game_info *info) SysPrintf("failed to read m3u file\n"); return false; } - } - else + } else { + disk_count = 1; disks[0].fname = strdup(info->path); + } set_cd_image(disks[0].fname); @@ -631,6 +827,7 @@ bool retro_load_game(const struct retro_game_info *info) } plugin_call_rearmed_cbs(); + dfinput_activate(); Config.PsxAuto = 1; if (CheckCdrom() == -1) { @@ -648,6 +845,7 @@ bool retro_load_game(const struct retro_game_info *info) // 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; @@ -712,11 +910,131 @@ static const unsigned short retro_psx_map[] = { }; #define RETRO_PSX_MAP_LEN (sizeof(retro_psx_map) / sizeof(retro_psx_map[0])) +static void update_variables(bool in_flight) +{ + struct retro_variable var; + + var.value = NULL; + var.key = "frameskip"; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value) + pl_rearmed_cbs.frameskip = atoi(var.value); + + var.value = NULL; + var.key = "region"; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value) + { + Config.PsxAuto = 0; + if (strcmp(var.value, "Automatic") == 0) + Config.PsxAuto = 1; + else if (strcmp(var.value, "NTSC") == 0) + Config.PsxType = 0; + else if (strcmp(var.value, "PAL") == 0) + Config.PsxType = 1; + } + + var.value = NULL; + var.key = "pad1type"; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value) + { + in_type1 = PSE_PAD_TYPE_STANDARD; + if (strcmp(var.value, "analog") == 0) + in_type1 = PSE_PAD_TYPE_ANALOGPAD; + } + +#ifdef __ARM_NEON__ + var.value = "NULL"; + var.key = "neon_interlace_enable"; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value) + { + if (strcmp(var.value, "disabled") == 0) + pl_rearmed_cbs.gpu_neon.allow_interlace = 0; + else if (strcmp(var.value, "enabled") == 0) + pl_rearmed_cbs.gpu_neon.allow_interlace = 1; + } + + var.value = NULL; + var.key = "neon_enhancement_enable"; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value) + { + if (strcmp(var.value, "disabled") == 0) + pl_rearmed_cbs.gpu_neon.enhancement_enable = 0; + else if (strcmp(var.value, "enabled") == 0) + pl_rearmed_cbs.gpu_neon.enhancement_enable = 1; + } + + var.value = NULL; + var.key = "neon_enhancement_no_main"; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value) + { + if (strcmp(var.value, "disabled") == 0) + pl_rearmed_cbs.gpu_neon.enhancement_no_main = 0; + else if (strcmp(var.value, "enabled") == 0) + pl_rearmed_cbs.gpu_neon.enhancement_no_main = 1; + } +#endif + + var.value = "NULL"; + var.key = "pcsx_rearmed_duping_enable"; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value) + { + if (strcmp(var.value, "off") == 0) + duping_enable = false; + else if (strcmp(var.value, "on") == 0) + duping_enable = true; + } + +#ifndef DRC_DISABLE + var.value = NULL; + var.key = "rearmed_drc"; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value) + { + R3000Acpu *prev_cpu = psxCpu; + + if (strcmp(var.value, "disabled") == 0) + Config.Cpu = CPU_INTERPRETER; + else if (strcmp(var.value, "enabled") == 0) + Config.Cpu = CPU_DYNAREC; + + psxCpu = (Config.Cpu == CPU_INTERPRETER) ? &psxInt : &psxRec; + if (psxCpu != prev_cpu) { + prev_cpu->Shutdown(); + psxCpu->Init(); + psxCpu->Reset(); // not really a reset.. + } + } +#endif + + if (in_flight) { + // inform core things about possible config changes + plugin_call_rearmed_cbs(); + + if (GPU_open != NULL && GPU_close != NULL) { + GPU_close(); + GPU_open(&gpuDisp, "PCSX", NULL); + } + + dfinput_activate(); + } +} + void retro_run(void) { int i; input_poll_cb(); + + bool updated = false; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated) + update_variables(true); + in_keystate = 0; for (i = 0; i < RETRO_PSX_MAP_LEN; i++) if (input_state_cb(1, RETRO_DEVICE_JOYPAD, 0, i)) @@ -726,23 +1044,91 @@ void retro_run(void) if (input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, i)) in_keystate |= retro_psx_map[i]; + if (in_type1 == PSE_PAD_TYPE_ANALOGPAD) + { + in_a1[0] = (input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X) / 256) + 128; + in_a1[1] = (input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y) / 256) + 128; + in_a2[0] = (input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X) / 256) + 128; + in_a2[1] = (input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y) / 256) + 128; + } + stop = 0; psxCpu->Execute(); samples_to_send += is_pal_mode ? 44100 / 50 : 44100 / 60; - video_cb((vout_fb_dirty || !vout_can_dupe) ? vout_buf : NULL, + video_cb((vout_fb_dirty || !vout_can_dupe || !duping_enable) ? vout_buf : NULL, vout_width, vout_height, vout_width * 2); vout_fb_dirty = 0; } +static bool try_use_bios(const char *path) +{ + FILE *f; + long size; + const char *name; + + f = fopen(path, "rb"); + if (f == NULL) + return false; + + fseek(f, 0, SEEK_END); + size = ftell(f); + fclose(f); + + if (size != 512 * 1024) + return false; + + name = strrchr(path, SLASH); + if (name++ == NULL) + name = path; + snprintf(Config.Bios, sizeof(Config.Bios), "%s", name); + return true; +} + +#if 1 +#include +#include + +static bool find_any_bios(const char *dirpath, char *path, size_t path_size) +{ + DIR *dir; + struct dirent *ent; + bool ret = false; + + dir = opendir(dirpath); + if (dir == NULL) + return false; + + while ((ent = readdir(dir))) { + if (strncasecmp(ent->d_name, "scph", 4) != 0) + continue; + + snprintf(path, path_size, "%s/%s", dirpath, ent->d_name); + ret = try_use_bios(path); + if (ret) + break; + } + closedir(dir); + return ret; +} +#else +#define find_any_bios(...) false +#endif + +static void check_system_specs(void) +{ + unsigned level = 6; + environ_cb(RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL, &level); +} + void retro_init(void) { const char *bios[] = { "scph1001", "scph5501", "scph7001" }; const char *dir; char path[256]; - FILE *f = NULL; int i, ret, level; + bool found_bios = false; ret = emu_core_preinit(); ret |= emu_core_init(); @@ -751,7 +1137,11 @@ void retro_init(void) exit(1); } - vout_buf = malloc(640 * 512 * 2); +#if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L) + posix_memalign(&vout_buf, 16, VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT * 2); +#else + vout_buf = malloc(VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT * 2); +#endif if (environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &dir) && dir) { @@ -759,19 +1149,27 @@ void retro_init(void) for (i = 0; i < sizeof(bios) / sizeof(bios[0]); i++) { snprintf(path, sizeof(path), "%s/%s.bin", dir, bios[i]); - f = fopen(path, "r"); - if (f != NULL) { - snprintf(Config.Bios, sizeof(Config.Bios), "%s.bin", bios[i]); + found_bios = try_use_bios(path); + if (found_bios) break; - } } + + if (!found_bios) + found_bios = find_any_bios(dir, path, sizeof(path)); } - if (f != NULL) { + if (found_bios) { SysPrintf("found BIOS file: %s\n", Config.Bios); - fclose(f); } else + { SysPrintf("no BIOS files found.\n"); + struct retro_message msg = + { + "no BIOS found, expect bugs!", + 180 + }; + environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, (void*)&msg); + } level = 1; environ_cb(RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL, &level); @@ -797,6 +1195,9 @@ void retro_init(void) SaveFuncs.write = save_write; SaveFuncs.seek = save_seek; SaveFuncs.close = save_close; + + update_variables(false); + check_system_specs(); } void retro_deinit(void)