diff --git a/src/modules/event/sdl/Event.cpp b/src/modules/event/sdl/Event.cpp index 0aeff94be..bd4c18a35 100644 --- a/src/modules/event/sdl/Event.cpp +++ b/src/modules/event/sdl/Event.cpp @@ -142,6 +142,13 @@ Message *Event::convert(SDL_Event &e) case SDL_QUIT: msg = new Message("quit"); break; + case SDL_VIDEORESIZE: + arg1 = new Variant((double) e.resize.w); + arg2 = new Variant((double) e.resize.h); + msg = new Message("resize", arg1, arg2); + arg1->release(); + arg2->release(); + break; } return msg; diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index 70b55c7d7..a174231cf 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -30,6 +30,8 @@ #include #include +using love::window::WindowFlags; + namespace love { namespace graphics @@ -105,7 +107,7 @@ void Graphics::restoreState(const DisplayState &s) setScissor(); } -bool Graphics::setMode(int width, int height, bool fullscreen, bool vsync, int fsaa) +bool Graphics::setMode(int width, int height, WindowFlags *flags) { // This operation destroys the OpenGL context, so // we must save the state. @@ -117,7 +119,7 @@ bool Graphics::setMode(int width, int height, bool fullscreen, bool vsync, int f // the display mode change. Volatile::unloadAll(); - bool success = currentWindow->setWindow(width, height, fullscreen, vsync, fsaa); + bool success = currentWindow->setWindow(width, height, flags); // Regardless of failure, we'll have to set up OpenGL once again. width = currentWindow->getWidth(); @@ -171,17 +173,18 @@ bool Graphics::setMode(int width, int height, bool fullscreen, bool vsync, int f return success; } -void Graphics::getMode(int &width, int &height, bool &fullscreen, bool &vsync, int &fsaa) +void Graphics::getMode(int &width, int &height, WindowFlags &flags) { - currentWindow->getWindow(width, height, fullscreen, vsync, fsaa); + currentWindow->getWindow(width, height, flags); } bool Graphics::toggleFullscreen() { - int width, height, fsaa; - bool fullscreen, vsync; - currentWindow->getWindow(width, height, fullscreen, vsync, fsaa); - return setMode(width, height, !fullscreen, vsync, fsaa); + int width, height; + WindowFlags flags; + currentWindow->getWindow(width, height, flags); + flags.fullscreen = !flags.fullscreen; + return setMode(width, height, &flags); } diff --git a/src/modules/graphics/opengl/Graphics.h b/src/modules/graphics/opengl/Graphics.h index b7dfa2b1a..e55fdf9d4 100644 --- a/src/modules/graphics/opengl/Graphics.h +++ b/src/modules/graphics/opengl/Graphics.h @@ -46,6 +46,8 @@ #include "Canvas.h" #include "PixelEffect.h" +using love::window::WindowFlags; + namespace love { namespace graphics @@ -128,21 +130,17 @@ public: * Sets the current display mode. * @param width The window width. * @param height The window height. - * @param fullscreen True if fullscreen, false otherwise. - * @param vsync True if we should wait for vsync, false otherwise. - * @param fsaa Number of full scene anti-aliasing buffer, or 0 for disabled. + * @param flags An optional WindowFlags structure. **/ - bool setMode(int width, int height, bool fullscreen, bool vsync, int fsaa); + bool setMode(int width, int height, WindowFlags *flags); /** * Gets the current display mode. * @param width Pointer to an integer for the window width. * @param height Pointer to an integer for the window height. - * @param fullscreen Pointer to a boolean for the fullscreen status. - * @param vsync Pointer to a boolean for the vsync status. - * @param fsaa Pointer to an integer for the current number of full scene anti-aliasing buffers. + * @param flags A WindowFlags structure. **/ - void getMode(int &width, int &height, bool &fullscreen, bool &vsync, int &fsaa); + void getMode(int &width, int &height, WindowFlags &flags); /** * Toggles fullscreen. Note that this also needs to reload the diff --git a/src/modules/graphics/opengl/wrap_Graphics.cpp b/src/modules/graphics/opengl/wrap_Graphics.cpp index d452c22eb..2f1d7c101 100644 --- a/src/modules/graphics/opengl/wrap_Graphics.cpp +++ b/src/modules/graphics/opengl/wrap_Graphics.cpp @@ -27,6 +27,8 @@ #include "scripts/graphics.lua.h" #include +using love::window::WindowFlags; + namespace love { namespace graphics @@ -36,6 +38,34 @@ namespace opengl static Graphics *instance = 0; +bool luax_boolflag(lua_State *L, int table_index, const char *key, bool defaultValue) +{ + lua_getfield(L, table_index, key); + + bool retval; + if (lua_isnoneornil(L, -1)) + retval = defaultValue; + else + retval = lua_toboolean(L, -1); + + lua_pop(L, 1); + return retval; +} + +int luax_intflag(lua_State *L, int table_index, const char *key, int defaultValue) +{ + lua_getfield(L, table_index, key); + + int retval; + if (!lua_isnumber(L, -1)) + retval = defaultValue; + else + retval = lua_tonumber(L, -1); + + lua_pop(L, 1); + return retval; +} + int w_checkMode(lua_State *L) { int w = luaL_checkint(L, 1); @@ -49,24 +79,52 @@ int w_setMode(lua_State *L) { int w = luaL_checkint(L, 1); int h = luaL_checkint(L, 2); - bool fs = luax_optboolean(L, 3, false); - bool vsync = luax_optboolean(L, 4, true); - int fsaa = luaL_optint(L, 5, 0); - luax_pushboolean(L, instance->setMode(w, h, fs, vsync, fsaa)); + if (lua_isnoneornil(L, 3)) + { + luax_pushboolean(L, instance->setMode(w, h, 0)); + return 1; + } + + luaL_checktype(L, 3, LUA_TTABLE); + + WindowFlags flags; + + flags.fullscreen = luax_boolflag(L, 3, "fullscreen", false); + flags.vsync = luax_boolflag(L, 3, "vsync", true); + flags.fsaa = luax_intflag(L, 3, "fsaa", 0); + flags.resizable = luax_boolflag(L, 3, "resizable", false); + flags.borderless = luax_boolflag(L, 3, "borderless", false); + + luax_pushboolean(L, instance->setMode(w, h, &flags)); return 1; } int w_getMode(lua_State *L) { - int w, h, fsaa; - bool fs, vsync; - instance->getMode(w, h, fs, vsync, fsaa); + int w, h; + WindowFlags flags; + instance->getMode(w, h, flags); lua_pushnumber(L, w); lua_pushnumber(L, h); - lua_pushboolean(L, fs); - lua_pushboolean(L, vsync); - lua_pushnumber(L, fsaa); - return 5; + + lua_newtable(L); + + luax_pushboolean(L, flags.fullscreen); + lua_setfield(L, -2, "fullscreen"); + + luax_pushboolean(L, flags.vsync); + lua_setfield(L, -2, "vsync"); + + lua_pushnumber(L, flags.fsaa); + lua_setfield(L, -2, "fsaa"); + + luax_pushboolean(L, flags.resizable); + lua_setfield(L, -2, "resizable"); + + luax_pushboolean(L, flags.borderless); + lua_setfield(L, -2, "borderless"); + + return 3; } int w_toggleFullscreen(lua_State *L) diff --git a/src/modules/window/Window.h b/src/modules/window/Window.h index eadb87254..001c8e50e 100644 --- a/src/modules/window/Window.h +++ b/src/modules/window/Window.h @@ -33,6 +33,15 @@ namespace love namespace window { +struct WindowFlags +{ + bool fullscreen; // = false + bool vsync; // = true + int fsaa; // = 0 + bool resizable; // = false + bool borderless; // = false +}; // WindowFlags + class Window : public Module { public: @@ -44,8 +53,8 @@ public: virtual ~Window(); - virtual bool setWindow(int width = 800, int height = 600, bool fullscreen = false, bool vsync = true, int fsaa = 0) = 0; - virtual void getWindow(int &width, int &height, bool &fullscreen, bool &vsync, int &fsaa) = 0; + virtual bool setWindow(int width, int height, WindowFlags *flags = 0) = 0; + virtual void getWindow(int &width, int &height, WindowFlags &flags) = 0; virtual bool checkWindowSize(int width, int height, bool fullscreen) = 0; virtual WindowSize **getFullscreenSizes(int &n) = 0; diff --git a/src/modules/window/sdl/Window.cpp b/src/modules/window/sdl/Window.cpp index 39e812725..83fcb41f5 100644 --- a/src/modules/window/sdl/Window.cpp +++ b/src/modules/window/sdl/Window.cpp @@ -60,8 +60,23 @@ Window::_currentMode::_currentMode() { } -bool Window::setWindow(int width, int height, bool fullscreen, bool vsync, int fsaa) +bool Window::setWindow(int width, int height, WindowFlags *flags) { + bool fullscreen = false; + bool vsync = true; + int fsaa = 0; + bool resizable = false; + bool borderless = false; + + if (flags) + { + fullscreen = flags->fullscreen; + vsync = flags->vsync; + fsaa = flags->fsaa; + resizable = flags->resizable; + borderless = flags->borderless; + } + bool mouseVisible = getMouseVisible(); // We need to restart the subsystem for two reasons: @@ -104,23 +119,30 @@ bool Window::setWindow(int width, int height, bool fullscreen, bool vsync, int f SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, fsaa); } - // Fullscreen? - Uint32 sdlflags = fullscreen ? (SDL_OPENGL | SDL_FULLSCREEN) : SDL_OPENGL; + Uint32 sdlflags = SDL_OPENGL; + // Flags + if (fullscreen) + sdlflags |= SDL_FULLSCREEN; + if (resizable) + sdlflags |= SDL_RESIZABLE; + if (borderless) + sdlflags |= SDL_NOFRAME; // Have SDL set the video mode. - if (SDL_SetVideoMode(width, height, 32, sdlflags) == 0) + SDL_Surface *surface; + if ((surface = SDL_SetVideoMode(width, height, 32, sdlflags)) == 0) { bool failed = true; if (fsaa > 0) { // FSAA might have failed, disable it and try again SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0); - failed = SDL_SetVideoMode(width, height, 32, sdlflags) == 0; + failed = (surface = SDL_SetVideoMode(width, height, 32, sdlflags)) == 0; if (failed) { // There might be no FSAA at all SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0); - failed = SDL_SetVideoMode(width, height, 32, sdlflags) == 0; + failed = (surface = SDL_SetVideoMode(width, height, 32, sdlflags)) == 0; } } if (failed) @@ -165,17 +187,21 @@ bool Window::setWindow(int width, int height, bool fullscreen, bool vsync, int f currentMode.fsaa = fsaa; currentMode.fullscreen = fullscreen; currentMode.vsync = (real_vsync != 0); + currentMode.resizable = ((surface->flags & SDL_RESIZABLE) != 0); + currentMode.borderless = ((surface->flags & SDL_NOFRAME) != 0); return true; } -void Window::getWindow(int &width, int &height, bool &fullscreen, bool &vsync, int &fsaa) +void Window::getWindow(int &width, int &height, WindowFlags &flags) { width = currentMode.width; height = currentMode.height; - fullscreen = currentMode.fullscreen; - vsync = currentMode.vsync; - fsaa = currentMode.fsaa; + flags.fullscreen = currentMode.fullscreen; + flags.vsync = currentMode.vsync; + flags.fsaa = currentMode.fsaa; + flags.resizable = currentMode.resizable; + flags.borderless = currentMode.borderless; } bool Window::checkWindowSize(int width, int height, bool fullscreen) diff --git a/src/modules/window/sdl/Window.h b/src/modules/window/sdl/Window.h index 52bb9279b..7a47bd689 100644 --- a/src/modules/window/sdl/Window.h +++ b/src/modules/window/sdl/Window.h @@ -37,8 +37,8 @@ public: Window(); ~Window(); - bool setWindow(int width = 800, int height = 600, bool fullscreen = false, bool vsync = true, int fsaa = 0); - void getWindow(int &width, int &height, bool &fullscreen, bool &vsync, int &fsaa); + bool setWindow(int width, int height, WindowFlags *flags = 0); + void getWindow(int &width, int &height, WindowFlags &flags); bool checkWindowSize(int width, int height, bool fullscreen); WindowSize **getFullscreenSizes(int &n); @@ -72,6 +72,8 @@ private: bool fullscreen; bool vsync; int fsaa; + bool resizable; + bool borderless; } currentMode; bool created; bool mouseVisible; diff --git a/src/scripts/boot.lua b/src/scripts/boot.lua index eee219e60..3ddbb93dd 100644 --- a/src/scripts/boot.lua +++ b/src/scripts/boot.lua @@ -179,6 +179,11 @@ function love.createhandlers() quit = function () return end, + resize = function(w, h) + local ow, oh, flags = love.graphics.getMode() + love.graphics.setMode(w, h, flags) + if love.resize then love.resize(w, h) end + end, }, { __index = function(self, name) error("Unknown event: " .. name) @@ -321,7 +326,14 @@ function love.init() -- Setup screen here. if c.screen and c.modules.graphics then if love.graphics.checkMode(c.screen.width, c.screen.height, c.screen.fullscreen) or (c.screen.width == 0 and c.screen.height == 0) then - assert(love.graphics.setMode(c.screen.width, c.screen.height, c.screen.fullscreen, c.screen.vsync, c.screen.fsaa), "Could not set screen mode") + assert(love.graphics.setMode(c.screen.width, c.screen.height, + { + fullscreen = c.screen.fullscreen, + vsync = c.screen.vsync, + fsaa = c.screen.fsaa, + resizable = c.screen.resizable, + borderless = c.screen.borderless, + }), "Could not set screen mode") else error("Could not set screen mode") end diff --git a/src/scripts/boot.lua.h b/src/scripts/boot.lua.h index 8da028949..3aaf84e06 100644 --- a/src/scripts/boot.lua.h +++ b/src/scripts/boot.lua.h @@ -309,6 +309,18 @@ const unsigned char boot_lua[] = 0x28, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a, + 0x09, 0x09, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x77, 0x2c, 0x20, 0x68, 0x29, 0x0a, + 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x77, 0x2c, 0x20, 0x6f, 0x68, 0x2c, 0x20, 0x66, + 0x6c, 0x61, 0x67, 0x73, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, + 0x63, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x28, 0x29, 0x0a, + 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, + 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x28, 0x77, 0x2c, 0x20, 0x68, 0x2c, 0x20, 0x66, 0x6c, 0x61, 0x67, 0x73, + 0x29, 0x0a, + 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x28, 0x77, + 0x2c, 0x20, 0x68, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x09, 0x7d, 0x2c, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x5f, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2c, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, @@ -530,12 +542,22 @@ const unsigned char boot_lua[] = 0x09, 0x09, 0x09, 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x28, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x28, 0x63, 0x2e, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x2e, 0x77, 0x69, 0x64, 0x74, 0x68, 0x2c, 0x20, 0x63, 0x2e, 0x73, 0x63, 0x72, 0x65, - 0x65, 0x6e, 0x2e, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x2c, 0x20, 0x63, 0x2e, 0x73, 0x63, 0x72, 0x65, 0x65, - 0x6e, 0x2e, 0x66, 0x75, 0x6c, 0x6c, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x2c, 0x20, 0x63, 0x2e, 0x73, 0x63, - 0x72, 0x65, 0x65, 0x6e, 0x2e, 0x76, 0x73, 0x79, 0x6e, 0x63, 0x2c, 0x20, 0x63, 0x2e, 0x73, 0x63, 0x72, 0x65, - 0x65, 0x6e, 0x2e, 0x66, 0x73, 0x61, 0x61, 0x29, 0x2c, 0x20, 0x22, 0x43, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6e, - 0x6f, 0x74, 0x20, 0x73, 0x65, 0x74, 0x20, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x6d, 0x6f, 0x64, 0x65, - 0x22, 0x29, 0x0a, + 0x65, 0x6e, 0x2e, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x7b, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x66, 0x75, 0x6c, 0x6c, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x3d, 0x20, 0x63, + 0x2e, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x2e, 0x66, 0x75, 0x6c, 0x6c, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, + 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x76, 0x73, 0x79, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x73, 0x63, 0x72, 0x65, + 0x65, 0x6e, 0x2e, 0x76, 0x73, 0x79, 0x6e, 0x63, 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x66, 0x73, 0x61, 0x61, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x73, 0x63, 0x72, 0x65, 0x65, + 0x6e, 0x2e, 0x66, 0x73, 0x61, 0x61, 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x2e, + 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x2e, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x61, 0x62, 0x6c, 0x65, 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x6c, 0x65, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x63, + 0x2e, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x2e, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x6c, 0x65, 0x73, 0x73, + 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x7d, 0x29, 0x2c, 0x20, 0x22, 0x43, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, + 0x73, 0x65, 0x74, 0x20, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x22, 0x43, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x65, 0x74, 0x20, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x22,