aboutsummaryrefslogtreecommitdiff
path: root/patches/fbalpha2012/1001-add-auto-frameskip.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/fbalpha2012/1001-add-auto-frameskip.patch')
-rw-r--r--patches/fbalpha2012/1001-add-auto-frameskip.patch297
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();