X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=frontend%2Flibretro.c;h=0b306a2f295bc91ce5b65c775d6dfba46bb108c7;hb=10a3edb5729a92eaeadfe77866f7f0ee700a9f1f;hp=8442a1502d4afc0d73edc72da773473eee5d3d0b;hpb=7a8117168d6b9ad083757e013049c0e45734f3fb;p=pcsx_rearmed.git diff --git a/frontend/libretro.c b/frontend/libretro.c index 8442a150..0b306a2f 100644 --- a/frontend/libretro.c +++ b/frontend/libretro.c @@ -96,6 +96,26 @@ static int show_advanced_gpu_unai_settings = -1; static int show_other_input_settings = -1; static float mouse_sensitivity = 1.0f; +typedef enum +{ + FRAMESKIP_NONE = 0, + FRAMESKIP_AUTO, + FRAMESKIP_AUTO_THRESHOLD, + FRAMESKIP_FIXED_INTERVAL +} frameskip_type_t; + +static unsigned frameskip_type = FRAMESKIP_NONE; +static unsigned frameskip_threshold = 0; +static unsigned frameskip_interval = 0; +static unsigned frameskip_counter = 0; + +static int retro_audio_buff_active = false; +static unsigned retro_audio_buff_occupancy = 0; +static int retro_audio_buff_underrun = false; + +static unsigned retro_audio_latency = 0; +static int update_audio_latency = false; + static unsigned previous_width = 0; static unsigned previous_height = 0; @@ -654,7 +674,7 @@ void retro_get_system_info(struct retro_system_info *info) #endif memset(info, 0, sizeof(*info)); info->library_name = "PCSX-ReARMed"; - info->library_version = "r22" GIT_VERSION; + info->library_version = "r23l" GIT_VERSION; info->valid_extensions = "bin|cue|img|mdf|pbp|toc|cbn|m3u|chd"; info->need_fullpath = true; } @@ -1195,6 +1215,61 @@ static void set_retro_memmap(void) #endif } +static void retro_audio_buff_status_cb( + bool active, unsigned occupancy, bool underrun_likely) +{ + retro_audio_buff_active = active; + retro_audio_buff_occupancy = occupancy; + retro_audio_buff_underrun = underrun_likely; +} + +static void retro_set_audio_buff_status_cb(void) +{ + if (frameskip_type == FRAMESKIP_NONE) + { + environ_cb(RETRO_ENVIRONMENT_SET_AUDIO_BUFFER_STATUS_CALLBACK, NULL); + retro_audio_latency = 0; + } + else + { + bool calculate_audio_latency = true; + + if (frameskip_type == FRAMESKIP_FIXED_INTERVAL) + environ_cb(RETRO_ENVIRONMENT_SET_AUDIO_BUFFER_STATUS_CALLBACK, NULL); + else + { + struct retro_audio_buffer_status_callback buf_status_cb; + buf_status_cb.callback = retro_audio_buff_status_cb; + if (!environ_cb(RETRO_ENVIRONMENT_SET_AUDIO_BUFFER_STATUS_CALLBACK, + &buf_status_cb)) + { + retro_audio_buff_active = false; + retro_audio_buff_occupancy = 0; + retro_audio_buff_underrun = false; + retro_audio_latency = 0; + calculate_audio_latency = false; + } + } + + if (calculate_audio_latency) + { + /* Frameskip is enabled - increase frontend + * audio latency to minimise potential + * buffer underruns */ + uint32_t frame_time_usec = 1000000.0 / (is_pal_mode ? 50.0 : 60.0); + + /* Set latency to 6x current frame time... */ + retro_audio_latency = (unsigned)(6 * frame_time_usec / 1000); + + /* ...then round up to nearest multiple of 32 */ + retro_audio_latency = (retro_audio_latency + 0x1F) & ~0x1F; + } + } + + update_audio_latency = true; + frameskip_counter = 0; +} + static void update_variables(bool in_flight); bool retro_load_game(const struct retro_game_info *info) { @@ -1406,6 +1481,7 @@ bool retro_load_game(const struct retro_game_info *info) emu_on_new_cd(0); set_retro_memmap(); + retro_set_audio_buff_status_cb(); return true; } @@ -1476,11 +1552,41 @@ static void update_variables(bool in_flight) #ifdef GPU_PEOPS int gpu_peops_fix = 0; #endif + frameskip_type_t prev_frameskip_type; + + var.value = NULL; + var.key = "pcsx_rearmed_frameskip_type"; + + prev_frameskip_type = frameskip_type; + frameskip_type = FRAMESKIP_NONE; + pl_rearmed_cbs.frameskip = 0; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + if (strcmp(var.value, "auto") == 0) + frameskip_type = FRAMESKIP_AUTO; + if (strcmp(var.value, "auto_threshold") == 0) + frameskip_type = FRAMESKIP_AUTO_THRESHOLD; + if (strcmp(var.value, "fixed_interval") == 0) + frameskip_type = FRAMESKIP_FIXED_INTERVAL; + } + if (frameskip_type != 0) + pl_rearmed_cbs.frameskip = -1; + var.value = NULL; - var.key = "pcsx_rearmed_frameskip"; + var.key = "pcsx_rearmed_frameskip_threshold"; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) - pl_rearmed_cbs.frameskip = atoi(var.value); + { + frameskip_threshold = strtol(var.value, NULL, 10); + } + + var.value = NULL; + var.key = "pcsx_rearmed_frameskip_interval"; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + frameskip_interval = strtol(var.value, NULL, 10); + } var.value = NULL; var.key = "pcsx_rearmed_region"; @@ -1628,7 +1734,7 @@ static void update_variables(bool in_flight) display_internal_fps = true; } -#if defined(LIGHTREC) || defined(NEW_DYNAREC) +#ifndef DRC_DISABLE var.value = NULL; var.key = "pcsx_rearmed_drc"; @@ -1661,7 +1767,8 @@ static void update_variables(bool in_flight) psxCpu->Reset(); // not really a reset.. } } -#endif /* LIGHTREC || NEW_DYNAREC */ +#endif /* !DRC_DISABLE */ + psxCpu->ApplyConfig(); var.value = NULL; var.key = "pcsx_rearmed_spu_reverb"; @@ -1700,7 +1807,6 @@ static void update_variables(bool in_flight) Config.RCntFix = 1; } -#ifdef ICACHE_EMULATION var.value = NULL; var.key = "pcsx_rearmed_icache_emulation"; @@ -1711,7 +1817,6 @@ static void update_variables(bool in_flight) else if (strcmp(var.value, "enabled") == 0) Config.icache_emulation = 1; } -#endif var.value = NULL; var.key = "pcsx_rearmed_inuyasha_fix"; @@ -2054,7 +2159,7 @@ static void update_variables(bool in_flight) GunconAdjustRatioY = atof(var.value); } -#ifdef NEW_DYNAREC +#if !defined(DRC_DISABLE) && !defined(LIGHTREC) var.value = NULL; var.key = "pcsx_rearmed_nosmccheck"; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) @@ -2093,7 +2198,27 @@ static void update_variables(bool in_flight) int psxclock = atoi(var.value); cycle_multiplier = 10000 / psxclock; } -#endif /* NEW_DYNAREC */ + + var.value = NULL; + var.key = "pcsx_rearmed_nocompathacks"; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + if (strcmp(var.value, "enabled") == 0) + new_dynarec_hacks |= NDHACK_NO_COMPAT_HACKS; + else + new_dynarec_hacks &= ~NDHACK_NO_COMPAT_HACKS; + } +#endif /* !DRC_DISABLE && !LIGHTREC */ + + var.value = NULL; + var.key = "pcsx_rearmed_nostalls"; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + if (strcmp(var.value, "enabled") == 0) + Config.DisableStalls = 1; + else + Config.DisableStalls = 0; + } var.value = NULL; var.key = "pcsx_rearmed_input_sensitivity"; @@ -2149,6 +2274,10 @@ static void update_variables(bool in_flight) GPU_open(&gpuDisp, "PCSX", NULL); } + /* Reinitialise frameskipping, if required */ + if (((frameskip_type != prev_frameskip_type))) + retro_set_audio_buff_status_cb(); + /* dfinput_activate(); */ } else @@ -2521,6 +2650,46 @@ void retro_run(void) print_internal_fps(); + /* Check whether current frame should + * be skipped */ + pl_rearmed_cbs.fskip_force = 0; + pl_rearmed_cbs.fskip_dirty = 0; + + if (frameskip_type != FRAMESKIP_NONE) + { + bool skip_frame = false; + + switch (frameskip_type) + { + case FRAMESKIP_AUTO: + skip_frame = retro_audio_buff_active && retro_audio_buff_underrun; + break; + case FRAMESKIP_AUTO_THRESHOLD: + skip_frame = retro_audio_buff_active && (retro_audio_buff_occupancy < frameskip_threshold); + break; + case FRAMESKIP_FIXED_INTERVAL: + skip_frame = true; + break; + default: + break; + } + + if (skip_frame && frameskip_counter < frameskip_interval) + pl_rearmed_cbs.fskip_force = 1; + } + + /* If frameskip/timing settings have changed, + * update frontend audio latency + * > Can do this before or after the frameskip + * check, but doing it after means we at least + * retain the current frame's audio output */ + if (update_audio_latency) + { + environ_cb(RETRO_ENVIRONMENT_SET_MINIMUM_AUDIO_LATENCY, + &retro_audio_latency); + update_audio_latency = false; + } + input_poll_cb(); update_input(); @@ -2532,6 +2701,13 @@ void retro_run(void) stop = 0; psxCpu->Execute(); + if (pl_rearmed_cbs.fskip_dirty == 1) { + if (frameskip_counter < frameskip_interval) + frameskip_counter++; + else if (frameskip_counter >= frameskip_interval || !pl_rearmed_cbs.fskip_force) + frameskip_counter = 0; + } + video_cb((vout_fb_dirty || !vout_can_dupe || !duping_enable) ? vout_buf_ptr : NULL, vout_width, vout_height, vout_width * 2); vout_fb_dirty = 0; @@ -2651,7 +2827,6 @@ static void loadPSXBios(void) unsigned useHLE = 0; const char *bios[] = { - "PS1_ROM", "ps1_rom", "PSXONPSP660", "psxonpsp660", "SCPH101", "scph101", "SCPH5501", "scph5501", @@ -2845,6 +3020,15 @@ void retro_deinit(void) /* Have to reset disks struct, otherwise * fnames/flabels will leak memory */ disk_init(); + frameskip_type = FRAMESKIP_NONE; + frameskip_threshold = 0; + frameskip_interval = 0; + frameskip_counter = 0; + retro_audio_buff_active = false; + retro_audio_buff_occupancy = 0; + retro_audio_buff_underrun = false; + retro_audio_latency = 0; + update_audio_latency = false; } #ifdef VITA