Render96 / Render96ex

Fork of https://github.com/sm64-port/sm64-port with additional features.
228 stars 42 forks source link

When 60 fps is disabled the frame rate is inconsistent and the game runs too fast #110

Open cdeletre opened 1 month ago

cdeletre commented 1 month ago

Description of the bug When I set 60 fps to disable in the option menu the are indeed 30 frames generated per second but they are displayed as fast as possible (I guess 60 fps per second would be the maximum) which makes the game running too fast.

To Reproduce Steps to reproduce the behavior:

  1. Start the game
  2. Go to option menu (start, then R) then go to Display section
  3. Disable "60 Fps"
  4. go back to the game (start) and play

Expected behavior When disabling "60 Fps" the game switch to 30 Fps (legacy mode) and should update the display at the rate of 30 fps.

Screenshots

The game running with 60 Fps enabled: 2024-05-28-render96-60fps

https://github.com/Render96/Render96ex/assets/12409537/ab16bd0c-d260-464c-ae73-1aef681b16b4

(I know it's laggy)

2024-05-28-render96-configuration-60fps.txt

The game running with 60 Fps disabled: 2024-05-28-render96-30fps

https://github.com/Render96/Render96ex/assets/12409537/86ff838d-ce12-4d1d-9345-b4da06a7df59

2024-05-28-render96-configuration-30fps.txt

Logs for the full session of test (60 Fps enabled at the begining then disabled):

2024-05-28-render96-log.txt

Platform:

Additional information I've tried to solve the issue by myself and came to something that kind of work but it is far from perfect. If you enable then disable 60 Fps you have to restart the game to have the 30 fps working correctly. I've forced the game to use timer instead of SDL_GL_SetSwapInterval:

--- gfx_sdl2.c  2024-05-28 10:43:53
+++ gfx_sdl2.c.patched  2024-05-28 10:43:40
@@ -54,9 +54,11 @@ static const int frame_time = 1000 / (2 * FRAMERATE);
 // whether to use timer for frame control
 static bool use_timer = true;
 // time between consequtive game frames
-static const int frame_time = 1000 / (2 * FRAMERATE);
+static const int frame_time_60FPS = 1000 / (2 * FRAMERATE);
+static const int frame_time_30FPS = 1000 / FRAMERATE;

+
 const SDL_Scancode windows_scancode_table[] = {
   /*  0                        1                            2                         3                            4                     5                            6                            7  */
   /*  8                        9                            A                         B                            C                     D                            E                            F  */
@@ -141,6 +143,9 @@ static inline void gfx_sdl_set_vsync(const bool enable
 }

 static inline void gfx_sdl_set_vsync(const bool enabled) {
+    use_timer = true;
+    SDL_GL_SetSwapInterval(0);
+    return;
 #ifdef TARGET_SWITCH
     use_timer = false;
         SDL_GL_SetSwapInterval(1);
@@ -357,9 +362,15 @@ static inline void sync_framerate_with_timer(void) {
     // get base timestamp on the first frame (might be different from 0)
     if (last_time == 0) last_time = SDL_GetTicks();
     const int elapsed = SDL_GetTicks() - last_time;
-    if (elapsed < frame_time)
-        SDL_Delay(frame_time - elapsed);
-    last_time += frame_time;
+    if(config60FPS){
+        if (elapsed < frame_time_60FPS)
+            SDL_Delay(frame_time_60FPS - elapsed);
+        last_time += frame_time_60FPS;
+    }else{
+        if (elapsed < frame_time_30FPS)
+            SDL_Delay(frame_time_30FPS - elapsed);
+        last_time += frame_time_30FPS;
+    }
 }

30fps.patch

I've build the game from the commit fb6c865 in the branch tester_rt64alpha