1
0
Fork 0
mirror of https://github.com/TerryCavanagh/VVVVVV.git synced 2024-12-23 10:09:43 +01:00

Move the VSync work to Screen.

The problem we're running into is entirely contained in the Screen - we need to
either decouple graphics context init from Screen::init or we need to take out
the screenbuffer interaction from loadstats (which I'm more in favor of since we
can just pull the config values and pass them to Screen::init later).
This commit is contained in:
Ethan Lee 2020-07-02 00:19:40 -04:00
parent d854c61960
commit 0f450f3e39
8 changed files with 55 additions and 50 deletions

View file

@ -4848,7 +4848,7 @@ void Game::loadstats()
if (pKey == "vsync") if (pKey == "vsync")
{ {
graphics.vsync = atoi(pText); graphics.screenbuffer->vsync = atoi(pText);
} }
if (pKey == "notextoutline") if (pKey == "notextoutline")
@ -5118,7 +5118,7 @@ void Game::savestats()
dataNode->LinkEndChild(msg); dataNode->LinkEndChild(msg);
msg = doc.NewElement("vsync"); msg = doc.NewElement("vsync");
msg->LinkEndChild(doc.NewText(help.String((int) graphics.vsync).c_str())); msg->LinkEndChild(doc.NewText(help.String((int) graphics.screenbuffer->vsync).c_str()));
dataNode->LinkEndChild(msg); dataNode->LinkEndChild(msg);
for (size_t i = 0; i < controllerButton_flip.size(); i += 1) for (size_t i = 0; i < controllerButton_flip.size(); i += 1)

View file

@ -139,8 +139,6 @@ void Graphics::init()
col_tb = 0; col_tb = 0;
kludgeswnlinewidth = false; kludgeswnlinewidth = false;
vsync = false;
} }
int Graphics::font_idx(uint32_t ch) { int Graphics::font_idx(uint32_t ch) {
@ -3273,42 +3271,3 @@ Uint32 Graphics::crewcolourreal(int t)
} }
return col_crewcyan; return col_crewcyan;
} }
void Graphics::processVsync()
{
SDL_SetHintWithPriority(SDL_HINT_RENDER_VSYNC, vsync ? "1" : "0", SDL_HINT_OVERRIDE);
if (screenbuffer == NULL)
{
return;
}
// FIXME: Sigh... work around SDL2 bug where the VSync hint is only
// listened to at renderer creation
// Ugh, have to re-create m_screenTexture as well, otherwise the screen
// will be black...
if (screenbuffer->m_screenTexture != NULL)
{
SDL_DestroyTexture(screenbuffer->m_screenTexture);
}
if (screenbuffer->m_renderer != NULL)
{
SDL_DestroyRenderer(screenbuffer->m_renderer);
}
screenbuffer->m_renderer = SDL_CreateRenderer(screenbuffer->m_window, -1, 0);
// FIXME: This is duplicated from Screen::init()!
screenbuffer->m_screenTexture = SDL_CreateTexture(
screenbuffer->m_renderer,
SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STREAMING,
320,
240
);
// Ugh, have to make sure to re-apply graphics options after doing the
// above, otherwise letterbox/integer won't be applied...
screenbuffer->ResizeScreen(-1, -1);
}

View file

@ -326,9 +326,6 @@ public:
bool kludgeswnlinewidth; bool kludgeswnlinewidth;
Uint32 crewcolourreal(int t); Uint32 crewcolourreal(int t);
bool vsync;
void processVsync();
}; };
extern Graphics graphics; extern Graphics graphics;

View file

@ -369,8 +369,8 @@ void menuactionpress()
case 6: case 6:
//toggle vsync //toggle vsync
music.playef(11); music.playef(11);
graphics.vsync = !graphics.vsync; graphics.screenbuffer->vsync = !graphics.screenbuffer->vsync;
graphics.processVsync(); graphics.screenbuffer->resetRendererWorkaround();
game.savestats(); game.savestats();
break; break;
default: default:

