Revert "(hopefully) fix the timing crap; add vsync option"

This reverts commit 2bd840a299.
This commit is contained in:
fgsfds 2020-05-18 23:03:04 +03:00 committed by Vinícius R. Miguel
parent ba26931aa1
commit c3c2451c6a
5 changed files with 46 additions and 43 deletions

View File

@ -27,8 +27,6 @@
#define TEXT_OPT_NEAREST _("Nearest")
#define TEXT_OPT_LINEAR _("Linear")
#define TEXT_OPT_MVOLUME _("Master Volume")
#define TEXT_OPT_VSYNC _("Vertical Sync")
#define TEXT_OPT_DOUBLE _("Double")
#define TEXT_RESET_WINDOW _("Reset Window")
#define TEXT_OPT_UNBOUND _("NONE")

View File

@ -72,9 +72,7 @@ static const u8 optsVideoStr[][32] = {
{ TEXT_OPT_TEXFILTER },
{ TEXT_OPT_NEAREST },
{ TEXT_OPT_LINEAR },
{ TEXT_RESET_WINDOW },
{ TEXT_OPT_VSYNC },
{ TEXT_OPT_DOUBLE },
{ TEXT_RESET_WINDOW }
};
static const u8 optsAudioStr[][32] = {
@ -114,12 +112,6 @@ static const u8 *filterChoices[] = {
optsVideoStr[3],
};
static const u8 *vsyncChoices[] = {
toggleStr[0],
toggleStr[1],
optsVideoStr[6],
};
enum OptType {
OPT_INVALID = 0,
OPT_TOGGLE,
@ -186,12 +178,8 @@ static void optmenu_act_exit(UNUSED struct Option *self, s32 arg) {
if (!arg) game_exit(); // only exit on A press and not directions
}
static void optvideo_reset_window(UNUSED struct Option *self, s32 arg) {
if (!arg) {
// Restrict reset to A press and not directions
configWindow.reset = true;
configWindow.settings_changed = true;
}
static void optvide_reset_window(UNUSED struct Option *self, s32 arg) {
if (!arg) configWindow.reset = true;; // Restrict reset to A press and not directions
}
/* submenu option lists */
@ -229,9 +217,8 @@ static struct Option optsControls[] = {
static struct Option optsVideo[] = {
DEF_OPT_TOGGLE( optsVideoStr[0], &configWindow.fullscreen ),
DEF_OPT_CHOICE( optsVideoStr[5], &configWindow.vsync, vsyncChoices ),
DEF_OPT_CHOICE( optsVideoStr[1], &configFiltering, filterChoices ),
DEF_OPT_BUTTON( optsVideoStr[4], optvideo_reset_window ),
DEF_OPT_BUTTON( optsVideoStr[4], optvide_reset_window ),
};
static struct Option optsAudio[] = {
@ -243,8 +230,8 @@ static struct Option optsCheats[] = {
DEF_OPT_TOGGLE( optsCheatsStr[1], &Cheats.MoonJump ),
DEF_OPT_TOGGLE( optsCheatsStr[2], &Cheats.GodMode ),
DEF_OPT_TOGGLE( optsCheatsStr[3], &Cheats.InfiniteLives ),
DEF_OPT_TOGGLE( optsCheatsStr[4], &Cheats.SuperSpeed ),
DEF_OPT_TOGGLE( optsCheatsStr[5], &Cheats.Responsive ),
DEF_OPT_TOGGLE( optsCheatsStr[4], &Cheats.SuperSpeed),
DEF_OPT_TOGGLE( optsCheatsStr[5], &Cheats.Responsive),
};

View File

@ -40,11 +40,10 @@ ConfigWindow configWindow = {
.y = SDL_WINDOWPOS_CENTERED,
.w = DESIRED_SCREEN_WIDTH,
.h = DESIRED_SCREEN_HEIGHT,
.vsync = 1,
.reset = false,
.vsync = false,
.fullscreen = false,
.exiting_fullscreen = false,
.settings_changed = false,
};
unsigned int configFiltering = 1; // 0=force nearest, 1=linear, (TODO) 2=three-point
unsigned int configMasterVolume = MAX_VOLUME; // 0 - MAX_VOLUME
@ -85,7 +84,6 @@ static const struct ConfigOption options[] = {
{.name = "window_y", .type = CONFIG_TYPE_UINT, .uintValue = &configWindow.y},
{.name = "window_w", .type = CONFIG_TYPE_UINT, .uintValue = &configWindow.w},
{.name = "window_h", .type = CONFIG_TYPE_UINT, .uintValue = &configWindow.h},
{.name = "vsync", .type = CONFIG_TYPE_UINT, .uintValue = &configWindow.vsync},
{.name = "texture_filtering", .type = CONFIG_TYPE_UINT, .uintValue = &configFiltering},
{.name = "master_volume", .type = CONFIG_TYPE_UINT, .uintValue = &configMasterVolume},
{.name = "key_a", .type = CONFIG_TYPE_BIND, .uintValue = configKeyA},

View File

@ -11,11 +11,10 @@
typedef struct {
unsigned int x, y, w, h;
unsigned int vsync;
bool reset;
bool vsync;
bool fullscreen;
bool exiting_fullscreen;
bool settings_changed;
} ConfigWindow;
extern ConfigWindow configWindow;

View File

@ -39,12 +39,9 @@
# define FRAMERATE 30
#endif
static const Uint32 FRAME_TIME = 1000 / FRAMERATE;
static SDL_Window *wnd;
static SDL_GLContext ctx = NULL;
static int inverted_scancode_table[512];
static Uint32 frame_start = 0;
const SDL_Scancode windows_scancode_table[] =
{
@ -113,9 +110,9 @@ static void gfx_sdl_set_fullscreen() {
}
static void gfx_sdl_reset_dimension_and_pos() {
if (configWindow.exiting_fullscreen) {
if (configWindow.exiting_fullscreen)
configWindow.exiting_fullscreen = false;
} else if (configWindow.reset) {
else if (configWindow.reset) {
configWindow.x = SDL_WINDOWPOS_CENTERED;
configWindow.y = SDL_WINDOWPOS_CENTERED;
configWindow.w = DESIRED_SCREEN_WIDTH;
@ -126,14 +123,29 @@ static void gfx_sdl_reset_dimension_and_pos() {
configWindow.fullscreen = false;
return;
}
} else if (!configWindow.settings_changed) {
} else
return;
}
configWindow.settings_changed = false;
SDL_SetWindowSize(wnd, configWindow.w, configWindow.h);
SDL_SetWindowPosition(wnd, configWindow.x, configWindow.y);
SDL_GL_SetSwapInterval(configWindow.vsync); // in case vsync changed
}
static bool test_vsync(void) {
// Even if SDL_GL_SetSwapInterval succeeds, it doesn't mean that VSync actually works.
// A 60 Hz monitor should have a swap interval of 16.67 milliseconds.
// If it takes less than 12 milliseconds, assume that VSync is not working.
// SDL_GetTicks() probably does not offer enough precision for this kind of shit.
Uint32 start, end;
// do an extra swap, sometimes the first one takes longer (maybe creates buffers?)
SDL_GL_SwapWindow(wnd);
SDL_GL_SwapWindow(wnd);
start = SDL_GetTicks();
SDL_GL_SwapWindow(wnd);
end = SDL_GetTicks();
return (end - start >= 12);
}
static void gfx_sdl_init(void) {
@ -153,9 +165,11 @@ static void gfx_sdl_init(void) {
if (gCLIOpts.FullScreen == 1)
configWindow.fullscreen = true;
else if (gCLIOpts.FullScreen == 2)
if (gCLIOpts.FullScreen == 2)
configWindow.fullscreen = false;
const char* window_title =
#ifndef USE_GLES
"Super Mario 64 PC port (OpenGL)";
@ -169,11 +183,14 @@ static void gfx_sdl_init(void) {
SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE
);
ctx = SDL_GL_CreateContext(wnd);
SDL_GL_SetSwapInterval(configWindow.vsync);
SDL_GL_SetSwapInterval(2);
gfx_sdl_set_fullscreen();
configWindow.vsync = test_vsync();
if (!configWindow.vsync)
printf("Warning: VSync is not enabled or not working. Falling back to timer for synchronization\n");
for (size_t i = 0; i < sizeof(windows_scancode_table) / sizeof(SDL_Scancode); i++) {
inverted_scancode_table[windows_scancode_table[i]] = i;
}
@ -258,19 +275,23 @@ static void gfx_sdl_handle_events(void) {
}
static bool gfx_sdl_start_frame(void) {
frame_start = SDL_GetTicks();
return true;
}
static void sync_framerate_with_timer(void) {
Uint32 elapsed = SDL_GetTicks() - frame_start;
// Number of milliseconds a frame should take (30 fps)
const Uint32 FRAME_TIME = 1000 / FRAMERATE;
static Uint32 last_time;
Uint32 elapsed = SDL_GetTicks() - last_time;
if (elapsed < FRAME_TIME)
SDL_Delay(FRAME_TIME - elapsed);
last_time = SDL_GetTicks();
}
static void gfx_sdl_swap_buffers_begin(void) {
// if vsync is set to 2, depend only on SwapInterval to sync
if (configWindow.vsync <= 1)
if (!configWindow.vsync)
sync_framerate_with_timer();
SDL_GL_SwapWindow(wnd);
}