Commits

Anonymous committed eda6915 Merge

Final commit

  • Participants
  • Parent commits 1f2449e, 74430fa

Comments (0)

Files changed (9)

File extra/nsis/love.nsi

 InstallDirRegKey HKCU "Software\LOVE" ""
 
 # Graphics
-!define MUI_ICON "love\extra\nsis\love.ico"
-!define MUI_UNICON "love\extra\nsis\love.ico"
+!define MUI_ICON "${LOVEICODIR}\love.ico"
+!define MUI_UNICON "${LOVEICODIR}\love.ico"
 !define MUI_ABORTWARNING
 !define MUI_HEADERIMAGE
-!define MUI_HEADERIMAGE_BITMAP "love\extra\nsis\top.bmp" # optional
-!define MUI_WELCOMEFINISHPAGE_BITMAP "love\extra\nsis\left.bmp"
-!define MUI_UNWELCOMEFINISHPAGE_BITMAP "love\extra\nsis\left.bmp"
+!define MUI_HEADERIMAGE_BITMAP "${LOVEICODIR}\top.bmp" # optional
+!define MUI_WELCOMEFINISHPAGE_BITMAP "${LOVEICODIR}\left.bmp"
+!define MUI_UNWELCOMEFINISHPAGE_BITMAP "${LOVEICODIR}\left.bmp"
 
 !define MUI_WELCOMEPAGE_TITLE "LÖVE Setup"
 !define MUI_WELCOMEPAGE_TEXT "This will install LÖVE, the unquestionably awesome Lua game framework."
 
 # Pages
 !insertmacro MUI_PAGE_WELCOME
-!insertmacro MUI_PAGE_LICENSE "love\license.txt"
+!insertmacro MUI_PAGE_LICENSE "${LOVELICDIR}\license.txt"
 !insertmacro MUI_PAGE_COMPONENTS
 !insertmacro MUI_PAGE_DIRECTORY
 !insertmacro MUI_PAGE_INSTFILES
 
 	SectionIn RO
 	SetOutPath $INSTDIR
-	File "love\platform\msvc2010\Release\love.exe"
-	File "love\platform\msvc2010\DevIL.dll"
-	File "love\platform\msvc2010\SDL.dll"
-	File "love\platform\msvc2010\OpenAL32.dll"
-	File "love\extra\nsis\love.ico"
-	File "love\extra\nsis\game.ico"
+	File "${LOVEBINDIR}\love.exe"
+	File "${LOVEBINDIR}\DevIL.dll"
+	File "${LOVEBINDIR}\SDL.dll"
+	File "${LOVEBINDIR}\OpenAL32.dll"
+	File "${LOVEBINDIR}\lua51.dll"
+	File "${LOVEICODIR}\love.ico"
+	File "${LOVEICODIR}\game.ico"
 
 	# Uninstaller
 	WriteUninstaller $INSTDIR\Uninstall.exe
 	Delete $INSTDIR\"SDL.dll"
 	Delete $INSTDIR\"love.exe"
 	Delete $INSTDIR\"OpenAL32.dll"
+	Delete $INSTDIR\"lua51.dll"
 	Delete $INSTDIR\"game.ico"
 	Delete $INSTDIR\"love.ico"
 	RMDir $INSTDIR

File src/modules/audio/openal/Source.cpp

 
 	Source::Source(Pool * pool, love::sound::SoundData * soundData)
 		: love::audio::Source(Source::TYPE_STATIC), pool(pool), valid(false),
