Browse Source

readded support for screenshots - love.graphics.newScreenshot() returns ImageData that can be manipulated as one pleases

bill@Ixion 16 years ago
parent
commit
cece5fe625

+ 0 - 1
platform/macosx/love.xcodeproj/project.pbxproj

@@ -1882,7 +1882,6 @@
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
 				HEADER_SEARCH_PATHS = (
 				HEADER_SEARCH_PATHS = (
-					/usr/local/include/IL,
 					/Library/Frameworks/SDL.framework/Headers,
 					/Library/Frameworks/SDL.framework/Headers,
 					/usr/local/include,
 					/usr/local/include,
 					/opt/local/include,
 					/opt/local/include,

+ 144 - 111
src/modules/graphics/opengl/Graphics.cpp

@@ -1,27 +1,31 @@
-/**
-* Copyright (c) 2006-2009 LOVE Development Team
-* 
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* 
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
+/**
+* Copyright (c) 2006-2009 LOVE Development Team
+* 
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* 
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 
+* 1. The origin of this software must not be misrepresented; you must not
+*    claim that you wrote the original software. If you use this software
+*    in a product, an acknowledgment in the product documentation would be
+*    appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+*    misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
 **/
 **/
 
 
 #include "Graphics.h"
 #include "Graphics.h"
 
 
 // LOVE
 // LOVE
 #include <common/config.h>
 #include <common/config.h>
+#include <image/devil/Image.h>
+
+// IL
+#include <IL/ilu.h>
 
 
 namespace love
 namespace love
 {
 {
@@ -33,9 +37,9 @@ namespace opengl
 	Graphics::Graphics()
 	Graphics::Graphics()
 		: currentFont(0)
 		: currentFont(0)
 	{
 	{
-		// Indicates that there is no screen
-		// created yet.
-		currentMode.width = 0;
+		// Indicates that there is no screen
+		// created yet.
+		currentMode.width = 0;
 		currentMode.height = 0;
 		currentMode.height = 0;
 
 
 		// Windows should be centered.
 		// Windows should be centered.
@@ -47,7 +51,7 @@ namespace opengl
 
 
 	Graphics::~Graphics()
 	Graphics::~Graphics()
 	{
 	{
-		if(currentFont != 0)
+		if(currentFont != 0)
 			currentFont->release();
 			currentFont->release();
 
 
 		SDL_QuitSubSystem(SDL_INIT_VIDEO);
 		SDL_QuitSubSystem(SDL_INIT_VIDEO);
@@ -66,8 +70,8 @@ namespace opengl
 		int bpp = SDL_VideoModeOK(width, height, 32, sdlflags);
 		int bpp = SDL_VideoModeOK(width, height, 32, sdlflags);
 
 
 		return (bpp >= 16);	
 		return (bpp >= 16);	
-	}
-
+	}
+
 	DisplayState Graphics::saveState()
 	DisplayState Graphics::saveState()
 	{
 	{
 		DisplayState s;
 		DisplayState s;
@@ -117,7 +121,7 @@ namespace opengl
 		if (s.scissor)
 		if (s.scissor)
 			glGetIntegerv(GL_SCISSOR_BOX, s.scissorBox);
 			glGetIntegerv(GL_SCISSOR_BOX, s.scissorBox);
 		return s;
 		return s;
-	}
+	}
 
 
 	void Graphics::restoreState(const DisplayState & s)
 	void Graphics::restoreState(const DisplayState & s)
 	{
 	{
@@ -135,8 +139,8 @@ namespace opengl
 			setScissor(s.scissorBox[0], s.scissorBox[1], s.scissorBox[2], s.scissorBox[3]);
 			setScissor(s.scissorBox[0], s.scissorBox[1], s.scissorBox[2], s.scissorBox[3]);
 		else
 		else
 			setScissor();
 			setScissor();
-	}
-
+	}
+
 	bool Graphics::setMode(int width, int height, bool fullscreen, bool vsync, int fsaa)
 	bool Graphics::setMode(int width, int height, bool fullscreen, bool vsync, int fsaa)
 	{
 	{
 		// This operation destroys the OpenGL context, so
 		// This operation destroys the OpenGL context, so
@@ -257,8 +261,8 @@ namespace opengl
 		restoreState(tempState);
 		restoreState(tempState);
 
 
 		return true;
 		return true;
-	}
-
+	}
+
 	bool Graphics::toggleFullscreen()
 	bool Graphics::toggleFullscreen()
 	{
 	{
 		// Try to do the change.
 		// Try to do the change.
@@ -271,8 +275,8 @@ namespace opengl
 		currentMode.fullscreen = !currentMode.fullscreen;
 		currentMode.fullscreen = !currentMode.fullscreen;
 		return true;
 		return true;
 	}
 	}
-
-
+
+
 	void Graphics::reset()
 	void Graphics::reset()
 	{
 	{
 		DisplayState s;
 		DisplayState s;
@@ -288,21 +292,21 @@ namespace opengl
 	void Graphics::present()
 	void Graphics::present()
 	{
 	{
 		SDL_GL_SwapBuffers();
 		SDL_GL_SwapBuffers();
-	}
-
+	}
+
 	void Graphics::setCaption(const char * caption)
 	void Graphics::setCaption(const char * caption)
 	{
 	{
 		SDL_WM_SetCaption(caption, 0);
 		SDL_WM_SetCaption(caption, 0);
 	}
 	}
 
 
-	int Graphics::getCaption(lua_State * L)
-	{
+	int Graphics::getCaption(lua_State * L)
+	{
 		char * title = 0;
 		char * title = 0;
-		SDL_WM_GetCaption(&title, 0);
-		lua_pushstring(L, title);
-		return 1;
-	}
-
+		SDL_WM_GetCaption(&title, 0);
+		lua_pushstring(L, title);
+		return 1;
+	}
+
 	int Graphics::getWidth()
 	int Graphics::getWidth()
 	{
 	{
 		return currentMode.width;
 		return currentMode.width;
@@ -379,19 +383,24 @@ namespace opengl
 		lua_pushnumber(L, scissor[3]);
 		lua_pushnumber(L, scissor[3]);
 
 
 		return 4;
 		return 4;
-	}
-
+	}
+
 	Image * Graphics::newImage(love::image::ImageData * data)
 	Image * Graphics::newImage(love::image::ImageData * data)
 	{
 	{
 		// Create the image.
 		// Create the image.
 		Image * image = new Image(data);
 		Image * image = new Image(data);
-
-		if(!image->load())
-		{
+		bool success;
+		try {
+			success = image->load();
+		} catch (love::Exception & e) {
+			image->release();
+			throw love::Exception(e.what());
+		}
+		if (!success) {
 			image->release();
 			image->release();
 			return 0;
 			return 0;
 		}
 		}
-
+		
 		return image;
 		return image;
 	}
 	}
 	
 	
@@ -403,10 +412,10 @@ namespace opengl
 		v.w = w;
 		v.w = w;
 		v.h = h;
 		v.h = h;
 		return new Quad(v, sw, sh);
 		return new Quad(v, sw, sh);
-	}
-
-	Font * Graphics::newFont(Data * data, int size)
-	{
+	}
+
+	Font * Graphics::newFont(Data * data, int size)
+	{
 		Font * font = new TrueTypeFont(data, size);
 		Font * font = new TrueTypeFont(data, size);
 
 
 		// Load it and check for errors.
 		// Load it and check for errors.
@@ -416,11 +425,11 @@ namespace opengl
 			return 0;
 			return 0;
 		}
 		}
 
 
-		return font;
-	}
-
-	Font * Graphics::newImageFont(Image * image, const char * glyphs, float spacing)
-	{
+		return font;
+	}
+
+	Font * Graphics::newImageFont(Image * image, const char * glyphs, float spacing)
+	{
 		Font * font = new ImageFont(image, std::string(glyphs));
 		Font * font = new ImageFont(image, std::string(glyphs));
 
 
 		// Load it and check for errors.
 		// Load it and check for errors.
@@ -430,19 +439,19 @@ namespace opengl
 			return 0;
 			return 0;
 		}
 		}
 
 
-		return font;
-	}
-
-	SpriteBatch * Graphics::newSpriteBatch(Image * image, int size, int usage)
-	{
-		return new SpriteBatch(image, size, usage);
-	}
-
-	ParticleSystem * Graphics::newParticleSystem(Image * image, int size)
-	{
-		return new ParticleSystem(image, size);
-	}
-
+		return font;
+	}
+
+	SpriteBatch * Graphics::newSpriteBatch(Image * image, int size, int usage)
+	{
+		return new SpriteBatch(image, size, usage);
+	}
+
+	ParticleSystem * Graphics::newParticleSystem(Image * image, int size)
+	{
+		return new ParticleSystem(image, size);
+	}
+
 	void Graphics::setColor(Color c)
 	void Graphics::setColor(Color c)
 	{
 	{
 		glColor4ubv(&c.r);
 		glColor4ubv(&c.r);
@@ -479,33 +488,33 @@ namespace opengl
 		t.a = (unsigned char)(255.0f*c[3]);
 		t.a = (unsigned char)(255.0f*c[3]);
 
 
 		return t;
 		return t;
-	}
-
+	}
+
 	void Graphics::setFont( Font * font )
 	void Graphics::setFont( Font * font )
 	{
 	{
-		if(currentFont != 0)
-			currentFont->release();
+		if(currentFont != 0)
+			currentFont->release();
 
 
 		currentFont = font;
 		currentFont = font;
 
 
 		if(font != 0)
 		if(font != 0)
 			currentFont->retain();
 			currentFont->retain();
-	}
-
-	void Graphics::setFont( Data * data, int size )
-	{
-		if(currentFont != 0)
-			currentFont->release();
-
-		currentFont = new TrueTypeFont(data, size);
-		currentFont->load();
-	}
-
-	Font * Graphics::getFont()
-	{
-		return currentFont;
-	}
-
+	}
+
+	void Graphics::setFont( Data * data, int size )
+	{
+		if(currentFont != 0)
+			currentFont->release();
+
+		currentFont = new TrueTypeFont(data, size);
+		currentFont->load();
+	}
+
+	Font * Graphics::getFont()
+	{
+		return currentFont;
+	}
+
 	void Graphics::setBlendMode( int mode )
 	void Graphics::setBlendMode( int mode )
 	{
 	{
 		if(mode == BLEND_ADDITIVE)
 		if(mode == BLEND_ADDITIVE)
@@ -659,8 +668,8 @@ namespace opengl
 		GLint max;
 		GLint max;
 		glGetIntegerv(GL_POINT_SIZE_MAX, &max);
 		glGetIntegerv(GL_POINT_SIZE_MAX, &max);
 		return (int)max;
 		return (int)max;
-	}
-
+	}
+
 	void Graphics::print( const char * str, float x, float y )
 	void Graphics::print( const char * str, float x, float y )
 	{
 	{
 		if(currentFont != 0)
 		if(currentFont != 0)
@@ -814,8 +823,8 @@ namespace opengl
 				}
 				}
 			} 
 			} 
 		}
 		}
