Add manual frame skipping

This commit is contained in:
bmaupin 2019-11-11 14:03:13 -05:00
parent 59c4f7f5c7
commit 3df169d3e8
3 changed files with 74 additions and 3 deletions

View File

@ -47,6 +47,14 @@ static int translation_caches_inited = 0;
#define MAX_PATH (512)
#endif
frameskip_type current_frameskip_type = no_frameskip;
u32 frameskip_value = 4;
u32 random_skip = 0;
u32 skip_next_frame = 0;
u32 frameskip_counter = 0;
static retro_log_printf_t log_cb;
static retro_video_refresh_t video_cb;
static retro_input_poll_t input_poll_cb;
@ -312,6 +320,9 @@ void retro_set_environment(retro_environment_t cb)
#ifdef HAVE_DYNAREC
{ "gpsp_drc", "Dynamic recompiler (restart); enabled|disabled" },
#endif
{ "gpsp_frameskip_type", "Frameskip type; off|manual" },
{ "gpsp_frameskip_value", "Frameskip value; 1|2|3|4|5|6|7|8|9|0" },
{ "gpsp_frameskip_variation", "Frameskip variation; uniform|random" },
{ NULL, NULL },
};
@ -422,9 +433,9 @@ static void extract_directory(char* buf, const char* path, size_t size)
static void check_variables(int started_from_load)
{
#ifdef HAVE_DYNAREC
struct retro_variable var;
#ifdef HAVE_DYNAREC
var.key = "gpsp_drc";
var.value = NULL;
@ -441,6 +452,31 @@ static void check_variables(int started_from_load)
else
dynarec_enable = 1;
#endif
var.key = "gpsp_frameskip_value";
var.value = 0;
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
frameskip_value = strtol(var.value, NULL, 10);
var.key = "gpsp_frameskip_type";
var.value = NULL;
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
{
if (!strcmp(var.value, "off"))
current_frameskip_type = no_frameskip;
else if (!strcmp(var.value, "manual"))
current_frameskip_type = manual_frameskip;
}
var.key = "gpsp_frameskip_variation";
var.value = NULL;
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
{
if (!strcmp(var.value, "uniform"))
random_skip = 0;
else if (!strcmp(var.value, "random"))
random_skip = 1;
}
}
static void set_input_descriptors()
@ -621,11 +657,33 @@ void retro_run(void)
input_poll_cb();
s32 used_frameskip = frameskip_value;
skip_next_frame = 0;
if(current_frameskip_type == manual_frameskip)
{
frameskip_counter = (frameskip_counter + 1) %
(used_frameskip + 1);
if(random_skip)
{
if(frameskip_counter != (rand() % (used_frameskip + 1)))
skip_next_frame = 1;
}
else
{
if(frameskip_counter)
skip_next_frame = 1;
}
}
switch_to_cpu_thread();
render_audio();
video_run();
/* Skip the video callback when skipping frames so the frontend can properly report FPS */
if (!skip_next_frame)
video_run();
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated)
check_variables(0);

12
main.h
View File

@ -54,9 +54,20 @@ typedef struct
timer_status_type status;
} timer_type;
typedef enum
{
auto_frameskip,
manual_frameskip,
no_frameskip
} frameskip_type;
extern u32 cpu_ticks;
extern u32 execute_cycles;
extern frameskip_type current_frameskip_type;
extern u32 frameskip_value;
extern u32 random_skip;
extern u32 global_cycles_per_instruction;
extern u32 skip_next_frame;
extern u32 cycle_memory_access;
extern u32 cycle_pc_relative_access;
@ -91,7 +102,6 @@ u32 file_length(const char *dummy, FILE *fp);
extern u32 real_frame_count;
extern u32 virtual_frame_count;
extern u32 max_frameskip;
extern u32 num_skipped_frames;
extern int dynarec_enable;

View File

@ -4437,6 +4437,9 @@ void update_scanline(void)
order_layers((dispcnt >> 8) & active_layers[video_mode]);
if(skip_next_frame)
return;
// If the screen is in in forced blank draw pure white.
if(dispcnt & 0x80)
{