View file

@ -231,7 +231,7 @@ void menurender()
graphics.bigprint(-1, 30, "Toggle VSync", tr, tg, tb, true); graphics.bigprint(-1, 30, "Toggle VSync", tr, tg, tb, true);
graphics.Print(-1, 65, "Turn VSync on or off.", tr, tg, tb, true); graphics.Print(-1, 65, "Turn VSync on or off.", tr, tg, tb, true);
if (!graphics.vsync) if (!graphics.screenbuffer->vsync)
{ {
graphics.Print(-1, 95, "Current mode: VSYNC OFF", tr/2, tg/2, tb/2, true); graphics.Print(-1, 95, "Current mode: VSYNC OFF", tr/2, tg/2, tb/2, true);
} }

View file

@ -26,6 +26,7 @@ void Screen::init()
isWindowed = true; isWindowed = true;
stretchMode = 0; stretchMode = 0;
isFiltered = false; isFiltered = false;
vsync = false;
filterSubrect.x = 1; filterSubrect.x = 1;
filterSubrect.y = 1; filterSubrect.y = 1;
filterSubrect.w = 318; filterSubrect.w = 318;
@ -287,3 +288,49 @@ void Screen::toggleLinearFilter()
240 240
); );
} }
void Screen::resetRendererWorkaround()
{
SDL_SetHintWithPriority(
SDL_HINT_RENDER_VSYNC,
vsync ? "1" : "0",
SDL_HINT_OVERRIDE
);
/* FIXME: This exists because SDL_HINT_RENDER_VSYNC is not dynamic!
* As a result, our only workaround is to tear down the renderer
* and recreate everything so that it can process the variable.
* -flibit
*/
if (m_renderer == NULL)
{
/* We haven't made it to init yet, don't worry about it */
return;
}
SDL_RendererInfo renderInfo;
SDL_GetRendererInfo(m_renderer, &renderInfo);
bool curVsync = (renderInfo.flags & SDL_RENDERER_PRESENTVSYNC) != 0;
if (vsync == curVsync)
{
return;
}
SDL_DestroyTexture(m_screenTexture);
SDL_DestroyRenderer(m_renderer);
m_renderer = SDL_CreateRenderer(m_window, -1, 0);
m_screenTexture = SDL_CreateTexture(
m_renderer,
SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STREAMING,
320,
240
);
/* Ugh, have to make sure to re-apply graphics options after doing the
* above, otherwise letterbox/integer won't be applied...
*/
ResizeScreen(-1, -1);
}

View file

@ -20,11 +20,13 @@ public:
void toggleFullScreen(); void toggleFullScreen();
void toggleStretchMode(); void toggleStretchMode();
void toggleLinearFilter(); void toggleLinearFilter();
void resetRendererWorkaround();
bool isWindowed; bool isWindowed;
bool isFiltered; bool isFiltered;
bool badSignalEffect; bool badSignalEffect;
int stretchMode; int stretchMode;
bool vsync;
SDL_Window *m_window; SDL_Window *m_window;
SDL_Renderer *m_renderer; SDL_Renderer *m_renderer;

View file

@ -252,7 +252,7 @@ int main(int argc, char *argv[])
// renderer created by Screen::init(), which is a bit wasteful! // renderer created by Screen::init(), which is a bit wasteful!
// This is annoying to fix because we'd have to call gameScreen.init() after // This is annoying to fix because we'd have to call gameScreen.init() after
// game.loadstats(), but game.loadstats() assumes gameScreen.init() is already called! // game.loadstats(), but game.loadstats() assumes gameScreen.init() is already called!
graphics.processVsync(); gameScreen.resetRendererWorkaround();
if (game.skipfakeload) if (game.skipfakeload)
game.gamestate = TITLEMODE; game.gamestate = TITLEMODE;