-	}
-
+	}
+
 	/**
 	/**
 	* Primitives
 	* Primitives
 	**/
 	**/
@@ -1168,8 +1177,32 @@ namespace opengl
 		return 0;
 		return 0;
 	}
 	}
 
 
-	bool Graphics::screenshot(love::filesystem::File * file)
+	love::image::ImageData * Graphics::newScreenshot(lua_State * L)
 	{
 	{
+		
+		int w = getWidth();
+		int h = getHeight();
+		
+		love::image::devil::Image * i = new love::image::devil::Image();
+		love::image::ImageData * img = i->newImageData(w, h);
+		
+		GLubyte * pixels = new GLubyte[4*w*h];
+		
+		glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+		
+		try {
+			img = i->newImageData(w, h, pixels);
+		} catch (Exception & e) {
+			luaL_error(L, e.what());
+		}
+		
+		// the screenshot is upside down, let's fix this
+		iluFlipImage();
+		
+		delete [] pixels;
+		
+		return img;
+		
 		// TODO: update this.
 		// TODO: update this.
 		/*
 		/*
 		int w = getWidth();
 		int w = getWidth();
@@ -1233,31 +1266,31 @@ namespace opengl
 	void Graphics::translate(float x, float y)
 	void Graphics::translate(float x, float y)
 	{
 	{
 		glTranslatef(x, y, 0);
 		glTranslatef(x, y, 0);
-	}
-
-	void Graphics::drawTest(Image * image, float x, float y, float a, float sx, float sy, float ox, float oy)
-	{
-		image->bind();
-
-		// Buffer for transforming the image.
-		vertex buf[4];
-
-		Matrix t;
-		t.translate(x, y);
-		t.rotate(a);
-		t.scale(sx, sy);
-		t.translate(ox, oy);
+	}
+
+	void Graphics::drawTest(Image * image, float x, float y, float a, float sx, float sy, float ox, float oy)
+	{
+		image->bind();
+
+		// Buffer for transforming the image.
+		vertex buf[4];
+
+		Matrix t;
+		t.translate(x, y);
+		t.rotate(a);
+		t.scale(sx, sy);
+		t.translate(ox, oy);
 		t.transform(buf, image->getVertices(), 4);
 		t.transform(buf, image->getVertices(), 4);
 
 
 		const vertex * vertices = image->getVertices();
 		const vertex * vertices = image->getVertices();
 
 
 		glEnableClientState(GL_VERTEX_ARRAY);
 		glEnableClientState(GL_VERTEX_ARRAY);
-		glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+		glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 		glVertexPointer(2, GL_FLOAT, sizeof(vertex), (GLvoid*)&buf[0].x);
 		glVertexPointer(2, GL_FLOAT, sizeof(vertex), (GLvoid*)&buf[0].x);
-		glTexCoordPointer(2, GL_FLOAT, sizeof(vertex), (GLvoid*)&vertices[0].s);
-		glDrawArrays(GL_QUADS, 0, 4);
+		glTexCoordPointer(2, GL_FLOAT, sizeof(vertex), (GLvoid*)&vertices[0].s);
+		glDrawArrays(GL_QUADS, 0, 4);
 		glDisableClientState(GL_TEXTURE_COORD_ARRAY);
 		glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-		glDisableClientState(GL_VERTEX_ARRAY);
+		glDisableClientState(GL_VERTEX_ARRAY);
 	}
 	}
 
 
 } // opengl
 } // opengl

+ 32 - 30
src/modules/graphics/opengl/Graphics.h

@@ -1,28 +1,28 @@
-/**
-* Copyright (c) 2006-2009 LOVE Development Team
-* 
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* 
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
+/**
+* Copyright (c) 2006-2009 LOVE Development Team
+* 
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* 
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 
+* 1. The origin of this software must not be misrepresented; you must not
+*    claim that you wrote the original software. If you use this software
+*    in a product, an acknowledgment in the product documentation would be
+*    appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+*    misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
 **/
 **/
 
 
 #ifndef LOVE_GRAPHICS_OPENGL_GRAPHICS_H
 #ifndef LOVE_GRAPHICS_OPENGL_GRAPHICS_H
 #define LOVE_GRAPHICS_OPENGL_GRAPHICS_H
 #define LOVE_GRAPHICS_OPENGL_GRAPHICS_H
 
 
-// STD
-#include <iostream>
+// STD
+#include <iostream>
 #include <cmath>
 #include <cmath>
 
 
 // SDL
 // SDL
@@ -31,10 +31,12 @@
 #include <SDL_opengl.h>
 #include <SDL_opengl.h>
 
 
 // LOVE
 // LOVE
-#include <graphics/Graphics.h>
-
-#include "Image.h"
-#include "TrueTypeFont.h"
+#include <graphics/Graphics.h>
+
+#include <image/ImageData.h>
+
+#include "Image.h"
+#include "TrueTypeFont.h"
 #include "ImageFont.h"
 #include "ImageFont.h"
 #include "Quad.h"
 #include "Quad.h"
 #include "SpriteBatch.h"
 #include "SpriteBatch.h"
@@ -125,7 +127,7 @@ namespace opengl
 		
 		
 		// Implements Module.
 		// Implements Module.
 		const char * getName() const;
 		const char * getName() const;
-
+
 		/**
 		/**
 		* Checks whether a display mode is supported or not. Note
 		* Checks whether a display mode is supported or not. Note
 		* that fullscreen is assumed, because windowed modes are
 		* that fullscreen is assumed, because windowed modes are
@@ -134,8 +136,8 @@ namespace opengl
 		* @param height The window height.
 		* @param height The window height.
 		**/
 		**/
 		bool checkMode(int width, int height, bool fullscreen);
 		bool checkMode(int width, int height, bool fullscreen);
-
-		DisplayState saveState();
+
+		DisplayState saveState();
 
 
 		void restoreState(const DisplayState & s);
 		void restoreState(const DisplayState & s);
 
 
@@ -516,14 +518,14 @@ namespace opengl
 		* Creates a screenshot of the view and saves it to the default folder.
 		* Creates a screenshot of the view and saves it to the default folder.
 		* @param file The file to write the screenshot to.
 		* @param file The file to write the screenshot to.
 		**/
 		**/
-		bool screenshot(love::filesystem::File * file);
+		love::image::ImageData * newScreenshot(lua_State * L);
 
 
 		void push();
 		void push();
 		void pop();
 		void pop();
 		void rotate(float r);
 		void rotate(float r);
 		void scale(float x, float y = 1.0f);
 		void scale(float x, float y = 1.0f);
-		void translate(float x, float y);
-
+		void translate(float x, float y);
+
 		void drawTest(Image * image, float x, float y, float a, float sx, float sy, float ox, float oy);
 		void drawTest(Image * image, float x, float y, float a, float sx, float sy, float ox, float oy);
 
 
 	}; // Graphics
 	}; // Graphics