-		pitch(1.0f), volume(1.0f), looping(false), offsetSamples(0), offsetSeconds(0), decoder(0)
+		pitch(1.0f), volume(1.0f), looping(false), offsetSamples(0), offsetSeconds(0),
+		decoder(0), toLoop(0)
 	{
 		alGenBuffers(1, buffers);
 		ALenum fmt = getFormat(soundData->getChannels(), soundData->getBits());
 
 	Source::Source(Pool * pool, love::sound::Decoder * decoder)
 		: love::audio::Source(Source::TYPE_STREAM), pool(pool), valid(false),
-		pitch(1.0f), volume(1.0f), looping(false), offsetSamples(0), offsetSeconds(0), decoder(decoder)
+		pitch(1.0f), volume(1.0f), looping(false), offsetSamples(0), offsetSeconds(0),
+		decoder(decoder), toLoop(0)
 	{
 		decoder->retain();
 		alGenBuffers(MAX_BUFFERS, buffers);
 			switch (*((Source::Unit*) unit)) {
 				case Source::UNIT_SAMPLES:
 					if (type == TYPE_STREAM) {
+						offsetSamples = offset;
 						ALint buffer;
 						alGetSourcei(source, AL_BUFFER, &buffer);
 						int freq;
 						alGetBufferi(buffer, AL_FREQUENCY, &freq);
 						offset /= freq;
+						offsetSeconds = offset;
 						decoder->seek(offset);
 					} else {
 						alSourcef(source, AL_SAMPLE_OFFSET, offset);
 				case Source::UNIT_SECONDS:	
 				default:
 					if (type == TYPE_STREAM) {
+						offsetSeconds = offset;
 						decoder->seek(offset);
+						ALint buffer;
+						alGetSourcei(source, AL_BUFFER, &buffer);
+						int freq;
+						alGetBufferi(buffer, AL_FREQUENCY, &freq);
+						offsetSamples = offset*freq;
 					} else {
 						alSourcef(source, AL_SEC_OFFSET, offset);
 					}
 					break;
 			}
+			if (type == TYPE_STREAM)
+			{
+				// Because we still have old data
+				// from before the seek in the buffers
+				// let's empty them.
+				stopAtomic(false);
+				playAtomic();
+				toLoop = 0;
+			}
 		}
 	}
 
 		//but this prevents a horrible, horrible bug
 	}
 
-	void Source::stopAtomic()
+	void Source::stopAtomic(bool rewind)
 	{
 		if(valid)
 		{
 
 			alSourcei(source, AL_BUFFER, AL_NONE);
 		}
-		rewindAtomic();
+		if (rewind)
+			rewindAtomic();
 		valid = false;
 	}
 
 			alBufferData(buffer, fmt, d->getBuffer(), decoded, d->getSampleRate());
 
 		if(decoder->isFinished() && isLooping()) {
-			offsetSamples = 0;
-			offsetSeconds = 0;
+			int queued, processed;
+			alGetSourcei(source, AL_BUFFERS_QUEUED, &queued);
+			alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
+			if (queued > processed)
+				toLoop = queued-processed;
+			else
+				toLoop = MAX_BUFFERS-processed;
 			d->rewind();
 		}
 
+		if (toLoop > 0)
+		{
+			if (--toLoop == 0)
+			{
+				offsetSamples = 0;
+				offsetSeconds = 0;
+			}
+		}
+
 		return decoded;
 	}
 

File src/modules/audio/openal/Source.h

 
 		love::sound::Decoder * decoder;
 
+		unsigned int toLoop;
+
 	public:
 		Source(Pool * pool, love::sound::SoundData * soundData);
 		Source(Pool * pool, love::sound::Decoder * decoder);
 		bool isStatic() const;
 
 		void playAtomic();
-		void stopAtomic();
+		void stopAtomic(bool rewind = true);
 		void pauseAtomic();
 		void resumeAtomic();
 		void rewindAtomic();

File src/modules/graphics/opengl/SpriteBatch.cpp

 namespace opengl
 {
 	SpriteBatch::SpriteBatch(Image * image, int size, int usage)
-		: image(image), size(size), next(0), usage(usage), lockp(0)
+		: image(image), size(size), next(0), usage(usage), lockp(0), color(0)
 	{
 		if (!(GLEE_ARB_vertex_buffer_object || GLEE_VERSION_1_5))
 			throw love::Exception("Your OpenGL version does not support SpriteBatches. Go upgrade!");
 
 		delete [] vertices;
 		delete [] indices;
+		delete color;
 	}
 
 	bool SpriteBatch::loadVolatile()
 			t.setTransformation(x, y, a, sx, sy, ox, oy, kx, ky);
 			t.transform(v, v, 4);
 
+			if (color)
+				setColorv(v, *color);
+
 			addv(v);
 
 			// Increment counter.
 			t.setTransformation(x, y, a, sx, sy, ox, oy, kx, ky);
 			t.transform(v, v, 4);
 
+			if (color)
+				setColorv(v, *color);
+
 			addv(v);
 
 			// Increment counter.
 		image->retain();
 	}
 
