Browse Source

changed PixelEffect name to ShaderEffect, added lua-side support for vert/frag shader combinations with love.graphics.newShaderEffect, added tentative support for single-file vertex+fragment shaders

Alexander Szpakowski 12 years ago
parent
commit
0611234067

+ 21 - 21
platform/macosx/love.xcodeproj/project.pbxproj

@@ -159,10 +159,8 @@
 		A96F41891412B36D0067FE9A /* wrap_WheelJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A96F41871412B35B0067FE9A /* wrap_WheelJoint.cpp */; };
 		A96F418C1412B3AD0067FE9A /* WheelJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A96F418A1412B3A30067FE9A /* WheelJoint.cpp */; };
 		A96F41921412BBEE0067FE9A /* Canvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A96F41901412BBEE0067FE9A /* Canvas.cpp */; };
-		A96F41951412BBF80067FE9A /* PixelEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A96F41931412BBF80067FE9A /* PixelEffect.cpp */; };
 		A96F41981412BC000067FE9A /* VertexBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A96F41961412BC000067FE9A /* VertexBuffer.cpp */; };
 		A96F419B1412BC070067FE9A /* wrap_Canvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A96F41991412BC070067FE9A /* wrap_Canvas.cpp */; };
-		A96F419E1412BC0E0067FE9A /* wrap_PixelEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A96F419C1412BC0E0067FE9A /* wrap_PixelEffect.cpp */; };
 		A96F41A41412C91F0067FE9A /* EdgeShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A96F41A21412C91E0067FE9A /* EdgeShape.cpp */; };
 		A96F41A71412C92B0067FE9A /* wrap_EdgeShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A96F41A51412C92B0067FE9A /* wrap_EdgeShape.cpp */; };
 		A97E632514604BC200020E43 /* wrap_Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A97E632314604BC200020E43 /* wrap_Keyboard.cpp */; };
@@ -238,6 +236,8 @@
 		A9F2D09114BA85EC0035D2A5 /* Audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A9F2D09014BA85EC0035D2A5 /* Audio.cpp */; };
 		A9F6E6AE15A1080D00C86200 /* love.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A9F6E6AC15A1080D00C86200 /* love.cpp */; };
 		A9F6E6B115A1099C00C86200 /* GmeDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A9F6E6AF15A1099C00C86200 /* GmeDecoder.cpp */; };
+		FADB91451683F5C600D84B22 /* ShaderEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADB91431683F5C600D84B22 /* ShaderEffect.cpp */; };
+		FADB91481683F5FA00D84B22 /* wrap_ShaderEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADB91461683F5F900D84B22 /* wrap_ShaderEffect.cpp */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXCopyFilesBuildPhase section */
@@ -293,7 +293,7 @@
 		A93E69EB10420ABF007D418B /* Reference.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Reference.h; sourceTree = "<group>"; };
 		A93E69EC10420ABF007D418B /* runtime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = runtime.cpp; sourceTree = "<group>"; };
 		A93E69ED10420ABF007D418B /* runtime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = runtime.h; sourceTree = "<group>"; };
-		A93E69EE10420ABF007D418B /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = types.h; sourceTree = "<group>"; };
+		A93E69EE10420ABF007D418B /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = types.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
 		A93E69EF10420ABF007D418B /* Vector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Vector.cpp; sourceTree = "<group>"; };
 		A93E69F010420ABF007D418B /* Vector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Vector.h; sourceTree = "<group>"; };
 		A93E69F110420ABF007D418B /* version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = version.h; sourceTree = "<group>"; };
@@ -401,14 +401,14 @@
 		A93E6A8010420AC2007D418B /* wrap_Rasterizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Rasterizer.h; sourceTree = "<group>"; };
 		A93E6A8210420AC2007D418B /* Drawable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Drawable.cpp; sourceTree = "<group>"; };
 		A93E6A8310420AC2007D418B /* Drawable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Drawable.h; sourceTree = "<group>"; };
-		A93E6A8410420AC2007D418B /* Graphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Graphics.h; sourceTree = "<group>"; };
+		A93E6A8410420AC2007D418B /* Graphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = Graphics.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
 		A93E6A8510420AC2007D418B /* Image.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Image.h; sourceTree = "<group>"; };
 		A93E6A8710420AC2007D418B /* Font.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Font.cpp; sourceTree = "<group>"; };
 		A93E6A8810420AC2007D418B /* Font.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Font.h; sourceTree = "<group>"; };
 		A93E6A8910420AC2007D418B /* GLee.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = GLee.c; sourceTree = "<group>"; };
 		A93E6A8A10420AC2007D418B /* GLee.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GLee.h; sourceTree = "<group>"; };
-		A93E6A8D10420AC2007D418B /* Graphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Graphics.cpp; sourceTree = "<group>"; };
-		A93E6A8E10420AC2007D418B /* Graphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Graphics.h; sourceTree = "<group>"; };
+		A93E6A8D10420AC2007D418B /* Graphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = Graphics.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
+		A93E6A8E10420AC2007D418B /* Graphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = Graphics.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
 		A93E6A8F10420AC2007D418B /* Image.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Image.cpp; sourceTree = "<group>"; };
 		A93E6A9010420AC2007D418B /* Image.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Image.h; sourceTree = "<group>"; };
 		A93E6A9310420AC2007D418B /* Quad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Quad.cpp; sourceTree = "<group>"; };
@@ -417,8 +417,8 @@
 		A93E6A9610420AC2007D418B /* SpriteBatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpriteBatch.h; sourceTree = "<group>"; };
 		A93E6A9910420AC2007D418B /* wrap_Font.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Font.cpp; sourceTree = "<group>"; };
 		A93E6A9A10420AC2007D418B /* wrap_Font.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Font.h; sourceTree = "<group>"; };
-		A93E6A9D10420AC3007D418B /* wrap_Graphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Graphics.cpp; sourceTree = "<group>"; };
-		A93E6A9E10420AC3007D418B /* wrap_Graphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Graphics.h; sourceTree = "<group>"; };
+		A93E6A9D10420AC3007D418B /* wrap_Graphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = wrap_Graphics.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
+		A93E6A9E10420AC3007D418B /* wrap_Graphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = wrap_Graphics.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
 		A93E6A9F10420AC3007D418B /* wrap_Image.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Image.cpp; sourceTree = "<group>"; };
 		A93E6AA010420AC3007D418B /* wrap_Image.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Image.h; sourceTree = "<group>"; };
 		A93E6AA110420AC3007D418B /* wrap_Quad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Quad.cpp; sourceTree = "<group>"; };
@@ -534,7 +534,7 @@
 		A93E6B9010420ACC007D418B /* Timer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Timer.h; sourceTree = "<group>"; };
 		A93E6B9710420ACC007D418B /* boot.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.lua; path = boot.lua; sourceTree = "<group>"; };
 		A93E6B9810420ACC007D418B /* boot.lua.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = boot.lua.h; sourceTree = "<group>"; };
-		A93E6B9910420ACC007D418B /* graphics.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.lua; path = graphics.lua; sourceTree = "<group>"; };
+		A93E6B9910420ACC007D418B /* graphics.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.lua; lineEnding = 0; path = graphics.lua; sourceTree = "<group>"; };
 		A93E6B9A10420ACC007D418B /* graphics.lua.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = graphics.lua.h; sourceTree = "<group>"; };
 		A93E6E4610420B4A007D418B /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = System/Library/Frameworks/OpenAL.framework; sourceTree = SDKROOT; };
 		A93E6E4710420B4A007D418B /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = "<absolute>"; };
@@ -558,7 +558,7 @@
 		A968F0C71083A07C00A895AA /* StringMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringMap.h; sourceTree = "<group>"; };
 		A968F0CE1083A9A900A895AA /* Event.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Event.cpp; sourceTree = "<group>"; };
 		A968F0D01083A9B900A895AA /* File.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = File.cpp; sourceTree = "<group>"; };
-		A968F0D21083A9D400A895AA /* Graphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Graphics.cpp; sourceTree = "<group>"; };
+		A968F0D21083A9D400A895AA /* Graphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = Graphics.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
 		A968F0D41083A9E700A895AA /* Joystick.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Joystick.cpp; sourceTree = "<group>"; };
 		A968F0D61083A9F200A895AA /* Keyboard.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Keyboard.cpp; sourceTree = "<group>"; };
 		A968F0D81083A9FC00A895AA /* Mouse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Mouse.cpp; sourceTree = "<group>"; };
@@ -587,15 +587,11 @@
 		A96F418A1412B3A30067FE9A /* WheelJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WheelJoint.cpp; sourceTree = "<group>"; };
 		A96F418B1412B3A80067FE9A /* WheelJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WheelJoint.h; sourceTree = "<group>"; };
 		A96F41901412BBEE0067FE9A /* Canvas.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Canvas.cpp; sourceTree = "<group>"; };
-		A96F41911412BBEE0067FE9A /* Canvas.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Canvas.h; sourceTree = "<group>"; };
-		A96F41931412BBF80067FE9A /* PixelEffect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PixelEffect.cpp; sourceTree = "<group>"; };
-		A96F41941412BBF80067FE9A /* PixelEffect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PixelEffect.h; sourceTree = "<group>"; };
+		A96F41911412BBEE0067FE9A /* Canvas.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = Canvas.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
 		A96F41961412BC000067FE9A /* VertexBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VertexBuffer.cpp; sourceTree = "<group>"; };
 		A96F41971412BC000067FE9A /* VertexBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VertexBuffer.h; sourceTree = "<group>"; };
 		A96F41991412BC070067FE9A /* wrap_Canvas.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Canvas.cpp; sourceTree = "<group>"; };
 		A96F419A1412BC070067FE9A /* wrap_Canvas.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Canvas.h; sourceTree = "<group>"; };
-		A96F419C1412BC0E0067FE9A /* wrap_PixelEffect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_PixelEffect.cpp; sourceTree = "<group>"; };
-		A96F419D1412BC0E0067FE9A /* wrap_PixelEffect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_PixelEffect.h; sourceTree = "<group>"; };
 		A96F41A21412C91E0067FE9A /* EdgeShape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EdgeShape.cpp; sourceTree = "<group>"; };
 		A96F41A31412C91E0067FE9A /* EdgeShape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EdgeShape.h; sourceTree = "<group>"; };
 		A96F41A51412C92B0067FE9A /* wrap_EdgeShape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_EdgeShape.cpp; sourceTree = "<group>"; };
@@ -741,6 +737,10 @@
 		A9F6E6B015A1099C00C86200 /* GmeDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GmeDecoder.h; sourceTree = "<group>"; };
 		A9F8833511163C8C00831E98 /* audio.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.lua; path = audio.lua; sourceTree = "<group>"; };
 		A9F8833611163C8C00831E98 /* audio.lua.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = audio.lua.h; sourceTree = "<group>"; };
+		FADB91431683F5C600D84B22 /* ShaderEffect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ShaderEffect.cpp; sourceTree = "<group>"; };
+		FADB91441683F5C600D84B22 /* ShaderEffect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShaderEffect.h; sourceTree = "<group>"; };
+		FADB91461683F5F900D84B22 /* wrap_ShaderEffect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_ShaderEffect.cpp; sourceTree = "<group>"; };
+		FADB91471683F5FA00D84B22 /* wrap_ShaderEffect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_ShaderEffect.h; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -1146,10 +1146,10 @@
 				A9642D7414D1A66000CE0B02 /* OpenGL.h */,
 				A9B4BA9A1045937F001DBC80 /* ParticleSystem.cpp */,
 				A9B4BA981045937F001DBC80 /* ParticleSystem.h */,