+ 16 - 1
src/modules/graphics/opengl/wrap_Graphics.cpp

@@ -20,6 +20,8 @@
 
 
 #include "wrap_Graphics.h"
 #include "wrap_Graphics.h"
 
 
+#include <image/ImageData.h>
+
 namespace love
 namespace love
 {
 {
 namespace graphics
 namespace graphics
@@ -142,7 +144,12 @@ namespace opengl
 		love::image::ImageData * data = luax_checktype<love::image::ImageData>(L, 1, "ImageData", IMAGE_IMAGE_DATA_T);
 		love::image::ImageData * data = luax_checktype<love::image::ImageData>(L, 1, "ImageData", IMAGE_IMAGE_DATA_T);
 
 
 		// Create the image.
 		// Create the image.
-		Image * image = instance->newImage(data);
+		Image * image = 0;
+		try {
+			image = instance->newImage(data);
+		} catch (love::Exception & e) {
+			luaL_error(L, e.what());
+		}
 			
 			
 		if(image == 0)
 		if(image == 0)
 			return luaL_error(L, "Could not load image.");
 			return luaL_error(L, "Could not load image.");
@@ -469,6 +476,13 @@ namespace opengl
 		lua_pushnumber(L, instance->getMaxPointSize());
 		lua_pushnumber(L, instance->getMaxPointSize());
 		return 1;
 		return 1;
 	}
 	}
