|
@@ -47,11 +47,11 @@ namespace sdl
|
|
{
|
|
{
|
|
|
|
|
|
Window::Window()
|
|
Window::Window()
|
|
- : windowTitle("")
|
|
|
|
- , created(false)
|
|
|
|
|
|
+ : created(false)
|
|
, mouseGrabbed(false)
|
|
, mouseGrabbed(false)
|
|
- , window(0)
|
|
|
|
|
|
+ , window(nullptr)
|
|
, context(nullptr)
|
|
, context(nullptr)
|
|
|
|
+ , displayedWindowError(false)
|
|
, displayedContextError(false)
|
|
, displayedContextError(false)
|
|
{
|
|
{
|
|
if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
|
|
if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
|
|
@@ -75,201 +75,9 @@ Window::~Window()
|
|
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
|
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
|
}
|
|
}
|
|
|
|
|
|
-bool Window::setWindow(int width, int height, WindowSettings *settings)
|
|
|
|
-{
|
|
|
|
- WindowSettings f;
|
|
|
|
-
|
|
|
|
- if (settings)
|
|
|
|
- f = *settings;
|
|
|
|
-
|
|
|
|
- f.minwidth = std::max(f.minwidth, 1);
|
|
|
|
- f.minheight = std::max(f.minheight, 1);
|
|
|
|
-
|
|
|
|
- f.display = std::min(std::max(f.display, 0), getDisplayCount() - 1);
|
|
|
|
-
|
|
|
|
- // Use the desktop resolution if a width or height of 0 is specified.
|
|
|
|
- if (width == 0 || height == 0)
|
|
|
|
- {
|
|
|
|
- SDL_DisplayMode mode = {};
|
|
|
|
- SDL_GetDesktopDisplayMode(f.display, &mode);
|
|
|
|
- width = mode.w;
|
|
|
|
- height = mode.h;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- Uint32 sdlflags = SDL_WINDOW_OPENGL;
|
|
|
|
-
|
|
|
|
- if (f.fullscreen)
|
|
|
|
- {
|
|
|
|
- if (f.fstype == FULLSCREEN_TYPE_DESKTOP)
|
|
|
|
- sdlflags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- sdlflags |= SDL_WINDOW_FULLSCREEN;
|
|
|
|
- SDL_DisplayMode mode = {0, width, height, 0, 0};
|
|
|
|
-
|
|
|
|
- // Fullscreen window creation will bug out if no mode can be used.
|
|
|
|
- if (SDL_GetClosestDisplayMode(f.display, &mode, &mode) == nullptr)
|
|
|
|
- {
|
|
|
|
- // GetClosestDisplayMode will fail if we request a size larger
|
|
|
|
- // than the largest available display mode, so we'll try to use
|
|
|
|
- // the largest (first) mode in that case.
|
|
|
|
- if (SDL_GetDisplayMode(f.display, 0, &mode) < 0)
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- width = mode.w;
|
|
|
|
- height = mode.h;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (f.resizable)
|
|
|
|
- sdlflags |= SDL_WINDOW_RESIZABLE;
|
|
|
|
-
|
|
|
|
- if (f.borderless)
|
|
|
|
- sdlflags |= SDL_WINDOW_BORDERLESS;
|
|
|
|
-
|
|
|
|
- // FIXME: disabled in Linux for runtime SDL 2.0.0 compatibility.
|
|
|
|
-#if SDL_VERSION_ATLEAST(2,0,1) && !defined(LOVE_LINUX)
|
|
|
|
- if (f.highdpi)
|
|
|
|
- sdlflags |= SDL_WINDOW_ALLOW_HIGHDPI;
|
|
|
|
-#endif
|
|
|
|
-
|
|
|
|
- int x = f.x;
|
|
|
|
- int y = f.y;
|
|
|
|
-
|
|
|
|
- if (f.useposition && !f.fullscreen)
|
|
|
|
- {
|
|
|
|
- // The position needs to be in the global coordinate space.
|
|
|
|
- SDL_Rect displaybounds = {};
|
|
|
|
- SDL_GetDisplayBounds(f.display, &displaybounds);
|
|
|
|
- x += displaybounds.x;
|
|
|
|
- y += displaybounds.y;
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- if (f.centered)
|
|
|
|
- x = y = SDL_WINDOWPOS_CENTERED_DISPLAY(f.display);
|
|
|
|
- else
|
|
|
|
- x = y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(f.display);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- graphics::Graphics *gfx = Module::getInstance<graphics::Graphics>(Module::M_GRAPHICS);
|
|
|
|
- if (gfx != nullptr)
|
|
|
|
- gfx->unSetMode();
|
|
|
|
-
|
|
|
|
- // Destroy and recreate the window if the dimensions or flags have changed.
|
|
|
|
- if (window)
|
|
|
|
- {
|
|
|
|
- int curdisplay = SDL_GetWindowDisplayIndex(window);
|
|
|
|
- Uint32 wflags = SDL_GetWindowFlags(window);
|
|
|
|
-
|
|
|
|
- Uint32 testflags = SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN_DESKTOP
|
|
|
|
- | SDL_WINDOW_RESIZABLE | SDL_WINDOW_BORDERLESS;
|
|
|
|
-
|
|
|
|
- // FIXME: disabled in Linux for runtime SDL 2.0.0 compatibility.
|
|
|
|
-#if SDL_VERSION_ATLEAST(2,0,1) && !defined(LOVE_LINUX)
|
|
|
|
- testflags |= SDL_WINDOW_ALLOW_HIGHDPI;
|
|
|
|
-#endif
|
|
|
|
-
|
|
|
|
- wflags &= testflags;
|
|
|
|
-
|
|
|
|
- if (sdlflags != wflags || width != curMode.width || height != curMode.height
|
|
|
|
- || f.display != curdisplay || f.msaa != curMode.settings.msaa || f.sRGB != curMode.settings.sRGB)
|
|
|
|
- {
|
|
|
|
- SDL_DestroyWindow(window);
|
|
|
|
- window = nullptr;
|
|
|
|
-
|
|
|
|
- // The old window may have generated pending events which are no
|
|
|
|
- // longer relevant. Destroy them all!
|
|
|
|
- SDL_FlushEvent(SDL_WINDOWEVENT);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (!window)
|
|
|
|
- {
|
|
|
|
- created = false;
|
|
|
|
-
|
|
|
|
- // In Windows and Linux, some GL attributes are set on window creation.
|
|
|
|
- setGLFramebufferAttributes(f.msaa, f.sRGB);
|
|
|
|
-
|
|
|
|
- const char *title = windowTitle.c_str();
|
|
|
|
- window = SDL_CreateWindow(title, x, y, width, height, sdlflags);
|
|
|
|
-
|
|
|
|
- if (!window && f.msaa > 0)
|
|
|
|
- {
|
|
|
|
- // MSAA might have caused the failure, disable it and try again.
|
|
|
|
- f.msaa = 0;
|
|
|
|
- setGLFramebufferAttributes(f.msaa, f.sRGB);
|
|
|
|
- window = SDL_CreateWindow(title, x, y, width, height, sdlflags);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (!window && f.sRGB)
|
|
|
|
- {
|
|
|
|
- // Same with sRGB support.
|
|
|
|
- f.sRGB = false;
|
|
|
|
- setGLFramebufferAttributes(f.msaa, f.sRGB);
|
|
|
|
- window = SDL_CreateWindow(title, x, y, width, height, sdlflags);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Make sure the window keeps any previously set icon.
|
|
|
|
- if (window && curMode.icon.get())
|
|
|
|
- setIcon(curMode.icon.get());
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (!window)
|
|
|
|
- {
|
|
|
|
- std::cerr << "Could not set video mode: " << SDL_GetError() << std::endl;
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Enforce minimum window dimensions.
|
|
|
|
- SDL_SetWindowMinimumSize(window, f.minwidth, f.minheight);
|
|
|
|
-
|
|
|
|
- if ((f.useposition || f.centered) && !f.fullscreen)
|
|
|
|
- SDL_SetWindowPosition(window, x, y);
|
|
|
|
-
|
|
|
|
- SDL_RaiseWindow(window);
|
|
|
|
-
|
|
|
|
- if (!setContext(f.msaa, f.vsync, f.sRGB))
|
|
|
|
- return false;
|
|
|
|
-
|
|
|
|
- created = true;
|
|
|
|
-
|
|
|
|
- updateSettings(f);
|
|
|
|
-
|
|
|
|
- if (gfx != nullptr)
|
|
|
|
- {
|
|
|
|
- int width = curMode.width;
|
|
|
|
- int height = curMode.height;
|
|
|
|
-
|
|
|
|
- // FIXME: disabled in Linux for runtime SDL 2.0.0 compatibility.
|
|
|
|
-#if SDL_VERSION_ATLEAST(2,0,1) && !defined(LOVE_LINUX)
|
|
|
|
- SDL_GL_GetDrawableSize(window, &width, &height);
|
|
|
|
-#endif
|
|
|
|
-
|
|
|
|
- gfx->setMode(width, height, curMode.settings.sRGB);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Make sure the mouse keeps its previous grab setting.
|
|
|
|
- setMouseGrab(mouseGrabbed);
|
|
|
|
-
|
|
|
|
- return true;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-bool Window::onWindowResize(int width, int height)
|
|
|
|
-{
|
|
|
|
- if (!window)
|
|
|
|
- return false;
|
|
|
|
-
|
|
|
|
- curMode.width = width;
|
|
|
|
- curMode.height = height;
|
|
|
|
-
|
|
|
|
- return true;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
void Window::setGLFramebufferAttributes(int msaa, bool sRGB)
|
|
void Window::setGLFramebufferAttributes(int msaa, bool sRGB)
|
|
{
|
|
{
|
|
- // Set GL window attributes.
|
|
|
|
|
|
+ // Set GL window / framebuffer attributes.
|
|
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
|
|
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
|
|
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
|
|
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
|
|
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
|
|
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
|
|
@@ -278,7 +86,6 @@ void Window::setGLFramebufferAttributes(int msaa, bool sRGB)
|
|
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1);
|
|
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1);
|
|
SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 0);
|
|
SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 0);
|
|
|
|
|
|
- // MSAA.
|
|
|
|
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, (msaa > 0) ? 1 : 0);
|
|
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, (msaa > 0) ? 1 : 0);
|
|
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, (msaa > 0) ? msaa : 0);
|
|
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, (msaa > 0) ? msaa : 0);
|
|
|
|
|
|
@@ -338,21 +145,12 @@ bool Window::checkGLVersion(const ContextAttribs &attribs)
|
|
if (glmajor < attribs.versionMajor
|
|
if (glmajor < attribs.versionMajor
|
|
|| (glmajor == attribs.versionMajor && glminor < attribs.versionMinor))
|
|
|| (glmajor == attribs.versionMajor && glminor < attribs.versionMinor))
|
|
return false;
|
|
return false;
|
|
-
|
|
|
|
|
|
+
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
-bool Window::setContext(int msaa, bool vsync, bool sRGB)
|
|
|
|
|
|
+bool Window::createWindowAndContext(int x, int y, int w, int h, Uint32 windowflags, int msaa, bool sRGB)
|
|
{
|
|
{
|
|
- // We would normally only need to recreate the context if MSAA changes or
|
|
|
|
- // SDL_GL_MakeCurrent is unsuccessful, but in Windows apparently MakeCurrent
|
|
|
|
- // can sometimes claim success but the context will actually be trashed.
|
|
|
|
- if (context)
|
|
|
|
- {
|
|
|
|
- SDL_GL_DeleteContext(context);
|
|
|
|
- context = nullptr;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
bool preferGLES = false;
|
|
bool preferGLES = false;
|
|
|
|
|
|
#ifdef LOVE_GRAPHICS_USE_OPENGLES
|
|
#ifdef LOVE_GRAPHICS_USE_OPENGLES
|
|
@@ -393,30 +191,89 @@ bool Window::setContext(int msaa, bool vsync, bool sRGB)
|
|
if (preferGLES)
|
|
if (preferGLES)
|
|
std::rotate(attribslist.begin(), attribslist.begin() + 1, attribslist.end());
|
|
std::rotate(attribslist.begin(), attribslist.begin() + 1, attribslist.end());
|
|
|
|
|
|
|
|
+ if (context)
|
|
|
|
+ {
|
|
|
|
+ SDL_GL_DeleteContext(context);
|
|
|
|
+ context = nullptr;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ std::string windowerror;
|
|
|
|
+
|
|
|
|
+ // Try each context profile in order.
|
|
for (ContextAttribs attribs : attribslist)
|
|
for (ContextAttribs attribs : attribslist)
|
|
{
|
|
{
|
|
- setGLFramebufferAttributes(msaa, sRGB);
|
|
|
|
|
|
+ // Unfortunately some OpenGL context settings are part of the internal
|
|
|
|
+ // window state in the Windows and Linux SDL backends, so we have to
|
|
|
|
+ // recreate the window when we want to change those settings...
|
|
|
|
+ if (window)
|
|
|
|
+ {
|
|
|
|
+ SDL_DestroyWindow(window);
|
|
|
|
+ SDL_FlushEvent(SDL_WINDOWEVENT);
|
|
|
|
+ window = nullptr;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ int curMSAA = msaa;
|
|
|
|
+ bool curSRGB = sRGB;
|
|
|
|
+
|
|
|
|
+ setGLFramebufferAttributes(curMSAA, curSRGB);
|
|
setGLContextAttributes(attribs);
|
|
setGLContextAttributes(attribs);
|
|
|
|
|
|
|
|
+ window = SDL_CreateWindow(title.c_str(), x, y, w, h, windowflags);
|
|
|
|
+
|
|
|
|
+ if (!window && curMSAA > 0)
|
|
|
|
+ {
|
|
|
|
+ // The MSAA setting could have caused the failure.
|
|
|
|
+ setGLFramebufferAttributes(0, curSRGB);
|
|
|
|
+ window = SDL_CreateWindow(title.c_str(), x, y, w, h, windowflags);
|
|
|
|
+ if (window)
|
|
|
|
+ curMSAA = 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!window && curSRGB)
|
|
|
|
+ {
|
|
|
|
+ // same with sRGB.
|
|
|
|
+ setGLFramebufferAttributes(curMSAA, false);
|
|
|
|
+ window = SDL_CreateWindow(title.c_str(), x, y, w, h, windowflags);
|
|
|
|
+ if (window)
|
|
|
|
+ curSRGB = false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!window && curMSAA > 0 && curSRGB)
|
|
|
|
+ {
|
|
|
|
+ // Or both!
|
|
|
|
+ setGLFramebufferAttributes(0, false);
|
|
|
|
+ window = SDL_CreateWindow(title.c_str(), x, y, w, h, windowflags);
|
|
|
|
+ if (window)
|
|
|
|
+ curSRGB = curMSAA = 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Immediately try the next context profile if window creation failed.
|
|
|
|
+ if (!window)
|
|
|
|
+ {
|
|
|
|
+ windowerror = std::string(SDL_GetError());
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ windowerror.clear();
|
|
|
|
+
|
|
context = SDL_GL_CreateContext(window);
|
|
context = SDL_GL_CreateContext(window);
|
|
|
|
|
|
- if (!context && msaa > 0)
|
|
|
|
|
|
+ if (!context && curMSAA > 0)
|
|
{
|
|
{
|
|
- // MSAA might have caused the failure, disable it and try again.
|
|
|
|
- setGLFramebufferAttributes(0, sRGB);
|
|
|
|
|
|
+ // MSAA and sRGB settings can also cause CreateContext to fail, on
|
|
|
|
+ // certain SDL backends.
|
|
|
|
+ setGLFramebufferAttributes(0, curSRGB);
|
|
context = SDL_GL_CreateContext(window);
|
|
context = SDL_GL_CreateContext(window);
|
|
}
|
|
}
|
|
|
|
|
|
- if (!context && sRGB)
|
|
|
|
|
|
+ if (!context && curSRGB)
|
|
{
|
|
{
|
|
- // Or maybe sRGB isn't supported.
|
|
|
|
- setGLFramebufferAttributes(msaa, false);
|
|
|
|
|
|
+ setGLFramebufferAttributes(curMSAA, false);
|
|
context = SDL_GL_CreateContext(window);
|
|
context = SDL_GL_CreateContext(window);
|
|
}
|
|
}
|
|
|
|
|
|
- if (!context && msaa > 0 && sRGB)
|
|
|
|
|
|
+ if (!context && curMSAA > 0 && curSRGB)
|
|
{
|
|
{
|
|
- // Or both are an issue!
|
|
|
|
setGLFramebufferAttributes(0, false);
|
|
setGLFramebufferAttributes(0, false);
|
|
context = SDL_GL_CreateContext(window);
|
|
context = SDL_GL_CreateContext(window);
|
|
}
|
|
}
|
|
@@ -439,41 +296,202 @@ bool Window::setContext(int msaa, bool vsync, bool sRGB)
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
- if (!context)
|
|
|
|
|
|
+ if (!context || !window)
|
|
{
|
|
{
|
|
- std::string title = "Unable to initialize OpenGL";
|
|
|
|
- std::string message = "This program requires a graphics card and video drivers which support OpenGL 2.1 or OpenGL ES 2.";
|
|
|
|
|
|
+ if (!windowerror.empty())
|
|
|
|
+ {
|
|
|
|
+ std::string title = "Unable to create window";
|
|
|
|
+ std::string message = "SDL error: " + windowerror;
|
|
|
|
|
|
- std::cerr << title << std::endl << message << std::endl;
|
|
|
|
|
|
+ std::cerr << title << std::endl << message << std::endl;
|
|
|
|
|
|
- // Display a message box with the error, but only once.
|
|
|
|
- if (!displayedContextError)
|
|
|
|
|
|
+ // Display a message box with the error, but only once.
|
|
|
|
+ if (!displayedWindowError)
|
|
|
|
+ {
|
|
|
|
+ showMessageBox(title, message, MESSAGEBOX_ERROR, false);
|
|
|
|
+ displayedWindowError = true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else if (!context)
|
|
{
|
|
{
|
|
- showMessageBox(title, message, MESSAGEBOX_ERROR, true);
|
|
|
|
- displayedContextError = true;
|
|
|
|
|
|
+ std::string title = "Unable to initialize OpenGL";
|
|
|
|
+ std::string message = "This program requires a graphics card and video drivers which support OpenGL 2.1 or OpenGL ES 2.";
|
|
|
|
+
|
|
|
|
+ std::cerr << title << std::endl << message << std::endl;
|
|
|
|
+
|
|
|
|
+ // Display a message box with the error, but only once.
|
|
|
|
+ if (!displayedContextError)
|
|
|
|
+ {
|
|
|
|
+ showMessageBox(title, message, MESSAGEBOX_ERROR, true);
|
|
|
|
+ displayedContextError = true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (context)
|
|
|
|
+ {
|
|
|
|
+ SDL_GL_DeleteContext(context);
|
|
|
|
+ context = nullptr;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (window)
|
|
|
|
+ {
|
|
|
|
+ SDL_DestroyWindow(window);
|
|
|
|
+ SDL_FlushEvent(SDL_WINDOWEVENT);
|
|
|
|
+ window = nullptr;
|
|
}
|
|
}
|
|
|
|
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
|
|
- // Set vertical synchronization.
|
|
|
|
- SDL_GL_SetSwapInterval(vsync ? 1 : 0);
|
|
|
|
|
|
+bool Window::setWindow(int width, int height, WindowSettings *settings)
|
|
|
|
+{
|
|
|
|
+ WindowSettings f;
|
|
|
|
|
|
- // Verify MSAA setting.
|
|
|
|
- int buffers;
|
|
|
|
- int samples;
|
|
|
|
- SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &buffers);
|
|
|
|
- SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &samples);
|
|
|
|
|
|
+ if (settings)
|
|
|
|
+ f = *settings;
|
|
|
|
+
|
|
|
|
+ f.minwidth = std::max(f.minwidth, 1);
|
|
|
|
+ f.minheight = std::max(f.minheight, 1);
|
|
|
|
+
|
|
|
|
+ f.display = std::min(std::max(f.display, 0), getDisplayCount() - 1);
|
|
|
|
|
|
- // Don't fail because of this, but issue a warning.
|
|
|
|
- if ((!buffers && msaa > 0) || (samples != msaa))
|
|
|
|
|
|
+ // Use the desktop resolution if a width or height of 0 is specified.
|
|
|
|
+ if (width == 0 || height == 0)
|
|
{
|
|
{
|
|
- std::cerr << "Warning, MSAA setting failed! (Result: " << samples << "x MSAA)" << std::endl;
|
|
|
|
- msaa = (buffers > 0) ? samples : 0;
|
|
|
|
|
|
+ SDL_DisplayMode mode = {};
|
|
|
|
+ SDL_GetDesktopDisplayMode(f.display, &mode);
|
|
|
|
+ width = mode.w;
|
|
|
|
+ height = mode.h;
|
|
}
|
|
}
|
|
|
|
|
|
- curMode.settings.msaa = msaa;
|
|
|
|
- curMode.settings.vsync = SDL_GL_GetSwapInterval() != 0;
|
|
|
|
|
|
+ Uint32 sdlflags = SDL_WINDOW_OPENGL;
|
|
|
|
+
|
|
|
|
+ if (f.fullscreen)
|
|
|
|
+ {
|
|
|
|
+ if (f.fstype == FULLSCREEN_TYPE_DESKTOP)
|
|
|
|
+ sdlflags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ sdlflags |= SDL_WINDOW_FULLSCREEN;
|
|
|
|
+ SDL_DisplayMode mode = {0, width, height, 0, 0};
|
|
|
|
+
|
|
|
|
+ // Fullscreen window creation will bug out if no mode can be used.
|
|
|
|
+ if (SDL_GetClosestDisplayMode(f.display, &mode, &mode) == nullptr)
|
|
|
|
+ {
|
|
|
|
+ // GetClosestDisplayMode will fail if we request a size larger
|
|
|
|
+ // than the largest available display mode, so we'll try to use
|
|
|
|
+ // the largest (first) mode in that case.
|
|
|
|
+ if (SDL_GetDisplayMode(f.display, 0, &mode) < 0)
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ width = mode.w;
|
|
|
|
+ height = mode.h;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (f.resizable)
|
|
|
|
+ sdlflags |= SDL_WINDOW_RESIZABLE;
|
|
|
|
+
|
|
|
|
+ if (f.borderless)
|
|
|
|
+ sdlflags |= SDL_WINDOW_BORDERLESS;
|
|
|
|
+
|
|
|
|
+ // FIXME: disabled in Linux for runtime SDL 2.0.0 compatibility.
|
|
|
|
+#if SDL_VERSION_ATLEAST(2,0,1) && !defined(LOVE_LINUX)
|
|
|
|
+ if (f.highdpi)
|
|
|
|
+ sdlflags |= SDL_WINDOW_ALLOW_HIGHDPI;
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+ int x = f.x;
|
|
|
|
+ int y = f.y;
|
|
|
|
+
|
|
|
|
+ if (f.useposition && !f.fullscreen)
|
|
|
|
+ {
|
|
|
|
+ // The position needs to be in the global coordinate space.
|
|
|
|
+ SDL_Rect displaybounds = {};
|
|
|
|
+ SDL_GetDisplayBounds(f.display, &displaybounds);
|
|
|
|
+ x += displaybounds.x;
|
|
|
|
+ y += displaybounds.y;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ if (f.centered)
|
|
|
|
+ x = y = SDL_WINDOWPOS_CENTERED_DISPLAY(f.display);
|
|
|
|
+ else
|
|
|
|
+ x = y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(f.display);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ graphics::Graphics *gfx = Module::getInstance<graphics::Graphics>(Module::M_GRAPHICS);
|
|
|
|
+ if (gfx != nullptr)
|
|
|
|
+ gfx->unSetMode();
|
|
|
|
+
|
|
|
|
+ if (context)
|
|
|
|
+ {
|
|
|
|
+ SDL_GL_DeleteContext(context);
|
|
|
|
+ context = nullptr;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (window)
|
|
|
|
+ {
|
|
|
|
+ SDL_DestroyWindow(window);
|
|
|
|
+ window = nullptr;
|
|
|
|
+
|
|
|
|
+ // The old window may have generated pending events which are no longer
|
|
|
|
+ // relevant. Destroy them all!
|
|
|
|
+ SDL_FlushEvent(SDL_WINDOWEVENT);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ created = false;
|
|
|
|
+
|
|
|
|
+ if (!createWindowAndContext(x, y, width, height, sdlflags, f.msaa, f.sRGB))
|
|
|
|
+ return false;
|
|
|
|
+
|
|
|
|
+ created = true;
|
|
|
|
+
|
|
|
|
+ // Make sure the window keeps any previously set icon.
|
|
|
|
+ setIcon(curMode.icon.get());
|
|
|
|
+
|
|
|
|
+ // Make sure the mouse keeps its previous grab setting.
|
|
|
|
+ setMouseGrab(mouseGrabbed);
|
|
|
|
+
|
|
|
|
+ // Enforce minimum window dimensions.
|
|
|
|
+ SDL_SetWindowMinimumSize(window, f.minwidth, f.minheight);
|
|
|
|
+
|
|
|
|
+ if ((f.useposition || f.centered) && !f.fullscreen)
|
|
|
|
+ SDL_SetWindowPosition(window, x, y);
|
|
|
|
+
|
|
|
|
+ SDL_RaiseWindow(window);
|
|
|
|
+
|
|
|
|
+ SDL_GL_SetSwapInterval(f.vsync ? 1 : 0);
|
|
|
|
+
|
|
|
|
+ updateSettings(f);
|
|
|
|
+
|
|
|
|
+ if (gfx != nullptr)
|
|
|
|
+ {
|
|
|
|
+ int width = curMode.width;
|
|
|
|
+ int height = curMode.height;
|
|
|
|
+
|
|
|
|
+ // FIXME: disabled in Linux for runtime SDL 2.0.0 compatibility.
|
|
|
|
+#if SDL_VERSION_ATLEAST(2,0,1) && !defined(LOVE_LINUX)
|
|
|
|
+ SDL_GL_GetDrawableSize(window, &width, &height);
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+ gfx->setMode(width, height, curMode.settings.sRGB);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+bool Window::onWindowResize(int width, int height)
|
|
|
|
+{
|
|
|
|
+ if (!window)
|
|
|
|
+ return false;
|
|
|
|
+
|
|
|
|
+ curMode.width = width;
|
|
|
|
+ curMode.height = height;
|
|
|
|
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
@@ -531,6 +549,15 @@ void Window::updateSettings(const WindowSettings &newsettings)
|
|
|
|
|
|
curMode.settings.sRGB = newsettings.sRGB;
|
|
curMode.settings.sRGB = newsettings.sRGB;
|
|
|
|
|
|
|
|
+ // Verify MSAA setting.
|
|
|
|
+ int buffers = 0;
|
|
|
|
+ int samples = 0;
|
|
|
|
+ SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &buffers);
|
|
|
|
+ SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &samples);
|
|
|
|
+
|
|
|
|
+ curMode.settings.msaa = (buffers > 0 ? samples : 0);
|
|
|
|
+ curMode.settings.vsync = SDL_GL_GetSwapInterval() != 0;
|
|
|
|
+
|
|
SDL_DisplayMode dmode = {};
|
|
SDL_DisplayMode dmode = {};
|
|
SDL_GetCurrentDisplayMode(curMode.settings.display, &dmode);
|
|
SDL_GetCurrentDisplayMode(curMode.settings.display, &dmode);
|
|
|
|
|
|
@@ -712,7 +739,7 @@ bool Window::isCreated() const
|
|
|
|
|
|
void Window::setWindowTitle(const std::string &title)
|
|
void Window::setWindowTitle(const std::string &title)
|
|
{
|
|
{
|
|
- windowTitle = title;
|
|
|
|
|
|
+ this->title = title;
|
|
|
|
|
|
if (window)
|
|
if (window)
|
|
SDL_SetWindowTitle(window, title.c_str());
|
|
SDL_SetWindowTitle(window, title.c_str());
|
|
@@ -720,7 +747,7 @@ void Window::setWindowTitle(const std::string &title)
|
|
|
|
|
|
const std::string &Window::getWindowTitle() const
|
|
const std::string &Window::getWindowTitle() const
|
|
{
|
|
{
|
|
- return windowTitle;
|
|
|
|
|
|
+ return title;
|
|
}
|
|
}
|
|
|
|
|
|
bool Window::setIcon(love::image::ImageData *imgd)
|
|
bool Window::setIcon(love::image::ImageData *imgd)
|