+	void SpriteBatch::setColor(const Color & color)
+	{
+		if(!this->color)
+			this->color = new Color(color);
+		else
+			*(this->color) = color;
+	}
+
+	void SpriteBatch::setColor()
+	{
+		delete color;
+		color = 0;
+	}
+
 	void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const
 	{
 		static Matrix t;
 		// Bind the VBO buffer.
 		glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo[0]);
 		glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, vbo[1]);
+
+		// Apply per-sprite color, if a color is set.
+		if (color)
+		{
+			glEnableClientState(GL_COLOR_ARRAY);
+			glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(vertex), 0);
+		}
+
 		glVertexPointer(2, GL_FLOAT, sizeof(vertex), (GLvoid*)(sizeof(unsigned char)*4));
 		glTexCoordPointer(2, GL_FLOAT, sizeof(vertex), (GLvoid*)(sizeof(unsigned char)*4+sizeof(float)*2));
 		
 		glDrawElements(GL_TRIANGLES, next*6, GL_UNSIGNED_SHORT, 0);
 
 		// Disable vertex arrays.
+		glDisableClientState(GL_COLOR_ARRAY);
 		glDisableClientState(GL_TEXTURE_COORD_ARRAY);
 		glDisableClientState(GL_VERTEX_ARRAY);
 
 		}
 	}
 
+	void SpriteBatch::setColorv(vertex * v, const Color & color)
+	{
+		v[0].r = color.r; v[0].g = color.g; v[0].b = color.b; v[0].a = color.a;
+		v[1].r = color.r; v[1].g = color.g; v[1].b = color.b; v[1].a = color.a;
+		v[2].r = color.r; v[2].g = color.g; v[2].b = color.b; v[2].a = color.a;
+		v[3].r = color.r; v[3].g = color.g; v[3].b = color.b; v[3].a = color.a;
+	}
+
 } // opengl
 } // graphics
 } // love

File src/modules/graphics/opengl/SpriteBatch.h

 #include <common/Matrix.h>
 #include <graphics/Drawable.h>
 #include <graphics/Volatile.h>
+#include <graphics/Color.h>
 
 // OpenGL
 #include "GLee.h"
 		// If the buffer is locked, this pointer is nonzero.
 		vertex * lockp;
 
+		// Current color. This color, if present, will be applied to the next
+		// added quad.
+		Color * color;
+
 	public:
 
 		enum UsageHint
 
 		void setImage(Image * newimage);
 
+		/**
+		 * Set the current color for this SpriteBatch. The geometry added
+		 * after this call will use this color. Note that global color
+		 * will not longer apply to the SpriteBatch if this is used.
+		 *
+		 * @param color The color to use for the following geometry.
+		 */
+		void setColor(const Color & color);
+
+		/**
+		 * Disable per-quad colors for this SpriteBatch. The next call to
+		 * draw will use the global color for all sprites.
+		 */
+		void setColor();
+
 		// Implements Drawable.
 		void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const;
 
 
 		void addv(const vertex * v);
 
+		/**
+		 * Set the color for vertices.
+		 *
+		 * @param v The vertices to set the color for. Must be an array of
+		 *          of size 4.
+		 * @param color The color to assign to each vertex.
+		 */
+		void setColorv(vertex * v, const Color & color);
+
 	}; // SpriteBatch
 
 } // opengl

File src/modules/graphics/opengl/wrap_Graphics.cpp

 			luax_newtype(L, "PixelEffect", GRAPHICS_PIXELEFFECT_T, (void*)effect);
 		} catch (love::Exception& e) {
 			// memory is freed in Graphics::newPixelEffect
-			return luaL_error(L, e.what());
+			luax_getfunction(L, "graphics", "_transformGLSLErrorMessages");
+			lua_pushstring(L, e.what());
+			lua_pcall(L, 1,1, 0);
+			const char* err = lua_tostring(L, -1);
+			return luaL_error(L, err);
 		}
 
 		return 1;