+	
+	int w_newScreenshot(lua_State * L)
+	{
+		love::image::ImageData * i = instance->newScreenshot(L);
+		luax_newtype(L, "ImageData", IMAGE_IMAGE_DATA_T, (void *)i);
+		return 1;
+	}
 
 
 	/**
 	/**
 	* Draws an Image at the specified coordinates, with rotation and 
 	* Draws an Image at the specified coordinates, with rotation and 
@@ -728,6 +742,7 @@ namespace opengl
 		{ "getPointSize", w_getPointSize },
 		{ "getPointSize", w_getPointSize },
 		{ "getPointStyle", w_getPointStyle },
 		{ "getPointStyle", w_getPointStyle },
 		{ "getMaxPointSize", w_getMaxPointSize },
 		{ "getMaxPointSize", w_getMaxPointSize },
+		{ "newScreenshot", w_newScreenshot },
 
 
 		{ "draw", w_draw },
 		{ "draw", w_draw },
 		{ "drawq", w_drawq },
 		{ "drawq", w_drawq },

+ 7 - 6
src/modules/graphics/opengl/wrap_Graphics.h

@@ -42,12 +42,12 @@ namespace opengl
 	int w_reset(lua_State * L);
 	int w_reset(lua_State * L);
 	int w_clear(lua_State * L);
 	int w_clear(lua_State * L);
 	int w_present(lua_State * L);
 	int w_present(lua_State * L);
-	int w_setCaption(lua_State * L);
-	int w_getCaption(lua_State * L);
-	int w_getWidth(lua_State * L);
-	int w_getHeight(lua_State * L);
-	int w_isCreated(lua_State * L);
-	int w_setScissor(lua_State * L);
+	int w_setCaption(lua_State * L);
+	int w_getCaption(lua_State * L);
+	int w_getWidth(lua_State * L);
+	int w_getHeight(lua_State * L);
+	int w_isCreated(lua_State * L);
+	int w_setScissor(lua_State * L);
 	int w_getScissor(lua_State * L);
 	int w_getScissor(lua_State * L);
 	int w_newImage(lua_State * L);
 	int w_newImage(lua_State * L);
 	int w_newGlyph(lua_State * L);
 	int w_newGlyph(lua_State * L);
@@ -79,6 +79,7 @@ namespace opengl
 	int w_getPointSize(lua_State * L);
 	int w_getPointSize(lua_State * L);
 	int w_getPointStyle(lua_State * L);
 	int w_getPointStyle(lua_State * L);
 	int w_getMaxPointSize(lua_State * L);
 	int w_getMaxPointSize(lua_State * L);
+	int w_newScreenshot(lua_State * L);
 	int w_draw(lua_State * L);
 	int w_draw(lua_State * L);
 	int w_drawq(lua_State * L);
 	int w_drawq(lua_State * L);
 	int w_drawTest(lua_State * L);
 	int w_drawTest(lua_State * L);

+ 48 - 39
src/modules/image/Image.h

@@ -1,21 +1,21 @@
-/**
-* Copyright (c) 2006-2009 LOVE Development Team
-* 
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* 
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
+/**
+* Copyright (c) 2006-2009 LOVE Development Team
+* 
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* 
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 
+* 1. The origin of this software must not be misrepresented; you must not
+*    claim that you wrote the original software. If you use this software
+*    in a product, an acknowledgment in the product documentation would be
+*    appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+*    misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
 **/
 **/
 
 
 #ifndef LOVE_IMAGE_IMAGE_H
 #ifndef LOVE_IMAGE_IMAGE_H
