@@ -44,6 +44,9 @@ static bool paused_when_focus_lost = false;
4444static Uint64 frame_time_start = 0 ;
4545static Uint64 frame_time_end = 0 ;
4646static bool input_updated = false ;
47+ static int monitor_refresh_rate = 60 ;
48+ static int vsync_frames_per_emu_frame = 1 ;
49+ static int vsync_frame_counter = 0 ;
4750static Uint16 input_last_state[GG_MAX_GAMEPADS] = { };
4851static bool input_turbo_toggle_prev[GG_MAX_GAMEPADS][2 ] = { };
4952static bool input_gamepad_shortcut_prev[GG_MAX_GAMEPADS][config_HotkeyIndex_COUNT] = { };
@@ -77,8 +80,10 @@ static void handle_mouse_cursor(void);
7780static void handle_menu (void );
7881static void handle_single_instance (void );
7982static void run_emulator (void );
83+ static bool should_run_emu_frame (void );
8084static void render (void );
8185static void frame_throttle (void );
86+ static void update_frame_pacing (void );
8287static void save_window_size (void );
8388static void log_sdl_error (const char * action, const char * file, int line);
8489static bool check_hotkey (const SDL_Event* event, const config_Hotkey& hotkey, bool allow_repeat);
@@ -139,7 +144,7 @@ int application_init(const char* rom_file, const char* symbol_file, bool force_f
139144 return 5 ;
140145 }
141146
142- SDL_GL_SetSwapInterval (config_video.sync ? 1 : 0 );
147+ application_set_vsync (config_video.sync );
143148
144149 if (config_emulator.fullscreen )
145150 application_trigger_fullscreen (true );
@@ -322,6 +327,7 @@ void application_trigger_fullscreen(bool fullscreen)
322327#endif
323328
324329 mouse_last_motion_time = SDL_GetTicks ();
330+ update_frame_pacing ();
325331}
326332
327333void application_trigger_fit_to_content (int width, int height)
@@ -330,6 +336,12 @@ void application_trigger_fit_to_content(int width, int height)
330336 SDL_ERROR (" SDL_SetWindowSize" );
331337}
332338
339+ void application_set_vsync (bool enabled)
340+ {
341+ SDL_GL_SetSwapInterval (enabled ? 1 : 0 );
342+ update_frame_pacing ();
343+ }
344+
333345void application_update_title_with_rom (const char * rom)
334346{
335347 char final_title[256 ];
@@ -740,6 +752,11 @@ static void sdl_events_app(const SDL_Event* event)
740752 }
741753 break ;
742754 }
755+ case SDL_WINDOWEVENT_DISPLAY_CHANGED:
756+ {
757+ update_frame_pacing ();
758+ break ;
759+ }
743760 }
744761 break ;
745762 }
@@ -1201,6 +1218,9 @@ static bool input_get_button(SDL_GameController* controller, int mapping)
12011218
12021219static void run_emulator (void )
12031220{
1221+ if (!should_run_emu_frame ())
1222+ return ;
1223+
12041224 config_emulator.paused = emu_is_paused ();
12051225 emu_audio_sync = config_audio.sync ;
12061226 emu_update ();
@@ -1210,6 +1230,20 @@ static void run_emulator(void)
12101230 input_updated = false ;
12111231}
12121232
1233+ static bool should_run_emu_frame (void )
1234+ {
1235+ if (config_video.sync && vsync_frames_per_emu_frame > 1 && !config_emulator.ffwd )
1236+ {
1237+ bool should_run = (vsync_frame_counter == 0 );
1238+ vsync_frame_counter++;
1239+ if (vsync_frame_counter >= vsync_frames_per_emu_frame)
1240+ vsync_frame_counter = 0 ;
1241+ return should_run;
1242+ }
1243+
1244+ return true ;
1245+ }
1246+
12131247static void render (void )
12141248{
12151249 renderer_begin_render ();
@@ -1269,6 +1303,37 @@ static void save_window_size(void)
12691303 }
12701304}
12711305
1306+ static void update_frame_pacing (void )
1307+ {
1308+ int display = SDL_GetWindowDisplayIndex (application_sdl_window);
1309+ SDL_ERROR (" SDL_GetWindowDisplayIndex" );
1310+
1311+ if (display < 0 )
1312+ display = 0 ;
1313+
1314+ SDL_DisplayMode mode;
1315+ if (SDL_GetCurrentDisplayMode (display, &mode) == 0 && mode.refresh_rate > 0 )
1316+ monitor_refresh_rate = mode.refresh_rate ;
1317+ else
1318+ {
1319+ SDL_ERROR (" SDL_GetCurrentDisplayMode" );
1320+ monitor_refresh_rate = 60 ;
1321+ }
1322+
1323+ const int emu_fps = 60 ;
1324+
1325+ if (monitor_refresh_rate <= emu_fps + 5 )
1326+ vsync_frames_per_emu_frame = 1 ;
1327+ else
1328+ vsync_frames_per_emu_frame = (monitor_refresh_rate + emu_fps / 2 ) / emu_fps;
1329+
1330+ vsync_frames_per_emu_frame = CLAMP (vsync_frames_per_emu_frame, 1 , 8 );
1331+
1332+ vsync_frame_counter = 0 ;
1333+
1334+ Debug (" Monitor refresh rate: %d Hz, vsync frames per emu frame: %d" , monitor_refresh_rate, vsync_frames_per_emu_frame);
1335+ }
1336+
12721337static void log_sdl_error (const char * action, const char * file, int line)
12731338{
12741339 const char * error = SDL_GetError ();
0 commit comments