File src/modules/graphics/opengl/wrap_SpriteBatch.cpp

 		return 0;
 	}
 
+	int w_SpriteBatch_setColor(lua_State * L)
+	{
+		SpriteBatch * t = luax_checkspritebatch(L, 1);
+
+		if (lua_gettop(L) <= 1)
+			t->setColor();
+		else
+		{
+			Color c;
+			c.r = (unsigned char)luaL_checkint(L, 2);
+			c.g = (unsigned char)luaL_checkint(L, 3);
+			c.b = (unsigned char)luaL_checkint(L, 4);
+			c.a = (unsigned char)luaL_optint(L, 5, 255);
+			t->setColor(c);
+		}
+
+		return 0;
+	}
+
 	static const luaL_Reg functions[] = {
 		{ "add", w_SpriteBatch_add },
 		{ "addq", w_SpriteBatch_addq },
 		{ "bind", w_SpriteBatch_bind },
 		{ "unbind", w_SpriteBatch_unbind },
 		{ "setImage", w_SpriteBatch_setImage },
+		{ "setColor", w_SpriteBatch_setColor },
 		{ 0, 0 }
 	};
 

File src/scripts/graphics.lua

 		love.graphics.printf = love.graphics.printf1
 	end
 
-	-- TRANSFORM OBJECTS
-	local function unpack_transform(transform, ...)
-		if type(transform) ~= "table" then
-			return transform, ...
-		end
-
-		local r = transform.rot or transform.r or 0
-		local sx = transform.sx or transform.scale or 1
-		local sy = transform.sy or transform.scale or 1
-		local ox, oy = transform.ox or 0, transform.oy or 0
-		local kx, ky = transform.kx or 0, transform.ky or 0
-
-		return r,sx,sy,ox,oy,kx,ky
-	end
-
-	local draw = love.graphics.draw
-	function love.graphics.draw(drawable, x, y, ...)
-		return draw(drawable, x, y, unpack_transform(...))
-	end
-
-	local drawq = love.graphics.drawq
-	function love.graphics.drawq(img, quad, x, y, ...)
-		return drawq(img, quad, x, y, unpack_transform(...))
-	end
-
-	local lgprint = love.graphics.print1 -- << notice the 1
-	function love.graphics.print1(text, x,y, ...)
-		return lgprint(text, x,y, unpack_transform(...))
-	end
-
-	local newSpritebatch = love.graphics.newSpriteBatch
-	function love.graphics.newSpriteBatch(image, size)
-		local sb = newSpritebatch(image, size)
-		local meta = getmetatable(sb)
-
-		local add = meta.add
-		function meta:add(x,y, ...)
-			return add(self, x,y, unpack_transform(...))
-		end
-
-		local addq = meta.addq
-		function meta:addq(quad, x,y, ...)
-			return addq(self, quad, x,y, unpack_transform(...))
-		end
-
-		love.graphics.newSpriteBatch = newSpritebatch
-		return sb
-	end
-
-
 	-- PIXEL EFFECTS
 	function love.graphics._effectCodeToGLSL(code)
 		local header = [[#version 120
 		return table.concat{header, code, footer}
 	end
 
-	local function _beautifyGLSLErrors(message)
+	function love.graphics._transformGLSLErrorMessages(message)
 		if not message:match("Cannot compile shader") then return message end
 		local lines = {"Cannot compile shader:"}
 		for l in message:gmatch("[^\n]+") do
 				linenumber, what, message = l:match("^%w+: 0:(%d+):%s*(%w+)%([^%)]+%)%s*(.+)$")
 			end
 			if linenumber and what and message then
-				lines[#lines+1] = ("%s in line %d: %s"):format(what, linenumber - 5, message)
+				lines[#lines+1] = ("Line %d: %s: %s"):format(linenumber - 5, what, message)
 			end
 		end
 		-- did not match any known error messages
 			if love.filesystem and love.filesystem.exists(code) then
 				code = love.filesystem.read(code)
 			end
-			local success, result = pcall(newPixelEffect, code)
-			if not success then
-				error(_beautifyGLSLErrors(result))
-			end
-			return result
+			return newPixelEffect(code)
 		end
 
 		local effect = love.graphics.newPixelEffect(code)

File src/scripts/graphics.lua.h

 	0x69, 0x6e, 0x74, 0x66, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 
 	0x63, 0x73, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x66, 0x31, 0x0a,
 	0x09, 0x65, 0x6e, 0x64, 0x0a,0x0a,
-	0x09, 0x2d, 0x2d, 0x20, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x4f, 0x52, 0x4d, 0x20, 0x4f, 0x42, 0x4a, 0x45, 
-	0x43, 0x54, 0x53, 0x0a,
-	0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x6e, 
-	0x70, 0x61, 0x63, 0x6b, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x28, 0x74, 0x72, 0x61, 
-	0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x2c, 0x20, 0x2e, 0x2e, 0x2e, 0x29, 0x0a,
-	0x09, 0x09, 0x69, 0x66, 0x20, 0x74, 0x79, 0x70, 0x65, 0x28, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 
-	0x6d, 0x29, 0x20, 0x7e, 0x3d, 0x20, 0x22, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
-	0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 
-	0x6d, 0x2c, 0x20, 0x2e, 0x2e, 0x2e, 0x0a,
-	0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,0x0a,
-	0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x72, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 
-	0x6f, 0x72, 0x6d, 0x2e, 0x72, 0x6f, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 
-	0x72, 0x6d, 0x2e, 0x72, 0x20, 0x6f, 0x72, 0x20, 0x30, 0x0a,
-	0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x78, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 
-	0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x73, 0x78, 0x20, 0x6f, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 
-	0x72, 0x6d, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x31, 0x0a,
-	0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x79, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 
-	0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x73, 0x79, 0x20, 0x6f, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 
-	0x72, 0x6d, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x31, 0x0a,
-	0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x78, 0x2c, 0x20, 0x6f, 0x79, 0x20, 0x3d, 0x20, 0x74, 
-	0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x6f, 0x78, 0x20, 0x6f, 0x72, 0x20, 0x30, 0x2c, 0x20, 
-	0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x6f, 0x79, 0x20, 0x6f, 0x72, 0x20, 0x30, 0x0a,
-	0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6b, 0x78, 0x2c, 0x20, 0x6b, 0x79, 0x20, 0x3d, 0x20, 0x74, 
-	0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x6b, 0x78, 0x20, 0x6f, 0x72, 0x20, 0x30, 0x2c, 0x20, 
-	0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x6b, 0x79, 0x20, 0x6f, 0x72, 0x20, 0x30, 0x0a,0x0a,
-	0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x2c, 0x73, 0x78, 0x2c, 0x73, 0x79, 0x2c, 0x6f, 
-	0x78, 0x2c, 0x6f, 0x79, 0x2c, 0x6b, 0x78, 0x2c, 0x6b, 0x79, 0x0a,
-	0x09, 0x65, 0x6e, 0x64, 0x0a,0x0a,
-	0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x64, 0x72, 0x61, 0x77, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 
-	0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x64, 0x72, 0x61, 0x77, 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, 0x64, 0x72, 0x61, 0x77, 0x28, 0x64, 0x72, 0x61, 0x77, 0x61, 0x62, 0x6c, 
-	0x65, 0x2c, 0x20, 0x78, 0x2c, 0x20, 0x79, 0x2c, 0x20, 0x2e, 0x2e, 0x2e, 0x29, 0x0a,
-	0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x64, 0x72, 0x61, 0x77, 0x28, 0x64, 0x72, 0x61, 0x77, 
-	0x61, 0x62, 0x6c, 0x65, 0x2c, 0x20, 0x78, 0x2c, 0x20, 0x79, 0x2c, 0x20, 0x75, 0x6e, 0x70, 0x61, 0x63, 0x6b, 
-	0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x28, 0x2e, 0x2e, 0x2e, 0x29, 0x29, 0x0a,
-	0x09, 0x65, 0x6e, 0x64, 0x0a,0x0a,
-	0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x64, 0x72, 0x61, 0x77, 0x71, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 
-	0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x64, 0x72, 0x61, 0x77, 0x71, 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, 0x64, 0x72, 0x61, 0x77, 0x71, 0x28, 0x69, 0x6d, 0x67, 0x2c, 0x20, 0x71, 
-	0x75, 0x61, 0x64, 0x2c, 0x20, 0x78, 0x2c, 0x20, 0x79, 0x2c, 0x20, 0x2e, 0x2e, 0x2e, 0x29, 0x0a,
-	0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x64, 0x72, 0x61, 0x77, 0x71, 0x28, 0x69, 0x6d, 0x67, 
-	0x2c, 0x20, 0x71, 0x75, 0x61, 0x64, 0x2c, 0x20, 0x78, 0x2c, 0x20, 0x79, 0x2c, 0x20, 0x75, 0x6e, 0x70, 0x61, 
-	0x63, 0x6b, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x28, 0x2e, 0x2e, 0x2e, 0x29, 0x29, 0x0a,
-	0x09, 0x65, 0x6e, 0x64, 0x0a,0x0a,
-	0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, 0x67, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x6c, 
-	0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 
-	0x31, 0x20, 0x2d, 0x2d, 0x20, 0x3c, 0x3c, 0x20, 0x6e, 0x6f, 0x74, 0x69, 0x63, 0x65, 0x20, 0x74, 0x68, 0x65, 
-	0x20, 0x31, 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, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x31, 0x28, 0x74, 0x65, 0x78, 0x74, 0x2c, 
-	0x20, 0x78, 0x2c, 0x79, 0x2c, 0x20, 0x2e, 0x2e, 0x2e, 0x29, 0x0a,
-	0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x67, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x74, 
-	0x65, 0x78, 0x74, 0x2c, 0x20, 0x78, 0x2c, 0x79, 0x2c, 0x20, 0x75, 0x6e, 0x70, 0x61, 0x63, 0x6b, 0x5f, 0x74, 
-	0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x28, 0x2e, 0x2e, 0x2e, 0x29, 0x29, 0x0a,
-	0x09, 0x65, 0x6e, 0x64, 0x0a,0x0a,
-	0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x65, 0x77, 0x53, 0x70, 0x72, 0x69, 0x74, 0x65, 0x62, 0x61, 
-	0x74, 0x63, 0x68, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 
-	0x73, 0x2e, 0x6e, 0x65, 0x77, 0x53, 0x70, 0x72, 0x69, 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 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, 0x53, 0x70, 0x72, 0x69, 0x74, 0x65, 0x42, 0x61, 0x74, 
-	0x63, 0x68, 0x28, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2c, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x29, 0x0a,
-	0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x62, 0x20, 0x3d, 0x20, 0x6e, 0x65, 0x77, 0x53, 0x70, 
-	0x72, 0x69, 0x74, 0x65, 0x62, 0x61, 0x74, 0x63, 0x68, 0x28, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2c, 0x20, 0x73, 
-	0x69, 0x7a, 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, 0x73, 0x62, 0x29, 0x0a,0x0a,
-	0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x61, 0x64, 0x64, 0x20, 0x3d, 0x20, 0x6d, 0x65, 0x74, 0x61, 
-	0x2e, 0x61, 0x64, 0x64, 0x0a,
-	0x09, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x3a, 0x61, 0x64, 
-	0x64, 0x28, 0x78, 0x2c, 0x79, 0x2c, 0x20, 0x2e, 0x2e, 0x2e, 0x29, 0x0a,
-	0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x64, 0x64, 0x28, 0x73, 0x65, 0x6c, 0x66, 
-	0x2c, 0x20, 0x78, 0x2c, 0x79, 0x2c, 0x20, 0x75, 0x6e, 0x70, 0x61, 0x63, 0x6b, 0x5f, 0x74, 0x72, 0x61, 0x6e, 
-	0x73, 0x66, 0x6f, 0x72, 0x6d, 0x28, 0x2e, 0x2e, 0x2e, 0x29, 0x29, 0x0a,
-	0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,0x0a,
-	0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x61, 0x64, 0x64, 0x71, 0x20, 0x3d, 0x20, 0x6d, 0x65, 0x74, 
-	0x61, 0x2e, 0x61, 0x64, 0x64, 0x71, 0x0a,
-	0x09, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x3a, 0x61, 0x64, 
-	0x64, 0x71, 0x28, 0x71, 0x75, 0x61, 0x64, 0x2c, 0x20, 0x78, 0x2c, 0x79, 0x2c, 0x20, 0x2e, 0x2e, 0x2e, 0x29, 0x0a,
-	0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x64, 0x64, 0x71, 0x28, 0x73, 0x65, 0x6c, 
-	0x66, 0x2c, 0x20, 0x71, 0x75, 0x61, 0x64, 0x2c, 0x20, 0x78, 0x2c, 0x79, 0x2c, 0x20, 0x75, 0x6e, 0x70, 0x61, 
-	0x63, 0x6b, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x28, 0x2e, 0x2e, 0x2e, 0x29, 0x29, 0x0a,
-	0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,0x0a,
-	0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x6e, 0x65, 
-	0x77, 0x53, 0x70, 0x72, 0x69, 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x20, 0x3d, 0x20, 0x6e, 0x65, 0x77, 
-	0x53, 0x70, 0x72, 0x69, 0x74, 0x65, 0x62, 0x61, 0x74, 0x63, 0x68, 0x0a,
-	0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x62, 0x0a,
-	0x09, 0x65, 0x6e, 0x64, 0x0a,0x0a,0x0a,
 	0x09, 0x2d, 0x2d, 0x20, 0x50, 0x49, 0x58, 0x45, 0x4c, 0x20, 0x45, 0x46, 0x46, 0x45, 0x43, 0x54, 0x53, 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, 
 	0x63, 0x61, 0x74, 0x7b, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2c, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x20, 
 	0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x7d, 0x0a,
 	0x09, 0x65, 0x6e, 0x64, 0x0a,0x0a,
-	0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5f, 0x62, 
-	0x65, 0x61, 0x75, 0x74, 0x69, 0x66, 0x79, 0x47, 0x4c, 0x53, 0x4c, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x28, 
-	0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x29, 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, 
 	0x6e, 0x64, 0x20, 0x77, 0x68, 0x61, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 
 	0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
 	0x09, 0x09, 0x09, 0x09, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x5b, 0x23, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x2b, 0x31, 
-	0x5d, 0x20, 0x3d, 0x20, 0x28, 0x22, 0x25, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x25, 
-	0x64, 0x3a, 0x20, 0x25, 0x73, 0x22, 0x29, 0x3a, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, 0x77, 0x68, 0x61, 
-	0x74, 0x2c, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x2d, 0x20, 0x35, 0x2c, 
-	0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x29, 0x0a,
+	0x5d, 0x20, 0x3d, 0x20, 0x28, 0x22, 0x4c, 0x69, 0x6e, 0x65, 0x20, 0x25, 0x64, 0x3a, 0x20, 0x25, 0x73, 0x3a, 
+	0x20, 0x25, 0x73, 0x22, 0x29, 0x3a, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x6e, 
+	0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x2d, 0x20, 0x35, 0x2c, 0x20, 0x77, 0x68, 0x61, 0x74, 0x2c, 0x20, 0x6d, 
+	0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x29, 0x0a,
 	0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
 	0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
 	0x09, 0x09, 0x2d, 0x2d, 0x20, 0x64, 0x69, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 
 	0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x28, 0x63, 0x6f, 0x64, 0x65, 
 	0x29, 0x0a,
 	0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
-	0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2c, 0x20, 
-	0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x20, 0x3d, 0x20, 0x70, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x6e, 0x65, 0x77, 
-	0x50, 0x69, 0x78, 0x65, 0x6c, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x2c, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x0a,
-	0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 
-	0x74, 0x68, 0x65, 0x6e, 0x0a,
-	0x09, 0x09, 0x09, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x5f, 0x62, 0x65, 0x61, 0x75, 0x74, 0x69, 0x66, 
-	0x79, 0x47, 0x4c, 0x53, 0x4c, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x28, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 
-	0x29, 0x29, 0x0a,
-	0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
-	0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 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, 0x65, 0x6e, 0x64, 0x0a,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,