diff options
Diffstat (limited to 'patches/fbalpha2012/1001-add-auto-frameskip.patch')
-rw-r--r-- | patches/fbalpha2012/1001-add-auto-frameskip.patch | 297 |
1 files changed, 297 insertions, 0 deletions
diff --git a/patches/fbalpha2012/1001-add-auto-frameskip.patch b/patches/fbalpha2012/1001-add-auto-frameskip.patch new file mode 100644 index 0000000..e497b81 --- /dev/null +++ b/patches/fbalpha2012/1001-add-auto-frameskip.patch @@ -0,0 +1,297 @@ +diff --git a/svn-current/trunk/src/burner/libretro/libretro.cpp b/svn-current/trunk/src/burner/libretro/libretro.cpp +index 639aab9..1b23498 100644 +--- a/svn-current/trunk/src/burner/libretro/libretro.cpp ++++ b/svn-current/trunk/src/burner/libretro/libretro.cpp +@@ -153,6 +153,72 @@ void retro_set_environment(retro_environment_t cb) + environ_cb = cb; + } + ++/* Frameskipping Support */ ++ ++unsigned frameskip_type = 0; ++unsigned frameskip_threshold = 0; ++uint16_t frameskip_counter = 0; ++unsigned frameskip_interval = 0; ++ ++static bool retro_audio_buff_active = false; ++static unsigned retro_audio_buff_occupancy = 0; ++static bool retro_audio_buff_underrun = false; ++ ++static unsigned audio_latency = 0; ++static bool update_audio_latency = false; ++ ++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; ++} ++ ++void init_frameskip(void) ++{ ++ if (frameskip_type > 0) ++ { ++ 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)) ++ { ++ if (log_cb) ++ log_cb(RETRO_LOG_WARN, "Frameskip disabled - frontend does not support audio buffer status monitoring.\n"); ++ ++ retro_audio_buff_active = false; ++ retro_audio_buff_occupancy = 0; ++ retro_audio_buff_underrun = false; ++ audio_latency = 0; ++ } ++ else ++ { ++ /* Frameskip is enabled - increase frontend ++ * audio latency to minimise potential ++ * buffer underruns */ ++#ifdef FBACORES_CPS ++ float frame_time_msec = 1000.0f / 59.629403f; ++#else ++ float frame_time_msec = 1000.0f / ((float)nBurnFPS / 100.0f); ++#endif ++ /* Set latency to 6x current frame time... */ ++ audio_latency = (unsigned)((6.0f * frame_time_msec) + 0.5f); ++ ++ /* ...then round up to nearest multiple of 32 */ ++ audio_latency = (audio_latency + 0x1F) & ~0x1F; ++ } ++ } ++ else ++ { ++ environ_cb(RETRO_ENVIRONMENT_SET_AUDIO_BUFFER_STATUS_CALLBACK, NULL); ++ audio_latency = 0; ++ } ++ ++ update_audio_latency = true; ++} ++ + char g_rom_dir[MAX_PATH]; + char g_save_dir[1024]; + char g_system_dir[1024]; +@@ -789,6 +855,14 @@ void retro_init() + log_cb = log_dummy; + + BurnLibInit(); ++ frameskip_type = 0; ++ frameskip_threshold = 0; ++ frameskip_counter = 0; ++ retro_audio_buff_active = false; ++ retro_audio_buff_occupancy = 0; ++ retro_audio_buff_underrun = false; ++ audio_latency = 0; ++ update_audio_latency = false; + } + + void retro_deinit() +@@ -828,10 +902,50 @@ void retro_run() + { + int width, height; + BurnDrvGetVisibleSize(&width, &height); ++ int nSkipFrame = 0; ++ + pBurnDraw = (uint8_t*)g_fba_frame; + + InputMake(); + ++ /* Check whether current frame should ++ * be skipped */ ++ if ((frameskip_type > 0) && retro_audio_buff_active) ++ { ++ switch (frameskip_type) ++ { ++ case 1: /* auto */ ++ nSkipFrame = retro_audio_buff_underrun ? 1 : 0; ++ break; ++ case 2: /* manual */ ++ nSkipFrame = (retro_audio_buff_occupancy < frameskip_threshold) ? 1 : 0; ++ break; ++ default: ++ nSkipFrame = 0; ++ break; ++ } ++ ++ if (!nSkipFrame || (frameskip_counter >= frameskip_interval)) ++ { ++ nSkipFrame = 0; ++ frameskip_counter = 0; ++ } ++ else ++ frameskip_counter++; ++ } ++ ++ if (nSkipFrame) ++ pBurnDraw = NULL; ++ ++ /* If frameskip settings have changed, update ++ * frontend audio latency */ ++ if (update_audio_latency) ++ { ++ environ_cb(RETRO_ENVIRONMENT_SET_MINIMUM_AUDIO_LATENCY, ++ &audio_latency); ++ update_audio_latency = false; ++ } ++ + ForceFrameStep(); + + unsigned drv_flags = BurnDrvGetFlags(); +@@ -851,7 +965,11 @@ void retro_run() + nBurnPitch = width * pitch_size; + } + +- video_cb(g_fba_frame, width, height, nBurnPitch); ++ if (!nSkipFrame) ++ video_cb(g_fba_frame, width, height, nBurnPitch); ++ else ++ video_cb(NULL, width, height, nBurnPitch); ++ + audio_batch_cb(g_audio_buf, nBurnSoundLen); + + bool updated = false; +@@ -860,7 +978,7 @@ void retro_run() + neo_geo_modes old_g_opt_neo_geo_mode = g_opt_neo_geo_mode; + bool old_bVerticalMode = bVerticalMode; + +- check_variables(); ++ check_variables(false); + + apply_dipswitch_from_variables(); + +@@ -1166,7 +1284,7 @@ bool retro_load_game(const struct retro_game_info *info) + SetControllerInfo(); + + set_environment(); +- check_variables(); ++ check_variables(true); + + pBurnSoundOut = g_audio_buf; + nBurnSoundRate = AUDIO_SAMPLERATE; +diff --git a/svn-current/trunk/src/burner/libretro/retro_common.cpp b/svn-current/trunk/src/burner/libretro/retro_common.cpp +index 6b8bf31..95c994a 100644 +--- a/svn-current/trunk/src/burner/libretro/retro_common.cpp ++++ b/svn-current/trunk/src/burner/libretro/retro_common.cpp +@@ -62,6 +62,11 @@ INT32 g_audio_samplerate = 48000; + UINT8 *diag_input; + neo_geo_modes g_opt_neo_geo_mode = NEO_GEO_MODE_MVS; + ++extern unsigned frameskip_type; ++extern unsigned frameskip_threshold; ++extern uint16_t frameskip_counter; ++extern unsigned frameskip_interval; ++ + #ifdef USE_CYCLONE + // 0 - c68k, 1 - m68k + // we don't use cyclone by default because it breaks savestates cross-platform compatibility (including netplay) +@@ -78,9 +83,11 @@ static UINT8 diag_input_select_l_r[] = {RETRO_DEVICE_ID_JOYPAD_SELECT, RETRO_DE + + // Global core options + static const struct retro_variable var_empty = { NULL, NULL }; ++static const struct retro_variable var_fbneo_frameskip = { "fbneo-frameskip-type", "Frameskip ; disabled|auto|threshold" }; ++static const struct retro_variable var_fbneo_frameskip_threshold = { "fbneo-threshold", "FS Threshold (%) ; 30|40|50|60" }; ++static const struct retro_variable var_fbneo_frameskip_interval = { "fbneo-interval", "FS Interval ; 0|1|2|3|4|5|6|7|8|9" }; + static const struct retro_variable var_fbneo_allow_depth_32 = { "fbneo-allow-depth-32", "Use 32-bits color depth when available; disabled|enabled" }; + static const struct retro_variable var_fbneo_vertical_mode = { "fbneo-vertical-mode", "Vertical mode; disabled|enabled" }; +-static const struct retro_variable var_fbneo_frameskip = { "fbneo-frameskip", "Frameskip; 0|1|2|3|4|5" }; + static const struct retro_variable var_fbneo_cpu_speed_adjust = { "fbneo-cpu-speed-adjust", "CPU overclock; 100|110|120|130|140|150|160|170|180|190|200" }; + static const struct retro_variable var_fbneo_diagnostic_input = { "fbneo-diagnostic-input", "Diagnostic Input; None|Hold Start|Start + A + B|Hold Start + A + B|Start + L + R|Hold Start + L + R|Hold Select|Select + A + B|Hold Select + A + B|Select + L + R|Hold Select + L + R" }; + static const struct retro_variable var_fbneo_hiscores = { "fbneo-hiscores", "Hiscores; enabled|disabled" }; +@@ -227,9 +234,11 @@ void set_environment() + #endif + + // Add the Global core options ++ vars_systems.push_back(&var_fbneo_frameskip); ++ vars_systems.push_back(&var_fbneo_frameskip_threshold); ++ vars_systems.push_back(&var_fbneo_frameskip_interval); + vars_systems.push_back(&var_fbneo_allow_depth_32); + vars_systems.push_back(&var_fbneo_vertical_mode); +- vars_systems.push_back(&var_fbneo_frameskip); + vars_systems.push_back(&var_fbneo_cpu_speed_adjust); + vars_systems.push_back(&var_fbneo_hiscores); + if (nGameType != RETRO_GAME_TYPE_NEOCD) +@@ -304,9 +313,40 @@ void set_environment() + #endif + } + +-void check_variables(void) ++void check_variables(bool first_run) + { + struct retro_variable var = {0}; ++ bool prev_frameskip_type; ++ ++ var.key = var_fbneo_frameskip.key; ++ var.value = NULL; ++ ++ prev_frameskip_type = frameskip_type; ++ frameskip_type = 0; ++ ++ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) ++ { ++ if (strcmp(var.value, "auto") == 0) ++ frameskip_type = 1; ++ if (strcmp(var.value, "threshold") == 0) ++ frameskip_type = 2; ++ } ++ ++ var.key = var_fbneo_frameskip_threshold.key; ++ var.value = NULL; ++ ++ frameskip_threshold = 30; ++ ++ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) ++ frameskip_threshold = strtol(var.value, NULL, 10); ++ ++ var.key = var_fbneo_frameskip_interval.key; ++ var.value = NULL; ++ ++ frameskip_interval = 1; ++ ++ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) ++ frameskip_interval = strtol(var.value, NULL, 10); + + var.key = var_fbneo_cpu_speed_adjust.key; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var)) +@@ -542,6 +582,11 @@ void check_variables(void) + bCycloneEnabled = false; + } + #endif ++ ++ /* Reinitialise frameskipping, if required */ ++ if (!first_run && ++ ((frameskip_type != prev_frameskip_type))) ++ init_frameskip(); + } + + #ifdef USE_CYCLONE +diff --git a/svn-current/trunk/src/burner/libretro/retro_common.h b/svn-current/trunk/src/burner/libretro/retro_common.h +index 3efc786..f4feae6 100644 +--- a/svn-current/trunk/src/burner/libretro/retro_common.h ++++ b/svn-current/trunk/src/burner/libretro/retro_common.h +@@ -78,7 +78,8 @@ char* str_char_replace(char* destination, char c_find, char c_replace); + void set_neo_system_bios(); + void evaluate_neogeo_bios_mode(const char* drvname); + void set_environment(); +-void check_variables(void); ++void check_variables(bool first_run); ++void init_frameskip(); + #ifdef USE_CYCLONE + void SetSekCpuCore(); + #endif +diff --git a/svn-current/trunk/src/burner/libretro/retro_input.cpp b/svn-current/trunk/src/burner/libretro/retro_input.cpp +index d6b1980..2bf2e8d 100644 +--- a/svn-current/trunk/src/burner/libretro/retro_input.cpp ++++ b/svn-current/trunk/src/burner/libretro/retro_input.cpp +@@ -2293,7 +2293,7 @@ void InputInit() + // Update core option for diagnostic inputs + set_environment(); + // Read the user core option values +- check_variables(); ++ check_variables(false); + + // The list of input descriptors is filled, we can assign them to retroarch + //SetInputDescriptors(); |