@@ -45,28 +45,37 @@ namespace image
 		* Destructor.
 		* Destructor.
 		**/
 		**/
 		virtual ~Image(){};
 		virtual ~Image(){};
-
-		/**
-		* Creates new ImageData from a file. 
-		* @param file The file containing the encoded image data.
-		* @return The new ImageData.
-		**/
-		virtual ImageData * newImageData(love::filesystem::File * file) = 0;
-
-		/**
-		* Creates new ImageData from a raw Data. 
-		* @param data The object containing encoded pixel data.
-		* @return The new ImageData.
-		**/
-		virtual ImageData * newImageData(Data * data) = 0;
-
-		/**
-		* Creates empty ImageData with the given size.
-		* @param The width of the ImageData.
-		* @param The height of the ImageData.
-		* @return The new ImageData.
-		**/
+
+		/**
+		* Creates new ImageData from a file. 
+		* @param file The file containing the encoded image data.
+		* @return The new ImageData.
+		**/
+		virtual ImageData * newImageData(love::filesystem::File * file) = 0;
+
+		/**
+		* Creates new ImageData from a raw Data. 
+		* @param data The object containing encoded pixel data.
+		* @return The new ImageData.
+		**/
+		virtual ImageData * newImageData(Data * data) = 0;
+		
+		/**
+		 * Creates empty ImageData with the given size.
+		 * @param The width of the ImageData.
+		 * @param The height of the ImageData.
+		 * @return The new ImageData.
+		 **/
 		virtual ImageData * newImageData(int width, int height) = 0;
 		virtual ImageData * newImageData(int width, int height) = 0;
