Skip to content

Commit

Permalink
Close snesrev#36
Browse files Browse the repository at this point in the history
  • Loading branch information
nightmareci committed Jan 22, 2024
1 parent eae20c6 commit 41b264e
Show file tree
Hide file tree
Showing 6 changed files with 841 additions and 26 deletions.
20 changes: 17 additions & 3 deletions smw.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
# Automatically save state on quit and reload on start
Autosave = 0

# Disable the SDL_Delay that happens each frame (Gives slightly better perf if your
# display is set to exactly 60hz)
# Disable the manual delaying without vsync that happens each frame. Instead,
# rely on vsync to do frame timing. Results in frames never being dropped at
# the cost of more lag, but be sure to set your display to 60hz when using
# this.
DisableFrameDelay = 0

# Save a snapshot each time a level is completed
Expand Down Expand Up @@ -31,7 +33,19 @@ NoSpriteLimits = 1

# Use either SDL, SDL-Software, or OpenGL as the output method
# SDL-Software rendering might give better performance on Raspberry pi.
#OutputMethod = SDL
OutputMethod = SDL

# The type of display sync to use, when vsync is not forced on ( Disabled, Vsync, or Adaptive )
# Vsync is forced on when DisableFrameDelay is 1. Disabled and Vsync should
# always work. Disabled produces less lag than Vsync, at the cost of possible
# tearing. Adaptive sync is only supported when OutputMethod is OpenGL. If your
# setup supports FreeSync or G-Sync, you'll get least-lag-no-tearing with frame
# delay not disabled, adaptive sync, and OpenGL output method. Choosing
# adaptive sync with OpenGL output method when your setup doesn't support
# adaptive sync can result in using vsync instead.
#DisplaySync = Disabled
DisplaySync = Vsync
#DisplaySync = Adaptive

# Set to true to use linear filtering. Gives less crisp pixels. Works with SDL and OpenGL.
#LinearFiltering = 0
Expand Down
5 changes: 5 additions & 0 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,11 @@ static bool HandleIniConfig(int section, const char *key, char *value) {
g_config.output_method = StringEqualsNoCase(value, "SDL-Software") ? kOutputMethod_SDLSoftware :
StringEqualsNoCase(value, "OpenGL") ? kOutputMethod_OpenGL : kOutputMethod_SDL;
return true;
} else if (StringEqualsNoCase(key, "DisplaySync")) {
g_config.display_sync = StringEqualsNoCase(value, "Disabled") ? 0 :
StringEqualsNoCase(value, "Vsync") ? 1 :
StringEqualsNoCase(value, "Adaptive") ? -1 : 0;
return true;
} else if (StringEqualsNoCase(key, "LinearFiltering")) {
return ParseBool(value, &g_config.linear_filtering);
} else if (StringEqualsNoCase(key, "NoSpriteLimits")) {
Expand Down
1 change: 1 addition & 0 deletions src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ typedef struct Config {
uint8 enable_msu;
bool resume_msu;
bool disable_frame_delay;
int display_sync;
bool save_playthrough;
uint8 msuvolume;
uint32 features0;
Expand Down
50 changes: 28 additions & 22 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include <sys/types.h>
#include <unistd.h>
#endif
#define NANOTIME_IMPLEMENTATION
#include "third_party/nanotime/nanotime.h"

#include "assets/smw_assets.h"

Expand Down Expand Up @@ -263,7 +265,26 @@ static bool SdlRenderer_Init(SDL_Window *window) {

SDL_Renderer *renderer = SDL_CreateRenderer(g_window, -1,
g_config.output_method == kOutputMethod_SDLSoftware ? SDL_RENDERER_SOFTWARE :
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
SDL_RENDERER_ACCELERATED | (g_config.disable_frame_delay || g_config.display_sync == 1 ? SDL_RENDERER_PRESENTVSYNC : 0));
if (g_config.disable_frame_delay) {
printf("Using vsync without frame delay\n");
}
else {
switch (g_config.display_sync) {
case 0:
printf("Disabled vsync\n");
break;
case 1:
printf("Using vsync\n");
break;
case -1:
printf("Attempted to use adaptive sync when not supported; defaulting to disabled vsync\n");
break;
default:
printf("Invalid g_config.display_func value of %d; defaulting to disabled vsync\n", g_config.display_sync);
break;
}
}
if (renderer == NULL) {
printf("Failed to create renderer: %s\n", SDL_GetError());
return false;
Expand Down Expand Up @@ -314,7 +335,7 @@ static void SdlRenderer_EndDraw(void) {
// printf("%f ms\n", v * 1000);
SDL_RenderClear(g_renderer);
SDL_RenderCopy(g_renderer, g_texture, &g_sdl_renderer_rect, NULL);
SDL_RenderPresent(g_renderer); // vsyncs to 60 FPS?
SDL_RenderPresent(g_renderer);
}

static const struct RendererFuncs kSdlRendererFuncs = {
Expand Down Expand Up @@ -478,12 +499,12 @@ error_reading:;
HandleCommand(kKeys_Load + 0, true);

bool running = true;
uint32 lastTick = SDL_GetTicks();
uint32 curTick = 0;
uint32 frameCtr = 0;
uint8 audiopaused = true;
bool has_bug_in_title = false;
GamepadInfo *gi;
nanotime_step_data stepper;
nanotime_step_init(&stepper, NANOTIME_NSEC_PER_SEC / 60, nanotime_now_max(), nanotime_now, nanotime_sleep);

while (running) {
SDL_Event event;
Expand Down Expand Up @@ -546,7 +567,7 @@ error_reading:;
}

if (g_paused) {
SDL_Delay(16);
nanotime_sleep(stepper.sleep_duration);
continue;
}

Expand Down Expand Up @@ -576,24 +597,9 @@ error_reading:;
}
}

// if vsync isn't working, delay manually
curTick = SDL_GetTicks();

// If not leaning on vsync to do timing, delay manually
if (!g_snes->disableRender && !g_config.disable_frame_delay) {
static const uint8 delays[3] = { 17, 17, 16 }; // 60 fps
lastTick += delays[frameCtr % 3];

if (lastTick > curTick) {
uint32 delta = lastTick - curTick;
if (delta > 500) {
lastTick = curTick - 500;
delta = 500;
}
// printf("Sleeping %d\n", delta);
SDL_Delay(delta);
} else if (curTick - lastTick > 500) {
lastTick = curTick;
}
nanotime_step(&stepper);
}
}

Expand Down
26 changes: 25 additions & 1 deletion src/opengl.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,31 @@ static bool OpenGLRenderer_Init(SDL_Window *window) {
SDL_GLContext context = SDL_GL_CreateContext(window);
(void)context;

SDL_GL_SetSwapInterval(1);
if (g_config.disable_frame_delay) {
SDL_GL_SetSwapInterval(1);
printf("Using vsync without frame delay\n");
}
else if (SDL_GL_SetSwapInterval(g_config.display_sync) < 0) {
SDL_GL_SetSwapInterval(0);
printf("Disabled vsync; chosen display sync setting not supported\n");
}
else {
switch (g_config.display_sync) {
case 0:
printf("Disabled vsync\n");
break;
case 1:
printf("Using vsync\n"); break;
break;
case -1:
printf("Using adaptive sync\n");
break;
default:
printf("Unknown value of g_config.display_sync: %d\n", g_config.display_sync);
break;
}
}

ogl_LoadFunctions();

if (!ogl_IsVersionGEQ(3, 3))
Expand Down
Loading

0 comments on commit 41b264e

Please sign in to comment.