-				A96F41931412BBF80067FE9A /* PixelEffect.cpp */,
-				A96F41941412BBF80067FE9A /* PixelEffect.h */,
 				A93E6A9310420AC2007D418B /* Quad.cpp */,
 				A93E6A9410420AC2007D418B /* Quad.h */,
+				FADB91431683F5C600D84B22 /* ShaderEffect.cpp */,
+				FADB91441683F5C600D84B22 /* ShaderEffect.h */,
 				A93E6A9510420AC2007D418B /* SpriteBatch.cpp */,
 				A93E6A9610420AC2007D418B /* SpriteBatch.h */,
 				A96F41961412BC000067FE9A /* VertexBuffer.cpp */,
@@ -1164,10 +1164,10 @@
 				A93E6AA010420AC3007D418B /* wrap_Image.h */,
 				A9B4BA9B1045937F001DBC80 /* wrap_ParticleSystem.cpp */,
 				A9B4BA991045937F001DBC80 /* wrap_ParticleSystem.h */,
-				A96F419C1412BC0E0067FE9A /* wrap_PixelEffect.cpp */,
-				A96F419D1412BC0E0067FE9A /* wrap_PixelEffect.h */,
 				A93E6AA110420AC3007D418B /* wrap_Quad.cpp */,
 				A93E6AA210420AC3007D418B /* wrap_Quad.h */,
+				FADB91461683F5F900D84B22 /* wrap_ShaderEffect.cpp */,
+				FADB91471683F5FA00D84B22 /* wrap_ShaderEffect.h */,
 				A93E6AA310420AC3007D418B /* wrap_SpriteBatch.cpp */,
 				A93E6AA410420AC3007D418B /* wrap_SpriteBatch.h */,
 			);
@@ -1878,10 +1878,8 @@
 				A96E254F13B9892100456DEA /* threads.cpp in Sources */,
 				A96E255113B9892100456DEA /* wrap_Thread.cpp in Sources */,
 				A96F41921412BBEE0067FE9A /* Canvas.cpp in Sources */,
-				A96F41951412BBF80067FE9A /* PixelEffect.cpp in Sources */,
 				A96F41981412BC000067FE9A /* VertexBuffer.cpp in Sources */,
 				A96F419B1412BC070067FE9A /* wrap_Canvas.cpp in Sources */,
-				A96F419E1412BC0E0067FE9A /* wrap_PixelEffect.cpp in Sources */,
 				A901B882143B65C500D77063 /* DrawQable.cpp in Sources */,
 				A901B885143B661400D77063 /* Quad.cpp in Sources */,
 				A986ECAF132CEBB000F048C8 /* Fixture.cpp in Sources */,
@@ -1957,6 +1955,8 @@
 				A9F6E6B115A1099C00C86200 /* GmeDecoder.cpp in Sources */,
 				A911D2DB15DFECC8005B7EB8 /* Module.cpp in Sources */,
 				A5474CEF1624903B00C8EEAC /* math.cpp in Sources */,
+				FADB91451683F5C600D84B22 /* ShaderEffect.cpp in Sources */,
+				FADB91481683F5FA00D84B22 /* wrap_ShaderEffect.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

+ 2 - 2
src/common/types.h

@@ -52,7 +52,7 @@ enum Type
 	GRAPHICS_PARTICLE_SYSTEM_ID,
 	GRAPHICS_SPRITE_BATCH_ID,
 	GRAPHICS_CANVAS_ID,
-	GRAPHICS_PIXELEFFECT_ID,
+	GRAPHICS_SHADEREFFECT_ID,
 
 	// Image
 	IMAGE_IMAGE_DATA_ID,
@@ -123,7 +123,7 @@ const bits GRAPHICS_FONT_T = (bits(1) << GRAPHICS_FONT_ID) | OBJECT_T;
 const bits GRAPHICS_PARTICLE_SYSTEM_T = (bits(1) << GRAPHICS_PARTICLE_SYSTEM_ID) | GRAPHICS_DRAWABLE_T;
 const bits GRAPHICS_SPRITE_BATCH_T = (bits(1) << GRAPHICS_SPRITE_BATCH_ID) | GRAPHICS_DRAWABLE_T;
 const bits GRAPHICS_CANVAS_T = (bits(1) << GRAPHICS_CANVAS_ID) | GRAPHICS_DRAWQABLE_T;
-const bits GRAPHICS_PIXELEFFECT_T = (bits(1) << GRAPHICS_PIXELEFFECT_ID) | OBJECT_T;
+const bits GRAPHICS_SHADEREFFECT_T = (bits(1) << GRAPHICS_SHADEREFFECT_ID) | OBJECT_T;
 
 // Image.
 const bits IMAGE_IMAGE_DATA_T = (bits(1) << IMAGE_IMAGE_DATA_ID) | DATA_T;

+ 1 - 1
src/modules/graphics/Graphics.cpp

@@ -157,7 +157,7 @@ StringMap<Graphics::Support, Graphics::SUPPORT_MAX_ENUM>::Entry Graphics::suppor
 {
 	{ "canvas", Graphics::SUPPORT_CANVAS },
 	{ "hdrcanvas", Graphics::SUPPORT_HDR_CANVAS },
-	{ "pixeleffect", Graphics::SUPPORT_PIXELEFFECT },
+	{ "shadereffect", Graphics::SUPPORT_SHADEREFFECT },
 	{ "npot", Graphics::SUPPORT_NPOT },
 	{ "subtractive", Graphics::SUPPORT_SUBTRACTIVE },
 };

+ 1 - 1
src/modules/graphics/Graphics.h

@@ -86,7 +86,7 @@ public:
 	{
 		SUPPORT_CANVAS = 1,
 		SUPPORT_HDR_CANVAS,
-		SUPPORT_PIXELEFFECT,
+		SUPPORT_SHADEREFFECT,
 		SUPPORT_NPOT,
 		SUPPORT_SUBTRACTIVE,
 		SUPPORT_MAX_ENUM

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

@@ -96,7 +96,7 @@ public:
 	static void bindDefaultCanvas();
 
 private:
-	friend class PixelEffect;
+	friend class ShaderEffect;
 	GLuint getTextureName() const
 	{
 		return img;

+ 4 - 4
src/modules/graphics/opengl/Graphics.cpp

@@ -190,7 +190,7 @@ void Graphics::reset()
 	DisplayState s;
 	discardStencil();
 	Canvas::bindDefaultCanvas();
-	PixelEffect::detach();
+	ShaderEffect::detach();
 	restoreState(s);
 }
 
@@ -450,12 +450,12 @@ Canvas *Graphics::newCanvas(int width, int height, Canvas::TextureType texture_t
 	return NULL; // never reached
 }
 
-PixelEffect *Graphics::newPixelEffect(const std::string &code)
+ShaderEffect *Graphics::newShaderEffect(const std::string &vertcode, const std::string &fragcode)
 {
-	PixelEffect *effect = NULL;
+	ShaderEffect *effect = NULL;
 	try
 	{
-		effect = new PixelEffect("", code);
+		effect = new ShaderEffect(vertcode, fragcode);
 	}
 	catch(love::Exception &e)
 	{

+ 2 - 2
src/modules/graphics/opengl/Graphics.h

@@ -44,7 +44,7 @@
 #include "SpriteBatch.h"
 #include "ParticleSystem.h"
 #include "Canvas.h"
-#include "PixelEffect.h"
+#include "ShaderEffect.h"
 
 namespace love
 {
@@ -271,7 +271,7 @@ public:
 
 	Canvas *newCanvas(int width, int height, Canvas::TextureType texture_type = Canvas::TYPE_NORMAL);
 
-	PixelEffect *newPixelEffect(const std::string &code);
+	ShaderEffect *newShaderEffect(const std::string &vertcode, const std::string &fragcode);
 
 	/**
 	 * Sets the foreground color.

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

@@ -126,7 +126,7 @@ private:
 
 	void drawv(const Matrix &t, const vertex *v) const;
 
-	friend class PixelEffect;
+	friend class ShaderEffect;
 	GLuint getTextureName() const
 	{
 		return texture;

+ 35 - 48
src/modules/graphics/opengl/PixelEffect.cpp → src/modules/graphics/opengl/ShaderEffect.cpp

@@ -18,7 +18,7 @@
  * 3. This notice may not be removed or altered from any source distribution.
  **/
 