+		
+		/**
+		 * Creates empty ImageData with the given size.
+		 * @param The width of the ImageData.
+		 * @param The height of the ImageData.
+		 * @param The data to load into the ImageData.
+		 * @return The new ImageData.
+		 **/
+		virtual ImageData * newImageData(int width, int height, void *data) = 0;
 
 
 	}; // Image
 	}; // Image
 
 

+ 41 - 31
src/modules/image/devil/Image.cpp

@@ -1,21 +1,21 @@
-/**
-* Copyright (c) 2006-2009 LOVE Development Team
-* 
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* 
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
+/**
+* Copyright (c) 2006-2009 LOVE Development Team
+* 
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* 
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 
+* 1. The origin of this software must not be misrepresented; you must not
+*    claim that you wrote the original software. If you use this software
+*    in a product, an acknowledgment in the product documentation would be
+*    appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+*    misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
 **/
 **/
 
 
 #include "Image.h"
 #include "Image.h"
@@ -46,19 +46,29 @@ namespace devil
 		return "love.image.devil";
 		return "love.image.devil";
 	}
 	}
 
 
-	love::image::ImageData * Image::newImageData(love::filesystem::File * file)
-	{
-		return new ImageData(file);
-	}
-
-	love::image::ImageData * Image::newImageData(Data * data)
-	{
-		return new ImageData(data);
-	}
-
-	love::image::ImageData * Image::newImageData(int width, int height)
-	{
-		return new ImageData(width, height);
+	love::image::ImageData * Image::newImageData(love::filesystem::File * file)
+	{
+		return new ImageData(file);
+	}
+
+	love::image::ImageData * Image::newImageData(Data * data)
+	{
+		try {
+			return new ImageData(data);
+		} catch (love::Exception & e) {
+			throw love::Exception(e.what());
+		}
+		
+	}
+	
+	love::image::ImageData * Image::newImageData(int width, int height)
+	{
+		return new ImageData(width, height);
+	}
+
+	love::image::ImageData * Image::newImageData(int width, int height, void *data)
+	{
+		return new ImageData(width, height, data);
 	}
 	}
 
 
 } // devil
 } // devil

+ 22 - 21
src/modules/image/devil/Image.h

@@ -1,21 +1,21 @@
-/**
-* Copyright (c) 2006-2009 LOVE Development Team
-* 
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* 
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
+/**
+* Copyright (c) 2006-2009 LOVE Development Team
+* 
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* 
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 
+* 1. The origin of this software must not be misrepresented; you must not
+*    claim that you wrote the original software. If you use this software
+*    in a product, an acknowledgment in the product documentation would be
+*    appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+*    misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
 **/
 **/
 
 
 #ifndef LOVE_IMAGE_DEVIL_IMAGE_H
 #ifndef LOVE_IMAGE_DEVIL_IMAGE_H
@@ -39,10 +39,11 @@ namespace devil
 
 
 		// Implements Module.
 		// Implements Module.
 		const char * getName() const;
 		const char * getName() const;
