Bart van Strien avatar Bart van Strien committed 9a6a533

Use a flags table for setMode now, implement resizable and borderless windows, and add resize event

Example setMode invocation: love.graphics.setMode(800, 600, {fullscreen = false, vsync = true, borderless = true})
t.screen.resizable and t.screen.borderless are available in love.conf
And love.resize(w, h) gets called if it exists on a resize event.
NOTE: love.handlers.resize(w, h) does the required setMode, but that does mean a visual reload

Comments (0)

Files changed (9)

src/modules/event/sdl/Event.cpp

 	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;

src/modules/graphics/opengl/Graphics.cpp

 #include <algorithm>
 #include <iterator>
 
+using love::window::WindowFlags;
+
 namespace love
 {
 namespace graphics
 		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.
 	// 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();
 	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);
 }
 
 

src/modules/graphics/opengl/Graphics.h

 #include "Canvas.h"
 #include "PixelEffect.h"
 
+using love::window::WindowFlags;
+
 namespace love
 {
 namespace graphics
 	 * 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

src/modules/graphics/opengl/wrap_Graphics.cpp

 #include "scripts/graphics.lua.h"
 #include <cassert>
 
+using love::window::WindowFlags;
+
 namespace love
 {
 namespace graphics
 
 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);
 {
 	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)

src/modules/window/Window.h

 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:
 
 	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;

src/modules/window/sdl/Window.cpp

 {
 }
 
-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:
 		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)
 	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)

src/modules/window/sdl/Window.h

 	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);
 		bool fullscreen;
 		bool vsync;
 		int fsaa;
+		bool resizable;
+		bool borderless;
 	} currentMode;
 	bool created;
 	bool mouseVisible;

src/scripts/boot.lua

 		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)
 	-- 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

src/scripts/boot.lua.h

 	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,
 	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, 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.