-#include "PixelEffect.h"
+#include "ShaderEffect.h"
 #include "GLee.h"
 #include "Graphics.h"
 
@@ -28,7 +28,7 @@ namespace
 // reattaches the originally active program when destroyed
 struct TemporaryAttacher
 {
-	TemporaryAttacher(love::graphics::opengl::PixelEffect *sp) : s(sp)
+	TemporaryAttacher(love::graphics::opengl::ShaderEffect *sp) : s(sp)
 	{
 		glGetIntegerv(GL_CURRENT_PROGRAM, &activeProgram);
 		s->attach();
@@ -37,7 +37,7 @@ struct TemporaryAttacher
 	{
 		glUseProgram(activeProgram);
 	}
-	love::graphics::opengl::PixelEffect *s;
+	love::graphics::opengl::ShaderEffect *s;
 	GLint activeProgram;
 };
 } // anonymous namespace
@@ -49,13 +49,13 @@ namespace graphics
 namespace opengl
 {
 
-PixelEffect *PixelEffect::current = NULL;
+ShaderEffect *ShaderEffect::current = NULL;
 
-std::map<std::string, GLint> PixelEffect::_texture_unit_pool;
-GLint PixelEffect::_current_texture_unit = 0;
-GLint PixelEffect::_max_texture_units = 0;
+std::map<std::string, GLint> ShaderEffect::_texture_unit_pool;
+GLint ShaderEffect::_current_texture_unit = 0;
+GLint ShaderEffect::_max_texture_units = 0;
 
-GLint PixelEffect::getTextureUnit(const std::string &name)
+GLint ShaderEffect::getTextureUnit(const std::string &name)
 {
 	std::map<std::string, GLint>::const_iterator it = _texture_unit_pool.find(name);
 
@@ -69,7 +69,7 @@ GLint PixelEffect::getTextureUnit(const std::string &name)
 	return _current_texture_unit;
 }
 
-	PixelEffect::PixelEffect(const std::string &vertcode, const std::string &fragcode)
+ShaderEffect::ShaderEffect(const std::string &vertcode, const std::string &fragcode)
 	: _program(0)
 	, _vertcode(vertcode)
 	, _fragcode(fragcode)
@@ -78,7 +78,7 @@ GLint PixelEffect::getTextureUnit(const std::string &name)
 	loadVolatile();
 }
 
-GLuint PixelEffect::createShader(GLenum type, const std::string &code)
+GLuint ShaderEffect::createShader(GLenum type, const std::string &code)
 {
 	const char *shadertypename = NULL;
 	switch (type)
@@ -125,46 +125,33 @@ GLuint PixelEffect::createShader(GLenum type, const std::string &code)
 	return shader;
 }
 
-GLuint PixelEffect::createProgram(const std::vector<GLuint> &shaders)
+void ShaderEffect::createProgram(const std::vector<GLuint> &shaders)
 {
-	GLuint program = glCreateProgram();
-	if (program == 0) // should only fail when called between glBegin() and glEnd()
+	_program = glCreateProgram();
+	if (_program == 0) // should only fail when called between glBegin() and glEnd()
 		throw love::Exception("Cannot create shader program object.");
 	
 	std::vector<GLuint>::const_iterator it;
 	for (it = shaders.begin(); it != shaders.end(); ++it)
-		glAttachShader(program, *it);
+		glAttachShader(_program, *it);
 	
-	glLinkProgram(program);
+	glLinkProgram(_program);
 	
 	for (it = shaders.begin(); it != shaders.end(); ++it)
-		glDetachShader(program, *it);
+		glDetachShader(_program, *it);
 	
 	GLint link_ok;
-	glGetProgramiv(program, GL_LINK_STATUS, &link_ok);
+	glGetProgramiv(_program, GL_LINK_STATUS, &link_ok);
 	if (link_ok == GL_FALSE)
 	{
-		GLint strlen, nullpos;
-		glGetProgramiv(program, GL_INFO_LOG_LENGTH, &strlen);
-		
-		char *temp_str = new char[strlen+1];
-		// be extra sure that the error string will be 0-terminated
-		memset(temp_str, '\0', strlen+1);
-		glGetProgramInfoLog(program, strlen, &nullpos, temp_str);
-		temp_str[nullpos] = '\0';
-		
-		std::string warnings(temp_str);
-		delete[] temp_str;
-
-		glDeleteProgram(program);
+		const std::string warnings = getWarnings();
+		glDeleteProgram(_program);
 		
 		throw love::Exception("Cannot link shader program object:\n%s", warnings.c_str());
 	}
-	
-	return program;
 }
 
-bool PixelEffect::loadVolatile()
+bool ShaderEffect::loadVolatile()
 {	
 	std::vector<GLuint> shaders;
 	
@@ -175,11 +162,11 @@ bool PixelEffect::loadVolatile()
 		shaders.push_back(createShader(GL_FRAGMENT_SHADER, _fragcode));
 	
 	if (shaders.size() == 0)
-		throw love::Exception("Cannot create PixelEffect: no source code!");
+		throw love::Exception("Cannot create ShaderEffect: no source code!");
 	
 	try
 	{
-		_program = createProgram(shaders);
+		createProgram(shaders);
 	}
 	catch (love::Exception &e)
 	{
@@ -197,18 +184,18 @@ bool PixelEffect::loadVolatile()
 	return true;
 }
 
-PixelEffect::~PixelEffect()
+ShaderEffect::~ShaderEffect()
 {
 	unloadVolatile();
 }
 
-void PixelEffect::unloadVolatile()
+void ShaderEffect::unloadVolatile()
 {
 	if (_program != 0)
 		glDeleteProgram(_program);
 }
 
-std::string PixelEffect::getGLSLVersion()
+std::string ShaderEffect::getGLSLVersion()
 {
 	// GL_SHADING_LANGUAGE_VERSION may not be available in OpenGL < 2.0.
 	const char *tmp = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION);
@@ -226,12 +213,12 @@ std::string PixelEffect::getGLSLVersion()
 }
 
 
-bool PixelEffect::isSupported()
+bool ShaderEffect::isSupported()
 {
 	return GLEE_VERSION_2_0 && getGLSLVersion() >= "1.2";
 }
 
-std::string PixelEffect::getWarnings() const
+std::string ShaderEffect::getWarnings() const
 {
 	GLint strlen, nullpos;
 	glGetProgramiv(_program, GL_INFO_LOG_LENGTH, &strlen);
@@ -246,19 +233,19 @@ std::string PixelEffect::getWarnings() const
 	return warnings;
 }
 
-void PixelEffect::attach()
+void ShaderEffect::attach()
 {
 	glUseProgram(_program);
 	current = this;
 }
 
-void PixelEffect::detach()
+void ShaderEffect::detach()
 {
 	glUseProgram(0);
 	current = NULL;
 }
 
