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;
#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;
}
#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)
{
emu_on_new_cd(0);
set_retro_memmap();
+ retro_set_audio_buff_status_cb();
return true;
}
#ifdef GPU_PEOPS
int gpu_peops_fix = 0;
#endif
+ frameskip_type_t prev_frameskip_type;
var.value = NULL;
- var.key = "pcsx_rearmed_frameskip";
+ 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)
- pl_rearmed_cbs.frameskip = atoi(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_threshold";
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && 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";
display_internal_fps = true;
}
-#if defined(LIGHTREC) || defined(NEW_DYNAREC)
+#ifndef DRC_DISABLE
var.value = NULL;
var.key = "pcsx_rearmed_drc";
psxCpu->Reset(); // not really a reset..
}
}
-#endif /* LIGHTREC || NEW_DYNAREC */
+#endif /* !DRC_DISABLE */
+ psxCpu->ApplyConfig();
var.value = NULL;
var.key = "pcsx_rearmed_spu_reverb";
else if (strcmp(var.value, "enabled") == 0)
Config.RCntFix = 1;
}
+
+ var.value = NULL;
+ var.key = "pcsx_rearmed_icache_emulation";
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+ {
+ if (strcmp(var.value, "disabled") == 0)
+ Config.icache_emulation = 0;
+ else if (strcmp(var.value, "enabled") == 0)
+ Config.icache_emulation = 1;
+ }
var.value = NULL;
var.key = "pcsx_rearmed_inuyasha_fix";
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)
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";
GPU_open(&gpuDisp, "PCSX", NULL);
}
+ /* Reinitialise frameskipping, if required */
+ if (((frameskip_type != prev_frameskip_type)))
+ retro_set_audio_buff_status_cb();
+
/* dfinput_activate(); */
}
else
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();
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;
unsigned useHLE = 0;
const char *bios[] = {
- "PS1_ROM", "ps1_rom",
"PSXONPSP660", "psxonpsp660",
"SCPH101", "scph101",
"SCPH5501", "scph5501",
/* 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