-		
-		love::image::ImageData * newImageData(love::filesystem::File * file);
-		love::image::ImageData * newImageData(Data * data);
+		
+		love::image::ImageData * newImageData(love::filesystem::File * file);
+		love::image::ImageData * newImageData(Data * data);
 		love::image::ImageData * newImageData(int width, int height);
 		love::image::ImageData * newImageData(int width, int height);
+		love::image::ImageData * newImageData(int width, int height, void *data);
 
 
 	}; // Image
 	}; // Image
 
 

+ 157 - 122
src/modules/image/devil/ImageData.cpp

@@ -1,135 +1,170 @@
-/**
-* Copyright (c) 2006-2009 LOVE Development Team
-* 
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* 
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "ImageData.h"
-
+/**
+* Copyright (c) 2006-2009 LOVE Development Team
+* 
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* 
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 
+* 1. The origin of this software must not be misrepresented; you must not
+*    claim that you wrote the original software. If you use this software
+*    in a product, an acknowledgment in the product documentation would be
+*    appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+*    misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+**/
+
+#include "ImageData.h"
+
 // STD
 // STD
-#include <iostream>
-
-namespace love
-{
-namespace image
-{
-namespace devil
-{
-	void ImageData::load(Data * data)
-	{
+#include <iostream>
+
+// LOVE
+#include <common/Exception.h>
+
+namespace love
+{
+namespace image
+{
+namespace devil
+{
+	void ImageData::load(Data * data)
+	{
 		// Generate DevIL image.
 		// Generate DevIL image.
-		ilGenImages(1, &image);
-
+		ilGenImages(1, &image);
+
 		// Bind the image.
 		// Bind the image.
-		ilBindImage(image);
-
+		ilBindImage(image);
+
 		// Try to load the image.
 		// Try to load the image.
-		ILboolean success = ilLoadL(IL_TYPE_UNKNOWN, (void*)data->getData(), data->getSize());
-
+		ILboolean success = ilLoadL(IL_TYPE_UNKNOWN, (void*)data->getData(), data->getSize());
+
 		// Check for errors
 		// Check for errors
 		if(!success)
 		if(!success)
 		{
 		{
-			std::cerr << "Could not decode image." << std::endl;
+			throw love::Exception("Could not decode image!");
 			return;
 			return;
-		}
-
+		}
+
 		width = ilGetInteger(IL_IMAGE_WIDTH);
 		width = ilGetInteger(IL_IMAGE_WIDTH);
 		height = ilGetInteger(IL_IMAGE_HEIGHT);
 		height = ilGetInteger(IL_IMAGE_HEIGHT);
-		origin = ilGetInteger(IL_IMAGE_ORIGIN);
-
-		// Make sure the image is in RGBA format.
-		ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);
-
-		// This should always be four.
-		bpp = ilGetInteger(IL_IMAGE_BPP);
-
-		if(bpp != 4)
-		{
-			std::cerr << "Bits per pixel != 4" << std::endl;
-			return;
-		}
-	}
-
-	ImageData::ImageData(Data * data)
-	{
-		load(data);
-	}
-
-	ImageData::ImageData(filesystem::File * file)
-	{
-		Data * data = file->read();
-		load(data);
-		data->release();
-	}
-
-	ImageData::ImageData(int width, int height)
-		: width(width), height(height), origin(IL_ORIGIN_UPPER_LEFT), bpp(4)
-	{
+		origin = ilGetInteger(IL_IMAGE_ORIGIN);
+
+		// Make sure the image is in RGBA format.
+		ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);
+
+		// This should always be four.
+		bpp = ilGetInteger(IL_IMAGE_BPP);
+
+		if(bpp != 4)
+		{
+			std::cerr << "Bits per pixel != 4" << std::endl;
+			return;
+		}
+	}
+
+	ImageData::ImageData(Data * data)
+	{
+		load(data);
+	}
+
+	ImageData::ImageData(filesystem::File * file)
+	{
+		Data * data = file->read();
+		load(data);
+		data->release();
+	}
+
+	ImageData::ImageData(int width, int height)
+		: width(width), height(height), origin(IL_ORIGIN_UPPER_LEFT), bpp(4)
+	{
 		// Generate DevIL image.
 		// Generate DevIL image.
-		ilGenImages(1, &image);
-
+		ilGenImages(1, &image);
+
 		// Bind the image.
 		// Bind the image.
-		ilBindImage(image);	
-
-		ilTexImage(width, height, 1, bpp, IL_RGBA, IL_UNSIGNED_BYTE, 0);
-	}
-
-	ImageData::~ImageData()
-	{
-		ilDeleteImages(1, &image);
-	}
-
-	int ImageData::getWidth() const 
-	{
-		return width;
-	}
-
-	int ImageData::getHeight() const 
-	{
-		return height;
-	}
-
-	void * ImageData::getData() const
+		ilBindImage(image);	
+
+		ilTexImage(width, height, 1, bpp, IL_RGBA, IL_UNSIGNED_BYTE, 0);
+	}
+	
+	ImageData::ImageData(int width, int height, void *data)
+	: width(width), height(height), origin(IL_ORIGIN_UPPER_LEFT), bpp(4)
+	{
+		// Generate DevIL image.
+		ilGenImages(1, &image);
+		// Bind the image.
+		ilBindImage(image);
+		// Try to load the data.
+		bool success = ilTexImage(width, height, 1, bpp, IL_RGBA, IL_UNSIGNED_BYTE, data);
+		int err = ilGetError();
+		if (err != IL_NO_ERROR){
+			switch (err) {
+				case IL_ILLEGAL_OPERATION:
+					throw love::Exception("Error: Illegal operation");
+					break;
+				case IL_INVALID_PARAM:
+					throw love::Exception("Error: invalid parameters");
+					break;
+				case IL_OUT_OF_MEMORY:
+					throw love::Exception("Error: out of memory");
+					break;
+				default:
+					throw love::Exception("Error: unknown error");
+					break;
+			}
+		}
+		
+		if(!success) {
+			throw love::Exception("Could not decode image data.");
+		}
+	}
+
+	ImageData::~ImageData()
+	{
+		ilDeleteImages(1, &image);
+	}
+
+	int ImageData::getWidth() const 
+	{
+		return width;
+	}
+
+	int ImageData::getHeight() const 
+	{
+		return height;
+	}
+
+	void * ImageData::getData() const
+	{
+		ilBindImage(image);
+		return ilGetData();
+	}
+
+	int ImageData::getSize() const
+	{
+		return width*height*bpp;
+	}
+
+	void ImageData::setPixel(int x, int y, pixel c)
+	{
+		int tx = x > width-1 ? width-1 : x;
+		int ty = y > height-1 ? height-1 : y;
+		pixel * pixels = (pixel *)getData();
+		pixels[y*width+x] = c;
+	}
+
+	pixel ImageData::getPixel(int x, int y) const
 	{
 	{
-		ilBindImage(image);
-		return ilGetData();
-	}
-
-	int ImageData::getSize() const
-	{
-		return width*height*bpp;
-	}
-
-	void ImageData::setPixel(int x, int y, pixel c)
-	{
-		int tx = x > width-1 ? width-1 : x;
-		int ty = y > height-1 ? height-1 : y;
-		pixel * pixels = (pixel *)getData();
-		pixels[y*width+x] = c;
-	}
-
-	pixel ImageData::getPixel(int x, int y) const
-	{
-		int tx = x > width-1 ? width-1 : x;
-		int ty = y > height-1 ? height-1 : y;
-		pixel * pixels = (pixel *)getData();
-		return pixels[y*width+x];
-	}
-
-} // devil
-} // image
-} // love
+		int tx = x > width-1 ? width-1 : x;
+		int ty = y > height-1 ? height-1 : y;
+		pixel * pixels = (pixel *)getData();
+		return pixels[y*width+x];
+	}
+
+} // devil
+} // image
+} // love

