diff --git a/gtk/src/gtk_config.cpp b/gtk/src/gtk_config.cpp index 9d8ceddb..4759de21 100644 --- a/gtk/src/gtk_config.cpp +++ b/gtk/src/gtk_config.cpp @@ -234,6 +234,7 @@ int Snes9xConfig::save_config_file() outint("NumberOfThreads", num_threads); outstring("HardwareAcceleration", display_driver, "none, opengl, xv, vulkan"); outint("SplashBackground", splash_image, "0: Black, 1: Color bars, 2: Pattern, 3: Blue, 4: Default"); + outbool("AutoVRR", auto_vrr, "Automatically use the best settings for variable sync in fullscreen mode"); section = "NTSC"; outstring("Hue", std::to_string(ntsc_setup.hue)); @@ -457,6 +458,7 @@ int Snes9xConfig::load_config_file() instr("HardwareAcceleration", display_driver); inbool("BilinearFilter", Settings.BilinearFilter); inint("SplashBackground", splash_image); + inbool("AutoVRR", auto_vrr); section = "NTSC"; indouble("Hue", ntsc_setup.hue); diff --git a/gtk/src/gtk_config.h b/gtk/src/gtk_config.h index ff953c12..031dbc8f 100644 --- a/gtk/src/gtk_config.h +++ b/gtk/src/gtk_config.h @@ -71,6 +71,7 @@ class Snes9xConfig int hires_effect; bool force_inverted_byte_order; int splash_image; + bool auto_vrr; snes_ntsc_setup_t ntsc_setup; int ntsc_format; diff --git a/gtk/src/gtk_display.cpp b/gtk/src/gtk_display.cpp index 6b6da8d9..3518c420 100644 --- a/gtk/src/gtk_display.cpp +++ b/gtk/src/gtk_display.cpp @@ -751,9 +751,9 @@ void S9xConvertMask(void *src, bpp); } -void S9xDisplayRefresh(int width, int height) +void S9xDisplayRefresh() { - driver->refresh(width, height); + driver->refresh(); } static void ntsc_filter_init() diff --git a/gtk/src/gtk_display.h b/gtk/src/gtk_display.h index 4a70feb7..72e66138 100644 --- a/gtk/src/gtk_display.h +++ b/gtk/src/gtk_display.h @@ -88,7 +88,7 @@ void S9xFilter(uint8 *src_buffer, int &width, int &height); void apply_filter_scale(int &width, int &height); -void S9xDisplayRefresh(int width, int height); +void S9xDisplayRefresh(); void S9xReinitDisplay(); void S9xDisplayReconfigure(); void S9xQueryDrivers(); diff --git a/gtk/src/gtk_display_driver.h b/gtk/src/gtk_display_driver.h index c02a841b..ffe187d7 100644 --- a/gtk/src/gtk_display_driver.h +++ b/gtk/src/gtk_display_driver.h @@ -15,7 +15,7 @@ class S9xDisplayDriver virtual ~S9xDisplayDriver() { } - virtual void refresh(int width, int height) = 0; + virtual void refresh() = 0; virtual int init() = 0; virtual void deinit() = 0; virtual void update(uint16_t *buffer, int width, int height, int stride_in_pixels) = 0; diff --git a/gtk/src/gtk_display_driver_gtk.cpp b/gtk/src/gtk_display_driver_gtk.cpp index 7b8d1b48..5a904f02 100644 --- a/gtk/src/gtk_display_driver_gtk.cpp +++ b/gtk/src/gtk_display_driver_gtk.cpp @@ -131,7 +131,7 @@ void S9xGTKDisplayDriver::clear() window->release_cairo(); } -void S9xGTKDisplayDriver::refresh(int width, int height) +void S9xGTKDisplayDriver::refresh() { clear(); } \ No newline at end of file diff --git a/gtk/src/gtk_display_driver_gtk.h b/gtk/src/gtk_display_driver_gtk.h index 9142cc66..d2caa7ce 100644 --- a/gtk/src/gtk_display_driver_gtk.h +++ b/gtk/src/gtk_display_driver_gtk.h @@ -14,7 +14,7 @@ class S9xGTKDisplayDriver : public S9xDisplayDriver { public: S9xGTKDisplayDriver(Snes9xWindow *window, Snes9xConfig *config); - void refresh(int width, int height); + void refresh(); int init(); void deinit(); void update(uint16_t *buffer, int width, int height, int stride_in_pixels); diff --git a/gtk/src/gtk_display_driver_opengl.cpp b/gtk/src/gtk_display_driver_opengl.cpp index b0173e09..6201ff41 100644 --- a/gtk/src/gtk_display_driver_opengl.cpp +++ b/gtk/src/gtk_display_driver_opengl.cpp @@ -340,7 +340,7 @@ bool S9xOpenGLDisplayDriver::opengl_defaults() return true; } -void S9xOpenGLDisplayDriver::refresh(int width, int height) +void S9xOpenGLDisplayDriver::refresh() { resize(); } diff --git a/gtk/src/gtk_display_driver_opengl.h b/gtk/src/gtk_display_driver_opengl.h index a8c5087a..b074d70e 100644 --- a/gtk/src/gtk_display_driver_opengl.h +++ b/gtk/src/gtk_display_driver_opengl.h @@ -31,7 +31,7 @@ class S9xOpenGLDisplayDriver : public S9xDisplayDriver { public: S9xOpenGLDisplayDriver(Snes9xWindow *window, Snes9xConfig *config); - void refresh(int width, int height) override; + void refresh() override; int init() override; void deinit() override; void update(uint16_t *buffer, int width, int height, int stride_in_pixels) override; diff --git a/gtk/src/gtk_display_driver_vulkan.cpp b/gtk/src/gtk_display_driver_vulkan.cpp index e767e06f..c00ad296 100644 --- a/gtk/src/gtk_display_driver_vulkan.cpp +++ b/gtk/src/gtk_display_driver_vulkan.cpp @@ -26,7 +26,7 @@ S9xVulkanDisplayDriver::~S9xVulkanDisplayDriver() { } -void S9xVulkanDisplayDriver::refresh(int width, int height) +void S9xVulkanDisplayDriver::refresh() { if (!context) return; diff --git a/gtk/src/gtk_display_driver_vulkan.h b/gtk/src/gtk_display_driver_vulkan.h index 282eae95..ec6511c0 100644 --- a/gtk/src/gtk_display_driver_vulkan.h +++ b/gtk/src/gtk_display_driver_vulkan.h @@ -21,7 +21,7 @@ class S9xVulkanDisplayDriver : public S9xDisplayDriver public: S9xVulkanDisplayDriver(Snes9xWindow *window, Snes9xConfig *config); ~S9xVulkanDisplayDriver(); - void refresh(int width, int height) override; + void refresh() override; int init() override; void deinit() override; void update(uint16_t *buffer, int width, int height, int stride_in_pixels) override; diff --git a/gtk/src/gtk_display_driver_xv.cpp b/gtk/src/gtk_display_driver_xv.cpp index 784b3131..4b009ed1 100644 --- a/gtk/src/gtk_display_driver_xv.cpp +++ b/gtk/src/gtk_display_driver_xv.cpp @@ -456,7 +456,7 @@ void S9xXVDisplayDriver::clear() XSync(display, False); } -void S9xXVDisplayDriver::refresh(int width, int height) +void S9xXVDisplayDriver::refresh() { clear(); } diff --git a/gtk/src/gtk_display_driver_xv.h b/gtk/src/gtk_display_driver_xv.h index 5dd84241..ee20c740 100644 --- a/gtk/src/gtk_display_driver_xv.h +++ b/gtk/src/gtk_display_driver_xv.h @@ -21,7 +21,7 @@ class S9xXVDisplayDriver : public S9xDisplayDriver { public: S9xXVDisplayDriver(Snes9xWindow *window, Snes9xConfig *config); - void refresh(int width, int height); + void refresh(); int init(); void deinit(); void update(uint16_t *buffer, int width, int height, int stride_in_pixels); diff --git a/gtk/src/gtk_preferences.cpp b/gtk/src/gtk_preferences.cpp index df07108a..221f13fd 100644 --- a/gtk/src/gtk_preferences.cpp +++ b/gtk/src/gtk_preferences.cpp @@ -283,7 +283,7 @@ void Snes9xPreferences::game_data_browse(std::string folder) void Snes9xPreferences::input_rate_changed() { double value = get_object("sound_input_rate")->get_value(); - value = value / 32040.0 * 60.09881389744051; + value = value / 32040.0 * NTSC_PROGRESSIVE_FRAME_RATE; get_object("relative_video_rate")->set_label(fmt::format("{:.4f}Hz", value)); } @@ -464,6 +464,7 @@ void Snes9xPreferences::move_settings_to_dialog() set_combo ("frameskip_combo", Settings.SkipFrames); set_check ("bilinear_filter", Settings.BilinearFilter); + set_check ("auto_vrr", config->auto_vrr); set_check ("sync_to_vblank", config->sync_to_vblank); set_check ("reduce_input_lag", config->reduce_input_lag); @@ -568,6 +569,7 @@ void Snes9xPreferences::get_settings_from_dialog() config->aspect_ratio = get_combo("aspect_ratio"); config->scale_method = get_combo("scale_method_combo"); config->hires_effect = get_combo("hires_effect"); + config->auto_vrr = get_check("auto_vrr"); config->force_inverted_byte_order = get_check("force_inverted_byte_order"); Settings.AutoSaveDelay = get_entry_value("save_sram_after_sec"); config->multithreading = get_check("multithreading"); @@ -697,7 +699,7 @@ void Snes9xPreferences::get_settings_from_dialog() } S9xDisplayReconfigure(); - S9xDisplayRefresh(top_level->last_width, top_level->last_height); + S9xDisplayRefresh(); S9xDeinitUpdate(top_level->last_width, top_level->last_height); diff --git a/gtk/src/gtk_s9x.cpp b/gtk/src/gtk_s9x.cpp index 0503ccdf..078ed672 100644 --- a/gtk/src/gtk_s9x.cpp +++ b/gtk/src/gtk_s9x.cpp @@ -222,7 +222,7 @@ void S9xNoROMLoaded() { S9xSoundStop(); gui_config->rom_loaded = false; - S9xDisplayRefresh(-1, -1); + S9xDisplayRefresh(); top_level->configure_widgets(); } diff --git a/gtk/src/gtk_s9xwindow.cpp b/gtk/src/gtk_s9xwindow.cpp index 73a11f50..be4d5cac 100644 --- a/gtk/src/gtk_s9xwindow.cpp +++ b/gtk/src/gtk_s9xwindow.cpp @@ -5,6 +5,7 @@ \*****************************************************************************/ #include "gtk_compat.h" +#include "gtk_config.h" #ifdef GDK_WINDOWING_X11 #include @@ -538,7 +539,7 @@ bool Snes9xWindow::draw(const Cairo::RefPtr &cr) setup_splash(); } - S9xDisplayRefresh(last_width, last_height); + S9xDisplayRefresh(); if (!(config->fullscreen)) { @@ -1204,6 +1205,21 @@ void Snes9xWindow::enter_fullscreen_mode() gdk_display_sync(gdk_display); window->present(); + if (config->auto_vrr) + { + autovrr_saved_frameskip = Settings.SkipFrames; + autovrr_saved_sound_input_rate = Settings.SoundInputRate; + autovrr_saved_sync_to_vblank = gui_config->sync_to_vblank; + autovrr_saved_sound_sync = Settings.SoundSync; + + Settings.SoundSync = false; + Settings.SkipFrames = THROTTLE_TIMER; + Settings.SoundInputRate = 32040; + S9xUpdateDynamicRate(1, 2); + gui_config->sync_to_vblank = true; + S9xDisplayRefresh(); + } + #ifdef GDK_WINDOWING_X11 if (GDK_IS_X11_WINDOW(window->get_window()->gobj()) && config->default_esc_behavior != ESC_TOGGLE_MENUBAR) @@ -1216,6 +1232,7 @@ void Snes9xWindow::enter_fullscreen_mode() config->fullscreen = 1; config->rom_loaded = rom_loaded; + /* If we're running a game, disable ui when entering fullscreen */ if (!Settings.Paused && config->rom_loaded) config->ui_visible = false; @@ -1230,6 +1247,16 @@ void Snes9xWindow::leave_fullscreen_mode() if (!config->fullscreen) return; + if (config->auto_vrr) + { + Settings.SkipFrames = autovrr_saved_frameskip; + Settings.SoundInputRate = autovrr_saved_sound_input_rate; + gui_config->sync_to_vblank = autovrr_saved_sync_to_vblank; + Settings.SoundSync = autovrr_saved_sound_sync; + S9xUpdateDynamicRate(1, 2); + S9xDisplayRefresh(); + } + GdkDisplay *gdk_display = window->get_display()->gobj(); GdkWindow *gdk_window = window->get_window()->gobj(); diff --git a/gtk/src/gtk_s9xwindow.h b/gtk/src/gtk_s9xwindow.h index 6e656318..a2b0414d 100644 --- a/gtk/src/gtk_s9xwindow.h +++ b/gtk/src/gtk_s9xwindow.h @@ -89,6 +89,10 @@ class Snes9xWindow : public GtkBuilderWindow int mouse_region_x, mouse_region_y; int mouse_region_width, mouse_region_height; int nfs_width, nfs_height, nfs_x, nfs_y; + int autovrr_saved_frameskip; + int autovrr_saved_sound_input_rate; + bool autovrr_saved_sync_to_vblank; + bool autovrr_saved_sound_sync; int fullscreen_state; int maximized_state; bool focused; diff --git a/gtk/src/snes9x.ui b/gtk/src/snes9x.ui index 961f3dcf..d43e68cd 100644 --- a/gtk/src/snes9x.ui +++ b/gtk/src/snes9x.ui @@ -3802,6 +3802,21 @@ True 1 + + + + Use best settings for FreeSync/G-Sync when fullscreen + True + True + False + True + True + + + False + True + 2 + @@ -3902,7 +3917,7 @@ False True - 2 + 3 @@ -3928,7 +3943,7 @@ False True - 3 + 4