-void PixelEffect::sendFloat(const std::string &name, int size, const GLfloat *vec, int count)
+void ShaderEffect::sendFloat(const std::string &name, int size, const GLfloat *vec, int count)
 {
 	TemporaryAttacher attacher(this);
 	GLint location = getUniformLocation(name);
@@ -289,7 +276,7 @@ void PixelEffect::sendFloat(const std::string &name, int size, const GLfloat *ve
 	checkSetUniformError();
 }
 
-void PixelEffect::sendMatrix(const std::string &name, int size, const GLfloat *m, int count)
+void ShaderEffect::sendMatrix(const std::string &name, int size, const GLfloat *m, int count)
 {
 	TemporaryAttacher attacher(this);
 	GLint location = getUniformLocation(name);
@@ -318,7 +305,7 @@ void PixelEffect::sendMatrix(const std::string &name, int size, const GLfloat *m
 	checkSetUniformError();
 }
 
-void PixelEffect::sendImage(const std::string &name, const Image &image)
+void ShaderEffect::sendImage(const std::string &name, const Image &image)
 {
 	GLint texture_unit = getTextureUnit(name);
 
@@ -336,7 +323,7 @@ void PixelEffect::sendImage(const std::string &name, const Image &image)
 	checkSetUniformError();
 }
 
-void PixelEffect::sendCanvas(const std::string &name, const Canvas &canvas)
+void ShaderEffect::sendCanvas(const std::string &name, const Canvas &canvas)
 {
 	GLint texture_unit = getTextureUnit(name);
 
@@ -354,7 +341,7 @@ void PixelEffect::sendCanvas(const std::string &name, const Canvas &canvas)
 	checkSetUniformError();
 }
 
-GLint PixelEffect::getUniformLocation(const std::string &name)
+GLint ShaderEffect::getUniformLocation(const std::string &name)
 {
 	std::map<std::string, GLint>::const_iterator it = _uniforms.find(name);
 	if (it != _uniforms.end())
@@ -372,7 +359,7 @@ GLint PixelEffect::getUniformLocation(const std::string &name)
 	return location;
 }
 
-void PixelEffect::checkSetUniformError()
+void ShaderEffect::checkSetUniformError()
 {
 	GLenum error_code = glGetError();
 	if (GL_INVALID_OPERATION == error_code)

+ 5 - 5
src/modules/graphics/opengl/PixelEffect.h → src/modules/graphics/opengl/ShaderEffect.h

@@ -36,11 +36,11 @@ namespace graphics
 namespace opengl
 {
 // A fragment shader
-class PixelEffect : public Object, public Volatile
+class ShaderEffect : public Object, public Volatile
 {
 public:
-	PixelEffect(const std::string &vertcode, const std::string &fragcode);
-	virtual ~PixelEffect();
+	ShaderEffect(const std::string &vertcode, const std::string &fragcode);
+	virtual ~ShaderEffect();
 	std::string getWarnings() const;
 
 	virtual bool loadVolatile();
@@ -51,7 +51,7 @@ public:
 	static std::string getGLSLVersion();
 	static bool isSupported();
 
-	static PixelEffect *current;
+	static ShaderEffect *current;
 
 	void sendFloat(const std::string &name, int size, const GLfloat *vec, int count);
 	void sendMatrix(const std::string &name, int size, const GLfloat *m, int count);
@@ -62,7 +62,7 @@ private:
 	GLint getUniformLocation(const std::string &name);
 	void checkSetUniformError();
 	GLuint createShader(GLenum type, const std::string &code);
-	GLuint createProgram(const std::vector<GLuint> &shaders);
+	void createProgram(const std::vector<GLuint> &shaders);
 	
 	GLuint _program;
 	std::string _vertcode;

+ 31 - 22
src/modules/graphics/opengl/wrap_Graphics.cpp

@@ -433,29 +433,38 @@ int w_newCanvas(lua_State *L)
 	return 1;
 }
 
-int w_newPixelEffect(lua_State *L)
+int w_newShaderEffect(lua_State *L)
 {
-	if (!PixelEffect::isSupported())
+	if (!ShaderEffect::isSupported())
 		return luaL_error(L, "Sorry, your graphics card does not support pixel effects.");
 
 	try
 	{
-		luaL_checkstring(L, 1);
+		// clamp stack to 2 elements
+		lua_settop(L, 2);
 
 		luax_getfunction(L, "graphics", "_effectCodeToGLSL");
+		
+		// push vertcode and fragcode strings to the top of the stack so they become arguments for the function
 		lua_pushvalue(L, 1);
-		lua_pcall(L, 1, 1, 0);
-
-		const char *code = lua_tostring(L, -1);
-		PixelEffect *effect = instance->newPixelEffect(code);
-		luax_newtype(L, "PixelEffect", GRAPHICS_PIXELEFFECT_T, (void *)effect);
+		lua_pushvalue(L, 2);
+		
+		// call effectCodeToGLSL
+		lua_pcall(L, 2, 2, 0);
+		
+		// get returned values from the top of the stack
+		const char *vertcode = luaL_optstring(L, -2, "");
+		const char *fragcode = luaL_optstring(L, -1, "");
+		
+		ShaderEffect *effect = instance->newShaderEffect(vertcode, fragcode);
+		luax_newtype(L, "ShaderEffect", GRAPHICS_SHADEREFFECT_T, (void *)effect);
 	}
 	catch(const love::Exception &e)
 	{
-		// memory is freed in Graphics::newPixelEffect
+		// memory is freed in Graphics::newShaderEffect
 		luax_getfunction(L, "graphics", "_transformGLSLErrorMessages");
 		lua_pushstring(L, e.what());
-		lua_pcall(L, 1,1, 0);
+		lua_pcall(L, 1, 1, 0);
 		const char *err = lua_tostring(L, -1);
 		return luaL_error(L, "%s", err);
 	}
@@ -794,26 +803,26 @@ int w_getCanvas(lua_State *L)
 	return 1;
 }
 
-int w_setPixelEffect(lua_State *L)
+int w_setShaderEffect(lua_State *L)
 {
 	if (lua_isnoneornil(L,1))
 	{
-		PixelEffect::detach();
+		ShaderEffect::detach();
 		return 0;
 	}
 
-	PixelEffect *effect = luax_checkpixeleffect(L, 1);
+	ShaderEffect *effect = luax_checkshadereffect(L, 1);
 	effect->attach();
 	return 0;
 }
 
-int w_getPixelEffect(lua_State *L)
+int w_getShaderEffect(lua_State *L)
 {
-	PixelEffect *effect = PixelEffect::current;
+	ShaderEffect *effect = ShaderEffect::current;
 	if (effect)
 	{
 		effect->retain();
-		luax_newtype(L, "PixelEffect", GRAPHICS_PIXELEFFECT_T, (void *) effect);
+		luax_newtype(L, "ShaderEffect", GRAPHICS_SHADEREFFECT_T, (void *) effect);
 	}
 	else
 		lua_pushnil(L);
@@ -841,8 +850,8 @@ int w_isSupported(lua_State *L)
 			if (!Canvas::isHdrSupported())
 				supported = false;
 			break;
-		case Graphics::SUPPORT_PIXELEFFECT:
-			if (!PixelEffect::isSupported())
+		case Graphics::SUPPORT_SHADEREFFECT:
+			if (!ShaderEffect::isSupported())
 				supported = false;
 			break;
 		case Graphics::SUPPORT_NPOT:
@@ -1256,7 +1265,7 @@ static const luaL_Reg functions[] =
 	{ "newSpriteBatch", w_newSpriteBatch },
 	{ "newParticleSystem", w_newParticleSystem },
 	{ "newCanvas", w_newCanvas },
-	{ "newPixelEffect", w_newPixelEffect },
+	{ "newShaderEffect", w_newShaderEffect },
 
 	{ "setColor", w_setColor },
 	{ "getColor", w_getColor },
@@ -1287,8 +1296,8 @@ static const luaL_Reg functions[] =
 	{ "setCanvas", w_setCanvas },
 	{ "getCanvas", w_getCanvas },
 
-	{ "setPixelEffect", w_setPixelEffect },
-	{ "getPixelEffect", w_getPixelEffect },
+	{ "setShaderEffect", w_setShaderEffect },
+	{ "getShaderEffect", w_getShaderEffect },
 
 	{ "isSupported", w_isSupported },
 
@@ -1349,7 +1358,7 @@ static const lua_CFunction types[] =
 	luaopen_spritebatch,
 	luaopen_particlesystem,
 	luaopen_canvas,
-	luaopen_pixeleffect,
+	luaopen_shadereffect,
 	0
 };
 

+ 4 - 3
src/modules/graphics/opengl/wrap_Graphics.h

@@ -28,7 +28,7 @@
 #include "wrap_SpriteBatch.h"
 #include "wrap_ParticleSystem.h"
 #include "wrap_Canvas.h"
-#include "wrap_PixelEffect.h"
+#include "wrap_ShaderEffect.h"
 #include "Graphics.h"
 
 namespace love
@@ -63,7 +63,7 @@ int w_newImageFont(lua_State *L);
 int w_newSpriteBatch(lua_State *L);
 int w_newParticleSystem(lua_State *L);
 int w_newCanvas(lua_State *L);  // comments in function
-int w_newPixelEffect(lua_State *L);
+int w_newShaderEffect(lua_State *L);
 int w_setColor(lua_State *L);
 int w_getColor(lua_State *L);
 int w_setBackgroundColor(lua_State *L);
@@ -90,7 +90,8 @@ int w_getMaxPointSize(lua_State *L);
 int w_newScreenshot(lua_State *L);
 int w_setCanvas(lua_State *L);
 int w_getCanvas(lua_State *L);
-int w_setPixelEffect(lua_State *L);
+int w_setShaderEffect(lua_State *L);
+int w_getShaderEffect(lua_State *L);
 int w_isSupported(lua_State *L);
 int w_draw(lua_State *L);
 int w_drawq(lua_State *L);

+ 22 - 22
src/modules/graphics/opengl/wrap_PixelEffect.cpp → src/modules/graphics/opengl/wrap_ShaderEffect.cpp

@@ -18,7 +18,7 @@
  * 3. This notice may not be removed or altered from any source distribution.
  **/
 
-#include "wrap_PixelEffect.h"
+#include "wrap_ShaderEffect.h"
 #include "wrap_Image.h"
 #include "wrap_Canvas.h"
 #include <string>
@@ -32,19 +32,19 @@ namespace graphics
 namespace opengl
 {
 
-PixelEffect *luax_checkpixeleffect(lua_State *L, int idx)
+ShaderEffect *luax_checkshadereffect(lua_State *L, int idx)
 {
-	return luax_checktype<PixelEffect>(L, idx, "PixelEffect", GRAPHICS_PIXELEFFECT_T);
+	return luax_checktype<ShaderEffect>(L, idx, "ShaderEffect", GRAPHICS_SHADEREFFECT_T);
 }
 
-int w_PixelEffect_getWarnings(lua_State *L)
+int w_ShaderEffect_getWarnings(lua_State *L)
 {
-	PixelEffect *effect = luax_checkpixeleffect(L, 1);
+	ShaderEffect *effect = luax_checkshadereffect(L, 1);
 	lua_pushstring(L, effect->getWarnings().c_str());
 	return 1;
 }
 
-static int _sendScalars(lua_State *L, PixelEffect *effect, const char *name, int count)
+static int _sendScalars(lua_State *L, ShaderEffect *effect, const char *name, int count)
 {
 	float *values = new float[count];
 	for (int i = 0; i < count; ++i)
@@ -71,7 +71,7 @@ static int _sendScalars(lua_State *L, PixelEffect *effect, const char *name, int
 	return 0;
 }
 
-static int _sendVectors(lua_State *L, PixelEffect *effect, const char *name, int count)
+static int _sendVectors(lua_State *L, ShaderEffect *effect, const char *name, int count)
 {
 	size_t dimension = lua_objlen(L, 3);
 	float *values = new float[count * dimension];
@@ -112,9 +112,9 @@ static int _sendVectors(lua_State *L, PixelEffect *effect, const char *name, int
 	return 0;
 }
 
-int w_PixelEffect_sendFloat(lua_State *L)
+int w_ShaderEffect_sendFloat(lua_State *L)
 {
-	PixelEffect *effect = luax_checkpixeleffect(L, 1);
+	ShaderEffect *effect = luax_checkshadereffect(L, 1);
 	const char *name = luaL_checkstring(L, 2);
 	int count = lua_gettop(L) - 2;
 
@@ -129,10 +129,10 @@ int w_PixelEffect_sendFloat(lua_State *L)
 	return luaL_typerror(L, 3, "number or table");
 }
 
-int w_PixelEffect_sendMatrix(lua_State *L)
+int w_ShaderEffect_sendMatrix(lua_State *L)
 {
 	int count = lua_gettop(L) - 2;
-	PixelEffect *effect = luax_checkpixeleffect(L, 1);
+	ShaderEffect *effect = luax_checkshadereffect(L, 1);
 	const char *name = luaL_checkstring(L, 2);
 
 	if (!lua_istable(L, 3))
@@ -186,9 +186,9 @@ int w_PixelEffect_sendMatrix(lua_State *L)
 	return 0;
 }
 
-int w_PixelEffect_sendImage(lua_State *L)
+int w_ShaderEffect_sendImage(lua_State *L)
 {
-	PixelEffect *effect = luax_checkpixeleffect(L, 1);
+	ShaderEffect *effect = luax_checkshadereffect(L, 1);
 	const char *name = luaL_checkstring(L, 2);
 	Image *img = luax_checkimage(L, 3);
 
@@ -204,9 +204,9 @@ int w_PixelEffect_sendImage(lua_State *L)
 	return 0;
 }
 
-int w_PixelEffect_sendCanvas(lua_State *L)
+int w_ShaderEffect_sendCanvas(lua_State *L)
 {
-	PixelEffect *effect = luax_checkpixeleffect(L, 1);
+	ShaderEffect *effect = luax_checkshadereffect(L, 1);
 	const char *name = luaL_checkstring(L, 2);
 	Canvas *canvas = luax_checkcanvas(L, 3);
 
@@ -225,17 +225,17 @@ int w_PixelEffect_sendCanvas(lua_State *L)
 
 static const luaL_Reg functions[] =
 {
-	{ "getWarnings", w_PixelEffect_getWarnings },
-	{ "sendFloat",   w_PixelEffect_sendFloat },
-	{ "sendMatrix",  w_PixelEffect_sendMatrix },
-	{ "sendImage",   w_PixelEffect_sendImage },
-	{ "sendCanvas",  w_PixelEffect_sendCanvas },
+	{ "getWarnings", w_ShaderEffect_getWarnings },
+	{ "sendFloat",   w_ShaderEffect_sendFloat },
+	{ "sendMatrix",  w_ShaderEffect_sendMatrix },
+	{ "sendImage",   w_ShaderEffect_sendImage },
+	{ "sendCanvas",  w_ShaderEffect_sendCanvas },
 	{ 0, 0 }
 };
 
-extern "C" int luaopen_pixeleffect(lua_State *L)
+extern "C" int luaopen_shadereffect(lua_State *L)
 {
-	return luax_register_type(L, "PixelEffect", functions);
+	return luax_register_type(L, "ShaderEffect", functions);
 }
 
 } // opengl

+ 7 - 7
src/modules/graphics/opengl/wrap_PixelEffect.h → src/modules/graphics/opengl/wrap_ShaderEffect.h

@@ -22,7 +22,7 @@
 #define LOVE_GRAPHICS_OPENGL_WRAP_PROGRAM_H
 
 #include "common/runtime.h"
-#include "PixelEffect.h"
+#include "ShaderEffect.h"
 
 namespace love
 {
@@ -31,12 +31,12 @@ namespace graphics
 namespace opengl
 {
 
-PixelEffect *luax_checkpixeleffect(lua_State *L, int idx);
-int w_PixelEffect_getWarnings(lua_State *L);
-int w_PixelEffect_sendFloat(lua_State *L);
-int w_PixelEffect_sendMatrix(lua_State *L);
-int w_PixelEffect_sendImage(lua_State *L);
-extern "C" int luaopen_pixeleffect(lua_State *L);
+ShaderEffect *luax_checkshadereffect(lua_State *L, int idx);
+int w_ShaderEffect_getWarnings(lua_State *L);
+int w_ShaderEffect_sendFloat(lua_State *L);
+int w_ShaderEffect_sendMatrix(lua_State *L);
+int w_ShaderEffect_sendImage(lua_State *L);
+extern "C" int luaopen_shadereffect(lua_State *L);
 
 } // opengl
 } // graphics

+ 1 - 1
src/scripts/boot.lua

@@ -760,7 +760,7 @@ function love.releaseerrhand(msg)
 	end
 
 	love.graphics.setCanvas()
-	love.graphics.setPixelEffect()
+	love.graphics.setShaderEffect()
 
 	-- Load.
 	if love.audio then love.audio.stop() end

+ 1 - 1
src/scripts/boot.lua.h

@@ -1783,7 +1783,7 @@ const unsigned char boot_lua[] =
 	0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, 
 	0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x28, 0x29, 0x0a,
 	0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, 
-	0x50, 0x69, 0x78, 0x65, 0x6c, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x28, 0x29, 0x0a,
+	0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x28, 0x29, 0x0a,
 	0x09, 0x2d, 0x2d, 0x20, 0x4c, 0x6f, 0x61, 0x64, 0x2e, 0x0a,
 	0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x20, 0x74, 0x68, 0x65, 
 	0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x2e, 0x73, 0x74, 0x6f, 0x70, 0x28, 

+ 97 - 26
src/scripts/graphics.lua

@@ -1284,25 +1284,78 @@ do
 	end
 
 	-- PIXEL EFFECTS
-	local GLSL_HEADER_LINE_COUNT = 6
-	local GLSL_HEADER = [[#version 120
-	#define number float
-	#define Image sampler2D
-	#define extern uniform
-	#define Texel texture2D
-	uniform sampler2D _tex0_;]]
-	local GLSL_FOOTER = [[void main() {
-		// fix weird crashing issue in OSX when _tex0_ is unused within effect()
-		float dummy = texture2D(_tex0_, vec2(.5)).r;
-		gl_FragColor = effect(gl_Color, _tex0_, gl_TexCoord[0].xy, gl_FragCoord.xy);
-	}]]
-	function love.graphics._effectCodeToGLSL(code)
-		return table.concat{GLSL_HEADER, "\n", code, GLSL_FOOTER}
+	local HEADER_LINE_COUNT = 7
+	
+	local GLSL_VERT = {
+		HEADER = [[
+#version 120
+#define number float
+#define Image sampler2D
+#define extern uniform
+#define Texel texture2D
+#define VERTEX
+uniform sampler2D _tex0_;]],
+		FOOTER = [[
+void main() {
+	gl_TexCoord[0] = gl_MultiTexCoord0;
+	gl_FrontColor = gl_Color;
+	gl_Position = transform(gl_Vertex);
+}]],
+	}
+	
+	local GLSL_FRAG = {
+		HEADER = [[
+#version 120
+#define number float
+#define Image sampler2D
+#define extern uniform
+#define Texel texture2D
+#define PIXEL
+uniform sampler2D _tex0_;]],
+		FOOTER = [[
+void main() {
+	// fix weird crashing issue in OSX when _tex0_ is unused within effect()
+	float dummy = texture2D(_tex0_, vec2(.5)).r;
+	gl_FragColor = effect(gl_Color, _tex0_, gl_TexCoord[0].xy, gl_FragCoord.xy);
+}]],
+	}
+
+	function love.graphics._effectCodeToGLSL(vertcode, fragcode)
+		if vertcode then
+			local s = vertcode:gsub("\r\n\t", " ")
+			s = s:gsub("%w+(%s+)%(", "")
+			if s:match("vec4 effect%(") then
+				fragcode = vertcode
+			end
+			if not s:match("vec4 transform%(") then
+				vertcode = nil
+			end
+		end
+		if fragcode then
+			local s = fragcode:gsub("\r\n\t", " ")
+			s = s:gsub("%w+(%s+)%(", "")
+			if s:match("vec4 transform%(") then
+				vertcode = fragcode
+			end
+			if not s:match("vec4 effect%(") then
+				fragcode = nil
+			end
+		end
+
+		if vertcode then
+			vertcode = table.concat{GLSL_VERT.HEADER, "\n", vertcode, GLSL_VERT.FOOTER}
+		end
+		if fragcode then
+			fragcode = table.concat{GLSL_FRAG.HEADER, "\n", fragcode, GLSL_FRAG.FOOTER}
+		end
+		
+		return vertcode, fragcode 
 	end
 
 	function love.graphics._transformGLSLErrorMessages(message)
-		if not message:match("Cannot compile shader") then return message end
-		local lines = {"Cannot compile shader:"}
+		local shadertype = message:match("Cannot compile (%a+) shader")
+		if not shadertype then return message end
+		local lines = {"Cannot compile "..shadertype.." shader:"}
 		for l in message:gmatch("[^\n]+") do
 			-- nvidia compiler message:
 			-- 0(<linenumber>) : error/warning [NUMBER]: <error message>
@@ -1340,7 +1393,7 @@ do
 	end
 
 	-- automagic uniform setter
-	local function pixeleffect_dispatch_send(self, name, value, ...)
+	local function shadereffect_dispatch_send(self, name, value, ...)
 		if type(value) == "number" then         -- scalar
 			self:sendFloat(name, value, ...)
 		elseif type(value) == "userdata" and value:typeOf("Image") then
@@ -1362,19 +1415,37 @@ do
 		end
 	end
 
-	local newPixelEffect = love.graphics.newPixelEffect
-	function love.graphics.newPixelEffect(code)
-		love.graphics.newPixelEffect = function(code)
-			if love.filesystem and love.filesystem.exists(code) then
-				code = love.filesystem.read(code)
+	local newShaderEffect = love.graphics.newShaderEffect
+	function love.graphics.newShaderEffect(vertcode, fragcode)
+		love.graphics.newShaderEffect = function(vertcode, fragcode)
+			if love.filesystem then
+				if vertcode and love.filesystem.exists(vertcode) then
+					vertcode = love.filesystem.read(vertcode)
+				end
+				if fragcode and love.filesystem.exists(fragcode) then
+					fragcode = love.filesystem.read(fragcode)
+				end
 			end
-			return newPixelEffect(code)
+			return newShaderEffect(vertcode, fragcode)
 		end
 
-		local effect = love.graphics.newPixelEffect(code)
+		local effect = love.graphics.newShaderEffect(vertcode, fragcode)
 		local meta = getmetatable(effect)
-		meta.send = pixeleffect_dispatch_send
+		meta.send = shadereffect_dispatch_send
 		return effect
 	end
-
+	
+	function love.graphics.newPixelEffect(fragcode)
+		return love.graphics.newShaderEffect(nil, fragcode)
+	end
+	
+	function love.graphics.newVertexEffect(vertcode)
+		return love.graphics.newShaderEffect(vertcode, nil)
+	end
+	
+	love.graphics.setPixelEffect = love.graphics.setShaderEffect
+	love.graphics.getPixelEffect = love.graphics.getShaderEffect
+	
+	love.graphics.setVertexEffect = love.graphics.setShaderEffect
+	love.graphics.getVertexEffect = love.graphics.getShaderEffect
 end

+ 198 - 65
src/scripts/graphics.lua.h

@@ -6260,55 +6260,139 @@ const unsigned char graphics_lua[] =
 	0x69, 0x6e, 0x74, 0x66, 0x28, 0x2e, 0x2e, 0x2e, 0x29, 0x0a,
 	0x09, 0x65, 0x6e, 0x64, 0x0a,
 	0x09, 0x2d, 0x2d, 0x20, 0x50, 0x49, 0x58, 0x45, 0x4c, 0x20, 0x45, 0x46, 0x46, 0x45, 0x43, 0x54, 0x53, 0x0a,
-	0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 
-	0x5f, 0x4c, 0x49, 0x4e, 0x45, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x20, 0x3d, 0x20, 0x36, 0x0a,
-	0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 
-	0x20, 0x3d, 0x20, 0x5b, 0x5b, 0x23, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x31, 0x32, 0x30, 0x0a,
-	0x09, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x66, 0x6c, 
-	0x6f, 0x61, 0x74, 0x0a,
-	0x09, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x73, 0x61, 0x6d, 
-	0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x0a,
-	0x09, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x75, 0x6e, 
-	0x69, 0x66, 0x6f, 0x72, 0x6d, 0x0a,
-	0x09, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x54, 0x65, 0x78, 0x65, 0x6c, 0x20, 0x74, 0x65, 0x78, 
-	0x74, 0x75, 0x72, 0x65, 0x32, 0x44, 0x0a,
-	0x09, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 
-	0x20, 0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x3b, 0x5d, 0x5d, 0x0a,
-	0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x46, 0x4f, 0x4f, 0x54, 0x45, 0x52, 
-	0x20, 0x3d, 0x20, 0x5b, 0x5b, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a,
-	0x09, 0x09, 0x2f, 0x2f, 0x20, 0x66, 0x69, 0x78, 0x20, 0x77, 0x65, 0x69, 0x72, 0x64, 0x20, 0x63, 0x72, 0x61, 
-	0x73, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x73, 0x73, 0x75, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x4f, 0x53, 0x58, 
-	0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x20, 0x69, 0x73, 0x20, 0x75, 0x6e, 
-	0x75, 0x73, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x20, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 
-	0x28, 0x29, 0x0a,
-	0x09, 0x09, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x20, 0x3d, 0x20, 0x74, 0x65, 
-	0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x44, 0x28, 0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x2c, 0x20, 0x76, 0x65, 
-	0x63, 0x32, 0x28, 0x2e, 0x35, 0x29, 0x29, 0x2e, 0x72, 0x3b, 0x0a,
-	0x09, 0x09, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x65, 
-	0x66, 0x66, 0x65, 0x63, 0x74, 0x28, 0x67, 0x6c, 0x5f, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2c, 0x20, 0x5f, 0x74, 
-	0x65, 0x78, 0x30, 0x5f, 0x2c, 0x20, 0x67, 0x6c, 0x5f, 0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x5b, 
-	0x30, 0x5d, 0x2e, 0x78, 0x79, 0x2c, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6f, 0x72, 
-	0x64, 0x2e, 0x78, 0x79, 0x29, 0x3b, 0x0a,
-	0x09, 0x7d, 0x5d, 0x5d, 0x0a,
+	0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x5f, 0x4c, 0x49, 0x4e, 0x45, 
+	0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x20, 0x3d, 0x20, 0x37, 0x0a,
+	0x09, 0x0a,
+	0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x56, 0x45, 0x52, 0x54, 0x20, 0x3d, 
+	0x20, 0x7b, 0x0a,
+	0x09, 0x09, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x20, 0x3d, 0x20, 0x5b, 0x5b, 0x0a,
+	0x23, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x31, 0x32, 0x30, 0x0a,
+	0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x66, 0x6c, 0x6f, 
+	0x61, 0x74, 0x0a,
+	0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x70, 
+	0x6c, 0x65, 0x72, 0x32, 0x44, 0x0a,
+	0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x75, 0x6e, 0x69, 
+	0x66, 0x6f, 0x72, 0x6d, 0x0a,
+	0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x54, 0x65, 0x78, 0x65, 0x6c, 0x20, 0x74, 0x65, 0x78, 0x74, 
+	0x75, 0x72, 0x65, 0x32, 0x44, 0x0a,
+	0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x56, 0x45, 0x52, 0x54, 0x45, 0x58, 0x0a,
+	0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 
+	0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x3b, 0x5d, 0x5d, 0x2c, 0x0a,
+	0x09, 0x09, 0x46, 0x4f, 0x4f, 0x54, 0x45, 0x52, 0x20, 0x3d, 0x20, 0x5b, 0x5b, 0x0a,
+	0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a,
+	0x09, 0x67, 0x6c, 0x5f, 0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x5b, 0x30, 0x5d, 0x20, 0x3d, 0x20, 
+	0x67, 0x6c, 0x5f, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x3b, 0x0a,
+	0x09, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x67, 
+	0x6c, 0x5f, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a,
+	0x09, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x61, 
+	0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x28, 0x67, 0x6c, 0x5f, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x29, 0x3b, 0x0a,
+	0x7d, 0x5d, 0x5d, 0x2c, 0x0a,
+	0x09, 0x7d, 0x0a,
+	0x09, 0x0a,
+	0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x46, 0x52, 0x41, 0x47, 0x20, 0x3d, 
+	0x20, 0x7b, 0x0a,
+	0x09, 0x09, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x20, 0x3d, 0x20, 0x5b, 0x5b, 0x0a,
+	0x23, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x31, 0x32, 0x30, 0x0a,
+	0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x66, 0x6c, 0x6f, 
+	0x61, 0x74, 0x0a,
+	0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x70, 
+	0x6c, 0x65, 0x72, 0x32, 0x44, 0x0a,
+	0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x75, 0x6e, 0x69, 
+	0x66, 0x6f, 0x72, 0x6d, 0x0a,
+	0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x54, 0x65, 0x78, 0x65, 0x6c, 0x20, 0x74, 0x65, 0x78, 0x74, 
+	0x75, 0x72, 0x65, 0x32, 0x44, 0x0a,
+	0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x50, 0x49, 0x58, 0x45, 0x4c, 0x0a,
+	0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 
+	0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x3b, 0x5d, 0x5d, 0x2c, 0x0a,
+	0x09, 0x09, 0x46, 0x4f, 0x4f, 0x54, 0x45, 0x52, 0x20, 0x3d, 0x20, 0x5b, 0x5b, 0x0a,
+	0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a,
+	0x09, 0x2f, 0x2f, 0x20, 0x66, 0x69, 0x78, 0x20, 0x77, 0x65, 0x69, 0x72, 0x64, 0x20, 0x63, 0x72, 0x61, 0x73, 
+	0x68, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x73, 0x73, 0x75, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x4f, 0x53, 0x58, 0x20, 
+	0x77, 0x68, 0x65, 0x6e, 0x20, 0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x20, 0x69, 0x73, 0x20, 0x75, 0x6e, 0x75, 
+	0x73, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x20, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x28, 
+	0x29, 0x0a,
+	0x09, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 
+	0x74, 0x75, 0x72, 0x65, 0x32, 0x44, 0x28, 0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x2c, 0x20, 0x76, 0x65, 0x63, 
+	0x32, 0x28, 0x2e, 0x35, 0x29, 0x29, 0x2e, 0x72, 0x3b, 0x0a,
+	0x09, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x65, 0x66, 
+	0x66, 0x65, 0x63, 0x74, 0x28, 0x67, 0x6c, 0x5f, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2c, 0x20, 0x5f, 0x74, 0x65, 
+	0x78, 0x30, 0x5f, 0x2c, 0x20, 0x67, 0x6c, 0x5f, 0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x5b, 0x30, 
+	0x5d, 0x2e, 0x78, 0x79, 0x2c, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6f, 0x72, 0x64, 
+	0x2e, 0x78, 0x79, 0x29, 0x3b, 0x0a,
+	0x7d, 0x5d, 0x5d, 0x2c, 0x0a,
+	0x09, 0x7d, 0x0a,
 	0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 
 	0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x5f, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x54, 
-	0x6f, 0x47, 0x4c, 0x53, 0x4c, 0x28, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x0a,
-	0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6e, 
-	0x63, 0x61, 0x74, 0x7b, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x2c, 0x20, 0x22, 
-	0x5c, 0x6e, 0x22, 0x2c, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x46, 0x4f, 
-	0x4f, 0x54, 0x45, 0x52, 0x7d, 0x0a,
+	0x6f, 0x47, 0x4c, 0x53, 0x4c, 0x28, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x66, 0x72, 
+	0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x0a,
+	0x09, 0x09, 0x69, 0x66, 0x20, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
+	0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x72, 0x74, 0x63, 
+	0x6f, 0x64, 0x65, 0x3a, 0x67, 0x73, 0x75, 0x62, 0x28, 0x22, 0x5c, 0x72, 0x5c, 0x6e, 0x5c, 0x74, 0x22, 0x2c, 
+	0x20, 0x22, 0x20, 0x22, 0x29, 0x0a,
+	0x09, 0x09, 0x09, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x3a, 0x67, 0x73, 0x75, 0x62, 0x28, 0x22, 0x25, 0x77, 0x2b, 
+	0x28, 0x25, 0x73, 0x2b, 0x29, 0x25, 0x28, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a,
+	0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x73, 0x3a, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x28, 0x22, 0x76, 0x65, 0x63, 
+	0x34, 0x20, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x25, 0x28, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
+	0x09, 0x09, 0x09, 0x09, 0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x72, 
+	0x74, 0x63, 0x6f, 0x64, 0x65, 0x0a,
+	0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
+	0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x3a, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x28, 
+	0x22, 0x76, 0x65, 0x63, 0x34, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x25, 0x28, 0x22, 
+	0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
+	0x09, 0x09, 0x09, 0x09, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x0a,
+	0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
+	0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
+	0x09, 0x09, 0x69, 0x66, 0x20, 0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
+	0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x66, 0x72, 0x61, 0x67, 0x63, 
+	0x6f, 0x64, 0x65, 0x3a, 0x67, 0x73, 0x75, 0x62, 0x28, 0x22, 0x5c, 0x72, 0x5c, 0x6e, 0x5c, 0x74, 0x22, 0x2c, 
+	0x20, 0x22, 0x20, 0x22, 0x29, 0x0a,
+	0x09, 0x09, 0x09, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x3a, 0x67, 0x73, 0x75, 0x62, 0x28, 0x22, 0x25, 0x77, 0x2b, 
+	0x28, 0x25, 0x73, 0x2b, 0x29, 0x25, 0x28, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a,
+	0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x73, 0x3a, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x28, 0x22, 0x76, 0x65, 0x63, 
+	0x34, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x25, 0x28, 0x22, 0x29, 0x20, 0x74, 0x68, 
+	0x65, 0x6e, 0x0a,
+	0x09, 0x09, 0x09, 0x09, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x72, 0x61, 
+	0x67, 0x63, 0x6f, 0x64, 0x65, 0x0a,
+	0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
+	0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x3a, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x28, 
+	0x22, 0x76, 0x65, 0x63, 0x34, 0x20, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x25, 0x28, 0x22, 0x29, 0x20, 0x74, 
+	0x68, 0x65, 0x6e, 0x0a,
+	0x09, 0x09, 0x09, 0x09, 0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x0a,
+	0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
+	0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
+	0x09, 0x09, 0x69, 0x66, 0x20, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
+	0x09, 0x09, 0x09, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x61, 0x62, 0x6c, 
+	0x65, 0x2e, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x7b, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x56, 0x45, 0x52, 0x54, 
+	0x2e, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x2c, 0x20, 0x22, 0x5c, 0x6e, 0x22, 0x2c, 0x20, 0x76, 0x65, 0x72, 
+	0x74, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x56, 0x45, 0x52, 0x54, 0x2e, 0x46, 
+	0x4f, 0x4f, 0x54, 0x45, 0x52, 0x7d, 0x0a,
+	0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
+	0x09, 0x09, 0x69, 0x66, 0x20, 0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
+	0x09, 0x09, 0x09, 0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x61, 0x62, 0x6c, 
+	0x65, 0x2e, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x7b, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x46, 0x52, 0x41, 0x47, 
+	0x2e, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x2c, 0x20, 0x22, 0x5c, 0x6e, 0x22, 0x2c, 0x20, 0x66, 0x72, 0x61, 
+	0x67, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x46, 0x52, 0x41, 0x47, 0x2e, 0x46, 
+	0x4f, 0x4f, 0x54, 0x45, 0x52, 0x7d, 0x0a,
+	0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
+	0x09, 0x09, 0x0a,
+	0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x2c, 
+	0x20, 0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x0a,
 	0x09, 0x65, 0x6e, 0x64, 0x0a,
 	0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 
 	0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x47, 0x4c, 
 	0x53, 0x4c, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x28, 0x6d, 0x65, 
 	0x73, 0x73, 0x61, 0x67, 0x65, 0x29, 0x0a,
-	0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x3a, 0x6d, 
-	0x61, 0x74, 0x63, 0x68, 0x28, 0x22, 0x43, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x69, 
-	0x6c, 0x65, 0x20, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 
-	0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x65, 0x6e, 0x64, 0x0a,
+	0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 
+	0x20, 0x3d, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x3a, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x28, 0x22, 
+	0x43, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x20, 0x28, 0x25, 0x61, 
+	0x2b, 0x29, 0x20, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x22, 0x29, 0x0a,
+	0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x74, 0x79, 0x70, 
+	0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6d, 0x65, 0x73, 0x73, 
+	0x61, 0x67, 0x65, 0x20, 0x65, 0x6e, 0x64, 0x0a,
 	0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x22, 
-	0x43, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x68, 0x61, 
-	0x64, 0x65, 0x72, 0x3a, 0x22, 0x7d, 0x0a,
+	0x43, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x20, 0x22, 0x2e, 0x2e, 
+	0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x2e, 0x22, 0x20, 0x73, 0x68, 0x61, 0x64, 
+	0x65, 0x72, 0x3a, 0x22, 0x7d, 0x0a,
 	0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x6c, 0x20, 0x69, 0x6e, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 
 	0x3a, 0x67, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x28, 0x22, 0x5b, 0x5e, 0x5c, 0x6e, 0x5d, 0x2b, 0x22, 0x29, 0x20, 
 	0x64, 0x6f, 0x0a,
@@ -6389,10 +6473,10 @@ const unsigned char graphics_lua[] =
 	0x09, 0x65, 0x6e, 0x64, 0x0a,
 	0x09, 0x2d, 0x2d, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x67, 0x69, 0x63, 0x20, 0x75, 0x6e, 0x69, 0x66, 
 	0x6f, 0x72, 0x6d, 0x20, 0x73, 0x65, 0x74, 0x74, 0x65, 0x72, 0x0a,
-	0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x69, 
-	0x78, 0x65, 0x6c, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x5f, 0x64, 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 
-	0x5f, 0x73, 0x65, 0x6e, 0x64, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2c, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 
-	0x76, 0x61, 0x6c, 0x75, 0x65, 0x2c, 0x20, 0x2e, 0x2e, 0x2e, 0x29, 0x0a,
+	0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x68, 
+	0x61, 0x64, 0x65, 0x72, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x5f, 0x64, 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, 
+	0x68, 0x5f, 0x73, 0x65, 0x6e, 0x64, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2c, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 
+	0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2c, 0x20, 0x2e, 0x2e, 0x2e, 0x29, 0x0a,
 	0x09, 0x09, 0x69, 0x66, 0x20, 0x74, 0x79, 0x70, 0x65, 0x28, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x29, 0x20, 0x3d, 
 	0x3d, 0x20, 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x20, 0x20, 
 	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x73, 0x63, 0x61, 0x6c, 0x61, 0x72, 0x0a,
@@ -6445,36 +6529,85 @@ const unsigned char graphics_lua[] =
 	0x29, 0x2e, 0x22, 0x29, 0x0a,
 	0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
 	0x09, 0x65, 0x6e, 0x64, 0x0a,
-	0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x65, 0x77, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x45, 0x66, 0x66, 
-	0x65, 0x63, 0x74, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 
-	0x73, 0x2e, 0x6e, 0x65, 0x77, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x0a,
+	0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x65, 0x77, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x45, 0x66, 
+	0x66, 0x65, 0x63, 0x74, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 
+	0x63, 0x73, 0x2e, 0x6e, 0x65, 0x77, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x0a,
 	0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 
-	0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x6e, 0x65, 0x77, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x45, 0x66, 0x66, 0x65, 
-	0x63, 0x74, 0x28, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x0a,
+	0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x6e, 0x65, 0x77, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x45, 0x66, 0x66, 
+	0x65, 0x63, 0x74, 0x28, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x66, 0x72, 0x61, 0x67, 
+	0x63, 0x6f, 0x64, 0x65, 0x29, 0x0a,
 	0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x6e, 0x65, 
-	0x77, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 
-	0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x0a,
+	0x77, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x75, 
+	0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x66, 
+	0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x0a,
 	0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 
-	0x74, 0x65, 0x6d, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 
-	0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x28, 0x63, 0x6f, 0x64, 0x65, 0x29, 
-	0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
-	0x09, 0x09, 0x09, 0x09, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 
-	0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x28, 0x63, 0x6f, 0x64, 0x65, 
-	0x29, 0x0a,
+	0x74, 0x65, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
+	0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x61, 0x6e, 
+	0x64, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 
+	0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x28, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x20, 0x74, 
+	0x68, 0x65, 0x6e, 0x0a,
+	0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 
+	0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x72, 0x65, 0x61, 0x64, 
+	0x28, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x0a,
+	0x09, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
+	0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x61, 0x6e, 
+	0x64, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 
+	0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x28, 0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x20, 0x74, 
+	0x68, 0x65, 0x6e, 0x0a,
+	0x09, 0x09, 0x09, 0x09, 0x09, 0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 
+	0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x72, 0x65, 0x61, 0x64, 
+	0x28, 0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x0a,
+	0x09, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
 	0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
-	0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x65, 0x77, 0x50, 0x69, 0x78, 0x65, 0x6c, 
-	0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x28, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x0a,
+	0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x65, 0x77, 0x53, 0x68, 0x61, 0x64, 0x65, 
+	0x72, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x28, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x20, 
+	0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x0a,
 	0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
 	0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x20, 0x3d, 0x20, 0x6c, 
-	0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x6e, 0x65, 0x77, 0x50, 0x69, 
-	0x78, 0x65, 0x6c, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x28, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x0a,
+	0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x6e, 0x65, 0x77, 0x53, 0x68, 
+	0x61, 0x64, 0x65, 0x72, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x28, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 
+	0x65, 0x2c, 0x20, 0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x0a,
 	0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 
 	0x6d, 0x65, 0x74, 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x29, 0x0a,
-	0x09, 0x09, 0x6d, 0x65, 0x74, 0x61, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x70, 0x69, 0x78, 0x65, 
-	0x6c, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x5f, 0x64, 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x73, 
-	0x65, 0x6e, 0x64, 0x0a,
+	0x09, 0x09, 0x6d, 0x65, 0x74, 0x61, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x73, 0x68, 0x61, 0x64, 
+	0x65, 0x72, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x5f, 0x64, 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 
+	0x73, 0x65, 0x6e, 0x64, 0x0a,
 	0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x0a,
 	0x09, 0x65, 0x6e, 0x64, 0x0a,
+	0x09, 0x0a,
+	0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 
+	0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x6e, 0x65, 0x77, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x45, 0x66, 0x66, 0x65, 
+	0x63, 0x74, 0x28, 0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x0a,
+	0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 
+	0x68, 0x69, 0x63, 0x73, 0x2e, 0x6e, 0x65, 0x77, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x45, 0x66, 0x66, 0x65, 
+	0x63, 0x74, 0x28, 0x6e, 0x69, 0x6c, 0x2c, 0x20, 0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x0a,
+	0x09, 0x65, 0x6e, 0x64, 0x0a,
+	0x09, 0x0a,
+	0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 
+	0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x6e, 0x65, 0x77, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x45, 0x66, 0x66, 
+	0x65, 0x63, 0x74, 0x28, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x0a,
+	0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 
+	0x68, 0x69, 0x63, 0x73, 0x2e, 0x6e, 0x65, 0x77, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x45, 0x66, 0x66, 0x65, 
+	0x63, 0x74, 0x28, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x6e, 0x69, 0x6c, 0x29, 0x0a,
+	0x09, 0x65, 0x6e, 0x64, 0x0a,
+	0x09, 0x0a,
+	0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, 
+	0x50, 0x69, 0x78, 0x65, 0x6c, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 
+	0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x53, 0x68, 0x61, 0x64, 0x65, 
+	0x72, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x0a,
+	0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x67, 0x65, 0x74, 
+	0x50, 0x69, 0x78, 0x65, 0x6c, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 
+	0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x53, 0x68, 0x61, 0x64, 0x65, 
+	0x72, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x0a,
+	0x09, 0x0a,
+	0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, 
+	0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 
+	0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x53, 0x68, 0x61, 0x64, 
+	0x65, 0x72, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x0a,
+	0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x67, 0x65, 0x74, 
+	0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 
+	0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x53, 0x68, 0x61, 0x64, 
+	0x65, 0x72, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x0a,
 	0x65, 0x6e, 0x64, 0x0a,
 }; // [graphics.lua]
 } // love