Browse Source

love.graphics object creation functions (love.graphics.new*) now cause an error instead of hard-crashing, if called when the window has not been created yet.

Alex Szpakowski 9 years ago
parent
commit
7c4edf2efc

+ 1 - 1
src/modules/graphics/opengl/Canvas.h

@@ -117,6 +117,7 @@ public:
 		return actual_samples;
 	}
 
+	static Format getSizedFormat(Format format);
 	static bool isSupported();
 	static bool isMultiFormatMultiCanvasSupported();
 	static bool isFormatSupported(Format format);
@@ -143,7 +144,6 @@ private:
 
 	void drawv(const Matrix4 &t, const Vertex *v);
 
-	static Format getSizedFormat(Format format);
 	static void convertFormat(Format format, GLenum &internalformat, GLenum &externalformat, GLenum &type);
 	static size_t getFormatBitsPerPixel(Format format);
 

+ 8 - 5
src/modules/graphics/opengl/Graphics.cpp

@@ -842,11 +842,14 @@ ParticleSystem *Graphics::newParticleSystem(Texture *texture, int size)
 
 Canvas *Graphics::newCanvas(int width, int height, Canvas::Format format, int msaa)
 {
+	if (!Canvas::isSupported())
+		throw love::Exception("Canvases are not supported by your OpenGL drivers!");
+
 	if (!Canvas::isFormatSupported(format))
 	{
 		const char *fstr = "rgba8";
-		Canvas::getConstant(format, fstr);
-		throw love::Exception("The %s canvas format is not supported by your OpenGL implementation.", fstr);
+		Canvas::getConstant(Canvas::getSizedFormat(format), fstr);
+		throw love::Exception("The %s canvas format is not supported by your OpenGL drivers.", fstr);
 	}
 
 	if (width > gl.getMaxTextureSize())
@@ -870,7 +873,7 @@ Canvas *Graphics::newCanvas(int width, int height, Canvas::Format format, int ms
 	switch (err)
 	{
 	case GL_FRAMEBUFFER_UNSUPPORTED:
-		error_string << "Not supported by your OpenGL implementation.";
+		error_string << "Not supported by your OpenGL drivers.";
 		break;
 	case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
 		error_string << "Texture format cannot be rendered to on this system.";
@@ -881,14 +884,14 @@ Canvas *Graphics::newCanvas(int width, int height, Canvas::Format format, int ms
 	case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
 	case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
 	case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
-		error_string << "Error in implementation.";
+		error_string << "Error in graphics driver.";
 		break;
 	default:
 		// my intel hda card wrongly returns 0 to glCheckFramebufferStatus() but sets
 		// no error flag. I think it meant to return GL_FRAMEBUFFER_UNSUPPORTED, but who
 		// knows.
 		if (glGetError() == GL_NO_ERROR)
-			error_string << "May not be supported by your OpenGL implementation.";
+			error_string << "May not be supported by your OpenGL drivers.";
 		// the remaining error is an indication of a serious fuckup since it should
 		// only be returned if glCheckFramebufferStatus() was called with the wrong
 		// arguments.

+ 29 - 0
src/modules/graphics/opengl/wrap_Graphics.cpp

@@ -47,6 +47,13 @@ namespace opengl
 
 #define instance() (Module::getInstance<Graphics>(Module::M_GRAPHICS))
 
+static int luax_checkgraphicscreated(lua_State *L)
+{
+	if (!instance()->isCreated())
+		return luaL_error(L, "love.graphics cannot function without a window!");
+	return 0;
+}
+
 int w_reset(lua_State *)
 {
 	instance()->reset();
@@ -290,6 +297,8 @@ static const char *imageFlagName(Image::FlagType flagtype)
 
 int w_newImage(lua_State *L)
 {
+	luax_checkgraphicscreated(L);
+
 	std::vector<love::image::ImageData *> data;
 	std::vector<love::image::CompressedImageData *> cdata;
 
@@ -400,6 +409,8 @@ int w_newImage(lua_State *L)
 
 int w_newQuad(lua_State *L)
 {
+	luax_checkgraphicscreated(L);
+
 	Quad::Viewport v;
 	v.x = luaL_checknumber(L, 1);
 	v.y = luaL_checknumber(L, 2);
@@ -417,6 +428,8 @@ int w_newQuad(lua_State *L)
 
 int w_newFont(lua_State *L)
 {
+	luax_checkgraphicscreated(L);
+
 	Font *font = nullptr;
 
 	// Convert to Rasterizer, if necessary.
@@ -443,6 +456,8 @@ int w_newFont(lua_State *L)
 
 int w_newImageFont(lua_State *L)
 {
+	luax_checkgraphicscreated(L);
+
 	// filter for glyphs
 	Texture::Filter filter = instance()->getDefaultFilter();
 
@@ -483,6 +498,8 @@ int w_newImageFont(lua_State *L)
 
 int w_newSpriteBatch(lua_State *L)
 {
+	luax_checkgraphicscreated(L);
+
 	Texture *texture = luax_checktexture(L, 1);
 	int size = (int) luaL_optnumber(L, 2, 1000);
 	Mesh::Usage usage = Mesh::USAGE_DYNAMIC;
@@ -505,6 +522,8 @@ int w_newSpriteBatch(lua_State *L)
 
 int w_newParticleSystem(lua_State *L)
 {
+	luax_checkgraphicscreated(L);
+
 	Texture *texture = luax_checktexture(L, 1);
 	lua_Number size = luaL_optnumber(L, 2, 1000);
 	ParticleSystem *t = 0;
@@ -522,6 +541,8 @@ int w_newParticleSystem(lua_State *L)
 
 int w_newCanvas(lua_State *L)
 {
+	luax_checkgraphicscreated(L);
+
 	// check if width and height are given. else default to screen dimensions.
 	int width       = (int) luaL_optnumber(L, 1, instance()->getWidth());
 	int height      = (int) luaL_optnumber(L, 2, instance()->getHeight());
@@ -547,6 +568,8 @@ int w_newCanvas(lua_State *L)
 
 int w_newShader(lua_State *L)
 {
+	luax_checkgraphicscreated(L);
+
 	// clamp stack to 2 elements
 	lua_settop(L, 2);
 
@@ -848,6 +871,8 @@ static Mesh *newCustomMesh(lua_State *L)
 
 int w_newMesh(lua_State *L)
 {
+	luax_checkgraphicscreated(L);
+
 	// Check first argument: table or number of vertices.
 	int arg1type = lua_type(L, 1);
 	if (arg1type != LUA_TTABLE && arg1type != LUA_TNUMBER)
@@ -868,6 +893,8 @@ int w_newMesh(lua_State *L)
 
 int w_newText(lua_State *L)
 {
+	luax_checkgraphicscreated(L);
+
 	Font *font = luax_checkfont(L, 1);
 	Text *t = nullptr;
 
@@ -888,6 +915,8 @@ int w_newText(lua_State *L)
 
 int w_newVideo(lua_State *L)
 {
+	luax_checkgraphicscreated(L);
+
 	if (!luax_istype(L, 1, VIDEO_VIDEO_STREAM_ID))
 		luax_convobj(L, 1, "video", "newVideoStream");
 

+ 3 - 4
src/modules/keyboard/sdl/Keyboard.cpp

@@ -55,6 +55,7 @@ bool Keyboard::isDown(const std::vector<Key> &keylist) const
 	for (Key key : keylist)
 	{
 		SDL_Scancode scancode = SDL_GetScancodeFromKey(keymap[key]);
+
 		if (state[scancode])
 			return true;
 	}
@@ -68,11 +69,9 @@ bool Keyboard::isScancodeDown(const std::vector<Scancode> &scancodelist) const
 
 	for (Scancode scancode : scancodelist)
 	{
-		SDL_Scancode sdlscancode = SDL_SCANCODE_UNKNOWN;
-		if (!scancodes.find(scancode, sdlscancode))
-			continue;
+		SDL_Scancode sdlcode = SDL_SCANCODE_UNKNOWN;
 
-		if (state[sdlscancode])
+		if (scancodes.find(scancode, sdlcode) && state[sdlcode])
 			return true;
 	}