diff --git a/desktop_version/src/Game.cpp b/desktop_version/src/Game.cpp index c2074420..2f4097d7 100644 --- a/desktop_version/src/Game.cpp +++ b/desktop_version/src/Game.cpp @@ -4848,7 +4848,7 @@ void Game::loadstats() if (pKey == "vsync") { - graphics.vsync = atoi(pText); + graphics.screenbuffer->vsync = atoi(pText); } if (pKey == "notextoutline") @@ -5118,7 +5118,7 @@ void Game::savestats() dataNode->LinkEndChild(msg); 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); for (size_t i = 0; i < controllerButton_flip.size(); i += 1) diff --git a/desktop_version/src/Graphics.cpp b/desktop_version/src/Graphics.cpp index 95da6806..c81d437c 100644 --- a/desktop_version/src/Graphics.cpp +++ b/desktop_version/src/Graphics.cpp @@ -139,8 +139,6 @@ void Graphics::init() col_tb = 0; kludgeswnlinewidth = false; - - vsync = false; } int Graphics::font_idx(uint32_t ch) { @@ -3273,42 +3271,3 @@ Uint32 Graphics::crewcolourreal(int t) } 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); -} diff --git a/desktop_version/src/Graphics.h b/desktop_version/src/Graphics.h index bf42d562..477523f3 100644 --- a/desktop_version/src/Graphics.h +++ b/desktop_version/src/Graphics.h @@ -326,9 +326,6 @@ public: bool kludgeswnlinewidth; Uint32 crewcolourreal(int t); - - bool vsync; - void processVsync(); }; extern Graphics graphics; diff --git a/desktop_version/src/Input.cpp b/desktop_version/src/Input.cpp index e352e6e0..4183247d 100644 --- a/desktop_version/src/Input.cpp +++ b/desktop_version/src/Input.cpp @@ -369,8 +369,8 @@ void menuactionpress() case 6: //toggle vsync music.playef(11); - graphics.vsync = !graphics.vsync; - graphics.processVsync(); + graphics.screenbuffer->vsync = !graphics.screenbuffer->vsync; + graphics.screenbuffer->resetRendererWorkaround(); game.savestats(); break; default: diff --git a/desktop_version/src/Render.cpp b/desktop_version/src/Render.cpp index 90ed9200..4adfcb2a 100644 --- a/desktop_version/src/Render.cpp +++ b/desktop_version/src/Render.cpp @@ -231,7 +231,7 @@ void menurender() graphics.bigprint(-1, 30, "Toggle VSync", 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); } diff --git a/desktop_version/src/Screen.cpp b/desktop_version/src/Screen.cpp index e8292511..b1c7de8c 100644 --- a/desktop_version/src/Screen.cpp +++ b/desktop_version/src/Screen.cpp @@ -26,6 +26,7 @@ void Screen::init() isWindowed = true; stretchMode = 0; isFiltered = false; + vsync = false; filterSubrect.x = 1; filterSubrect.y = 1; filterSubrect.w = 318; @@ -287,3 +288,49 @@ void Screen::toggleLinearFilter() 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); +} diff --git a/desktop_version/src/Screen.h b/desktop_version/src/Screen.h index ea77a6c4..e29237fd 100644 --- a/desktop_version/src/Screen.h +++ b/desktop_version/src/Screen.h @@ -20,11 +20,13 @@ public: void toggleFullScreen(); void toggleStretchMode(); void toggleLinearFilter(); + void resetRendererWorkaround(); bool isWindowed; bool isFiltered; bool badSignalEffect; int stretchMode; + bool vsync; SDL_Window *m_window; SDL_Renderer *m_renderer; diff --git a/desktop_version/src/main.cpp b/desktop_version/src/main.cpp index 291c6b90..55ea9955 100644 --- a/desktop_version/src/main.cpp +++ b/desktop_version/src/main.cpp @@ -252,7 +252,7 @@ int main(int argc, char *argv[]) // renderer created by Screen::init(), which is a bit wasteful! // 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! - graphics.processVsync(); + gameScreen.resetRendererWorkaround(); if (game.skipfakeload) game.gamestate = TITLEMODE;