+ 1 - 0
src/modules/image/devil/ImageData.h

@@ -60,6 +60,7 @@ namespace devil
 		ImageData(Data * data);
 		ImageData(Data * data);
 		ImageData(love::filesystem::File * file);
 		ImageData(love::filesystem::File * file);
 		ImageData(int width, int height);
 		ImageData(int width, int height);
+		ImageData(int width, int height, void *data);
 		virtual ~ImageData();
 		virtual ~ImageData();
 
 
 		// Implements Data.
 		// Implements Data.

+ 6 - 1
src/modules/image/wrap_Image.cpp

@@ -45,7 +45,12 @@ namespace image
 		if(luax_istype(L, 1, DATA_T))
 		if(luax_istype(L, 1, DATA_T))
 		{
 		{
 			Data * d = luax_checktype<Data>(L, 1, "Data", DATA_T);
 			Data * d = luax_checktype<Data>(L, 1, "Data", DATA_T);
-			ImageData * t = instance->newImageData(d);
+			ImageData * t;
+			try {
+				t = instance->newImageData(d);
+			} catch (love::Exception & e) {
+				return luaL_error(L, e.what());
+			}
 			luax_newtype(L, "ImageData", IMAGE_IMAGE_DATA_T, (void*)t);
 			luax_newtype(L, "ImageData", IMAGE_IMAGE_DATA_T, (void*)t);
 			return 1;
 			return 1;
 		}
 		}