Browse Source

Applied the new style guidelines.

Well, sort of. Lot's more to be done, but this is a start.
rude 13 years ago
parent
commit
81c38e22d0
100 changed files with 13261 additions and 13105 deletions
  1. 58 56
      src/common/Data.h
  2. 100 99
      src/common/EnumMap.h
  3. 65 62
      src/common/Exception.cpp
  4. 67 64
      src/common/Exception.h
  5. 198 196
      src/common/Matrix.cpp
  6. 167 166
      src/common/Matrix.h
  7. 45 44
      src/common/Memoizer.cpp
  8. 46 46
      src/common/Memoizer.h
  9. 55 55
      src/common/Module.h
  10. 52 52
      src/common/Object.cpp
  11. 76 76
      src/common/Object.h
  12. 82 81
      src/common/Reference.cpp
  13. 88 87
      src/common/Reference.h
  14. 168 167
      src/common/StringMap.h
  15. 175 173
      src/common/Variant.cpp
  16. 76 73
      src/common/Variant.h
  17. 25 25
      src/common/Vector.cpp
  18. 311 310
      src/common/Vector.h
  19. 80 78
      src/common/b64.cpp
  20. 40 38
      src/common/b64.h
  21. 93 93
      src/common/config.h
  22. 42 41
      src/common/delay.cpp
  23. 33 33
      src/common/delay.h
  24. 65 64
      src/common/int.h
  25. 85 85
      src/common/math.h
  26. 481 480
      src/common/runtime.cpp
  27. 384 383
      src/common/runtime.h
  28. 174 173
      src/common/types.h
  29. 61 60
      src/common/utf8.cpp
  30. 47 46
      src/common/utf8.h
  31. 37 36
      src/common/version.h
  32. 58 56
      src/common/wrap_Data.cpp
  33. 38 37
      src/common/wrap_Data.h
  34. 34 34
      src/launcher.cpp
  35. 363 363
      src/love.cpp
  36. 52 51
      src/modules/audio/Audio.cpp
  37. 239 234
      src/modules/audio/Audio.h
  38. 74 73
      src/modules/audio/Source.cpp
  39. 119 119
      src/modules/audio/Source.h
  40. 168 167
      src/modules/audio/null/Audio.cpp
  41. 89 87
      src/modules/audio/null/Audio.h
  42. 205 205
      src/modules/audio/null/Source.cpp
  43. 94 93
      src/modules/audio/null/Source.h
  44. 319 316
      src/modules/audio/openal/Audio.cpp
  45. 142 140
      src/modules/audio/openal/Audio.h
  46. 293 292
      src/modules/audio/openal/Pool.cpp
  47. 124 126
      src/modules/audio/openal/Pool.h
  48. 724 698
      src/modules/audio/openal/Source.cpp
  49. 150 151
      src/modules/audio/openal/Source.h
  50. 343 339
      src/modules/audio/wrap_Audio.cpp
  51. 61 60
      src/modules/audio/wrap_Audio.h
  52. 320 318
      src/modules/audio/wrap_Source.cpp
  53. 66 65
      src/modules/audio/wrap_Source.h
  54. 297 295
      src/modules/event/Event.cpp
  55. 83 83
      src/modules/event/Event.h
  56. 314 313
      src/modules/event/sdl/Event.cpp
  57. 82 81
      src/modules/event/sdl/Event.h
  58. 150 148
      src/modules/event/sdl/wrap_Event.cpp
  59. 48 47
      src/modules/event/sdl/wrap_Event.h
  60. 53 52
      src/modules/filesystem/File.cpp
  61. 178 177
      src/modules/filesystem/File.h
  62. 91 88
      src/modules/filesystem/FileData.cpp
  63. 84 85
      src/modules/filesystem/FileData.h
  64. 243 240
      src/modules/filesystem/physfs/File.cpp
  65. 89 88
      src/modules/filesystem/physfs/File.h
  66. 610 605
      src/modules/filesystem/physfs/Filesystem.cpp
  67. 297 297
      src/modules/filesystem/physfs/Filesystem.h
  68. 227 225
      src/modules/filesystem/physfs/wrap_File.cpp
  69. 52 50
      src/modules/filesystem/physfs/wrap_File.h
  70. 71 69
      src/modules/filesystem/physfs/wrap_FileData.cpp
  71. 45 43
      src/modules/filesystem/physfs/wrap_FileData.h
  72. 443 440
      src/modules/filesystem/physfs/wrap_Filesystem.cpp
  73. 75 74
      src/modules/filesystem/physfs/wrap_Filesystem.h
  74. 54 54
      src/modules/font/Font.h
  75. 127 122
      src/modules/font/GlyphData.cpp
  76. 134 133
      src/modules/font/GlyphData.h
  77. 153 151
      src/modules/font/ImageRasterizer.cpp
  78. 71 70
      src/modules/font/ImageRasterizer.h
  79. 53 53
      src/modules/font/Rasterizer.cpp
  80. 97 96
      src/modules/font/Rasterizer.h
  81. 79 78
      src/modules/font/freetype/Font.cpp
  82. 74 75
      src/modules/font/freetype/Font.h
  83. 122 118
      src/modules/font/freetype/TrueTypeRasterizer.cpp
  84. 68 69
      src/modules/font/freetype/TrueTypeRasterizer.h
  85. 113 110
      src/modules/font/freetype/wrap_Font.cpp
  86. 43 42
      src/modules/font/freetype/wrap_Font.h
  87. 46 44
      src/modules/font/wrap_GlyphData.cpp
  88. 41 40
      src/modules/font/wrap_GlyphData.h
  89. 46 44
      src/modules/font/wrap_Rasterizer.cpp
  90. 39 38
      src/modules/font/wrap_Rasterizer.h
  91. 109 103
      src/modules/graphics/Color.h
  92. 33 33
      src/modules/graphics/DrawQable.cpp
  93. 65 64
      src/modules/graphics/DrawQable.h
  94. 33 33
      src/modules/graphics/Drawable.cpp
  95. 64 63
      src/modules/graphics/Drawable.h
  96. 166 165
      src/modules/graphics/Graphics.cpp
  97. 144 143
      src/modules/graphics/Graphics.h
  98. 82 77
      src/modules/graphics/Image.cpp
  99. 85 85
      src/modules/graphics/Image.h
  100. 37 36
      src/modules/graphics/Quad.cpp

+ 58 - 56
src/common/Data.h

@@ -1,56 +1,58 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_DATA_H
-#define LOVE_DATA_H
-
-// LOVE
-#include "config.h"
-#include "Object.h"
-
-namespace love
-{
-	/**
-	* This class is a simple abstraction over all objects which contain data.
-	**/
-	class Data : public Object
-	{
-	public:
-
-		/**
-		* Destructor.
-		**/
-		virtual ~Data() {};
-
-		/**
-		* Gets a pointer to the data. This pointer will obviously not
-		* be valid if the Data object is destroyed.
-		**/
-		virtual void * getData() const = 0 ;
-
-		/**
-		* Gets the size of the Data in bytes.
-		**/
-		virtual int getSize() const = 0;
-
-	}; // Data
-} // love
-
-#endif // LOVE_DATA_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_DATA_H
+#define LOVE_DATA_H
+
+// LOVE
+#include "config.h"
+#include "Object.h"
+
+namespace love
+{
+
+/**
+ * This class is a simple abstraction over all objects which contain data.
+ **/
+class Data : public Object
+{
+public:
+
+	/**
+	 * Destructor.
+	 **/
+	virtual ~Data() {};
+
+	/**
+	 * Gets a pointer to the data. This pointer will obviously not
+	 * be valid if the Data object is destroyed.
+	 **/
+	virtual void *getData() const = 0 ;
+
+	/**
+	 * Gets the size of the Data in bytes.
+	 **/
+	virtual int getSize() const = 0;
+
+}; // Data
+
+} // love
+
+#endif // LOVE_DATA_H

+ 100 - 99
src/common/EnumMap.h

@@ -1,99 +1,100 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_ENUM_MAP_H
-#define LOVE_ENUM_MAP_H
-
-#include "Exception.h"
-
-namespace love
-{
-	template<typename T, typename U, unsigned PEAK>
-	class EnumMap
-	{
-	private:
-
-		struct Value
-		{
-			unsigned v;
-			bool set;
-			Value() : set(false) {}
-		};
-
-		Value values_t[PEAK];
-		Value values_u[PEAK];
-
-	public:
-
-		struct Entry
-		{
-			T t;
-			U u;
-		};
-
-		EnumMap(Entry * entries, unsigned size)
-		{
-			unsigned n = size/sizeof(Entry);
-
-			for (unsigned i = 0; i<n; ++i)
-			{
-				unsigned e_t = (unsigned)entries[i].t;
-				unsigned e_u = (unsigned)entries[i].u;
-
-				if (e_t < PEAK)
-				{
-					values_u[e_t].v = e_u;
-					values_u[e_t].set = true;
-				}
-				if (e_u < PEAK)
-				{
-					values_t[e_u].v = e_t;
-					values_t[e_u].set = true;
-				}
-			}
-		}
-
-		bool find(T t, U & u)
-		{
-			if ((unsigned)t < PEAK && values_u[(unsigned)t].set)
-			{
-				u = (U)values_u[(unsigned)t].v;
-				return true;
-			}
-
-			return false;
-		}
-
-		bool find(U u, T & t)
-		{
-			if ((unsigned)u < PEAK && values_t[(unsigned)u].set)
-			{
-				t = (T)values_t[(unsigned)u].v;
-				return true;
-			}
-
-			return false;
-		}
-
-	}; // EnumMap
-
-} // love
-
-#endif // LOVE_ENUM_MAP_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_ENUM_MAP_H
+#define LOVE_ENUM_MAP_H
+
+#include "Exception.h"
+
+namespace love
+{
+
+template<typename T, typename U, unsigned PEAK>
+class EnumMap
+{
+public:
+
+	struct Entry
+	{
+		T t;
+		U u;
+	};
+
+	EnumMap(Entry *entries, unsigned size)
+	{
+		unsigned n = size/sizeof(Entry);
+
+		for (unsigned i = 0; i<n; ++i)
+		{
+			unsigned e_t = (unsigned)entries[i].t;
+			unsigned e_u = (unsigned)entries[i].u;
+
+			if (e_t < PEAK)
+			{
+				values_u[e_t].v = e_u;
+				values_u[e_t].set = true;
+			}
+			if (e_u < PEAK)
+			{
+				values_t[e_u].v = e_t;
+				values_t[e_u].set = true;
+			}
+		}
+	}
+
+	bool find(T t, U &u)
+	{
+		if ((unsigned)t < PEAK && values_u[(unsigned)t].set)
+		{
+			u = (U)values_u[(unsigned)t].v;
+			return true;
+		}
+
+		return false;
+	}
+
+	bool find(U u, T &t)
+	{
+		if ((unsigned)u < PEAK && values_t[(unsigned)u].set)
+		{
+			t = (T)values_t[(unsigned)u].v;
+			return true;
+		}
+
+		return false;
+	}
+
+private:
+
+	struct Value
+	{
+		unsigned v;
+		bool set;
+		Value() : set(false) {}
+	};
+
+	Value values_t[PEAK];
+	Value values_u[PEAK];
+
+}; // EnumMap
+
+} // love
+
+#endif // LOVE_ENUM_MAP_H

+ 65 - 62
src/common/Exception.cpp

@@ -1,62 +1,65 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "Exception.h"
-#include <common/config.h>
-#include <iostream>
-using namespace std;
-
-namespace love
-{
-	Exception::Exception(const char * fmt, ...)
-	{
-		va_list args;
-		int size_buffer = 256, size_out;
-		char * buffer;
-		while (true)
-		{
-			buffer = new char[size_buffer];
-			memset(buffer, 0, size_buffer);
-
-			va_start(args, fmt);
-			size_out = vsnprintf(buffer, size_buffer, fmt, args);
-			va_end(args);
-
-			// see http://perfec.to/vsnprintf/pasprintf.c
-			// if size_out ...
-			//      == -1             --> output was truncated
-			//      == size_buffer    --> output was truncated
-			//      == size_buffer-1  --> ambiguous, /may/ have been truncated
-			//       > size_buffer    --> output was truncated, and size_out
-			//                            bytes would have been written
-			if (size_out == size_buffer || size_out == -1 || size_out == size_buffer-1)
-				size_buffer *= 2;
-			else if (size_out > size_buffer)
-				size_buffer = size_out + 2; // to avoid the ambiguous case
-			else
-				break;
-
-			delete[] buffer;
-		}
-		message = std::string(buffer);
-		delete[] buffer;
-	}
-
-}
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "Exception.h"
+#include "common/config.h"
+
+#include <iostream>
+
+using namespace std;
+
+namespace love
+{
+
+Exception::Exception(const char *fmt, ...)
+{
+	va_list args;
+	int size_buffer = 256, size_out;
+	char *buffer;
+	while (true)
+	{
+		buffer = new char[size_buffer];
+		memset(buffer, 0, size_buffer);
+
+		va_start(args, fmt);
+		size_out = vsnprintf(buffer, size_buffer, fmt, args);
+		va_end(args);
+
+		// see http://perfec.to/vsnprintf/pasprintf.c
+		// if size_out ...
+		//      == -1             --> output was truncated
+		//      == size_buffer    --> output was truncated
+		//      == size_buffer-1  --> ambiguous, /may/ have been truncated
+		//       > size_buffer    --> output was truncated, and size_out
+		//                            bytes would have been written
+		if (size_out == size_buffer || size_out == -1 || size_out == size_buffer-1)
+			size_buffer *= 2;
+		else if (size_out > size_buffer)
+			size_buffer = size_out + 2; // to avoid the ambiguous case
+		else
+			break;
+
+		delete[] buffer;
+	}
+	message = std::string(buffer);
+	delete[] buffer;
+}
+
+}

+ 67 - 64
src/common/Exception.h

@@ -1,64 +1,67 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_EXCEPTION_H
-#define LOVE_EXCEPTION_H
-
-#include <exception>
-#include <cstdarg> // vararg
-#include <cstdio> // vsnprintf
-#include <cstring> // strncpy
-#include <string>
-
-namespace love
-{
-	/**
-	* A convenient vararg-enabled exception class.
-	**/
-	class Exception : public std::exception
-	{
-	private:
-
-		std::string message;
-
-	public:
-
-		/**
-		* Creates a new Exception according to printf-rules.
-		*
-		* See: http://www.cplusplus.com/reference/clibrary/cstdio/printf/
-		*
-		* @param fmt The format string (see printf).
-		**/
-		Exception(const char * fmt, ...);
-		virtual ~Exception() throw() {}
-
-		/**
-		* Returns a string containing reason for the exception.
-		* @return A description of the exception.
-		**/
-		inline virtual const char * what() const throw()
-		{ return message.c_str(); }
-
-	}; // class
-
-} // love
-
-#endif // LOVE_EXCEPTION_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_EXCEPTION_H
+#define LOVE_EXCEPTION_H
+
+#include <exception>
+#include <cstdarg> // vararg
+#include <cstdio> // vsnprintf
+#include <cstring> // strncpy
+#include <string>
+
+namespace love
+{
+
+/**
+ * A convenient vararg-enabled exception class.
+ **/
+class Exception : public std::exception
+{
+public:
+
+	/**
+	 * Creates a new Exception according to printf-rules.
+	 *
+	 * See: http://www.cplusplus.com/reference/clibrary/cstdio/printf/
+	 *
+	 * @param fmt The format string (see printf).
+	 **/
+	Exception(const char *fmt, ...);
+	virtual ~Exception() throw() {}
+
+	/**
+	 * Returns a string containing reason for the exception.
+	 * @return A description of the exception.
+	 **/
+	inline virtual const char *what() const throw()
+	{
+		return message.c_str();
+	}
+
+private:
+
+	std::string message;
+
+}; // Exception
+
+} // love
+
+#endif // LOVE_EXCEPTION_H

+ 198 - 196
src/common/Matrix.cpp

@@ -1,196 +1,198 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "Matrix.h"
-
-// STD
-#include <cstring> // memcpy
-#include <cmath>
-
-namespace love
-{
-
-	// | e0 e4 e8  e12 |
-	// | e1 e5 e9  e13 |
-	// | e2 e6 e10 e14 |
-	// | e3 e7 e11 e15 |
-
-	Matrix::Matrix()
-	{
-		setIdentity();
-	}
-
-	Matrix::~Matrix()
-	{
-	}
-
-	//                 | e0 e4 e8  e12 |
-	//                 | e1 e5 e9  e13 |
-	//                 | e2 e6 e10 e14 |
-	//                 | e3 e7 e11 e15 |
-	// | e0 e4 e8  e12 |
-	// | e1 e5 e9  e13 |
-	// | e2 e6 e10 e14 |
-	// | e3 e7 e11 e15 |
-
-	Matrix Matrix::operator * (const Matrix & m) const
-	{
-		Matrix t;
-
-		t.e[0] = (e[0]*m.e[0]) + (e[4]*m.e[1]) + (e[8]*m.e[2]) + (e[12]*m.e[3]);
-		t.e[4] = (e[0]*m.e[4]) + (e[4]*m.e[5]) + (e[8]*m.e[6]) + (e[12]*m.e[7]);
-		t.e[8] = (e[0]*m.e[8]) + (e[4]*m.e[9]) + (e[8]*m.e[10]) + (e[12]*m.e[11]);
-		t.e[12] = (e[0]*m.e[12]) + (e[4]*m.e[13]) + (e[8]*m.e[14]) + (e[12]*m.e[15]);
-
-		t.e[1] = (e[1]*m.e[0]) + (e[5]*m.e[1]) + (e[9]*m.e[2]) + (e[13]*m.e[3]);
-		t.e[5] = (e[1]*m.e[4]) + (e[5]*m.e[5]) + (e[9]*m.e[6]) + (e[13]*m.e[7]);
-		t.e[9] = (e[1]*m.e[8]) + (e[5]*m.e[9]) + (e[9]*m.e[10]) + (e[13]*m.e[11]);
-		t.e[13] = (e[1]*m.e[12]) + (e[5]*m.e[13]) + (e[9]*m.e[14]) + (e[13]*m.e[15]);
-
-		t.e[2] = (e[2]*m.e[0]) + (e[6]*m.e[1]) + (e[10]*m.e[2]) + (e[14]*m.e[3]);
-		t.e[6] = (e[2]*m.e[4]) + (e[6]*m.e[5]) + (e[10]*m.e[6]) + (e[14]*m.e[7]);
-		t.e[10] = (e[2]*m.e[8]) + (e[6]*m.e[9]) + (e[10]*m.e[10]) + (e[14]*m.e[11]);
-		t.e[14] = (e[2]*m.e[12]) + (e[6]*m.e[13]) + (e[10]*m.e[14]) + (e[14]*m.e[15]);
-
-		t.e[3] = (e[3]*m.e[0]) + (e[7]*m.e[1]) + (e[11]*m.e[2]) + (e[15]*m.e[3]);
-		t.e[7] = (e[3]*m.e[4]) + (e[7]*m.e[5]) + (e[11]*m.e[6]) + (e[15]*m.e[7]);
-		t.e[11] = (e[3]*m.e[8]) + (e[7]*m.e[9]) + (e[11]*m.e[10]) + (e[15]*m.e[11]);
-		t.e[15] = (e[3]*m.e[12]) + (e[7]*m.e[13]) + (e[11]*m.e[14]) + (e[15]*m.e[15]);
-
-		return t;
-	}
-
-	void Matrix::operator *= (const Matrix & m)
-	{
-		Matrix t = (*this) * m;
-		memcpy((void*)this->e, (void*)t.e, sizeof(float)*16);
-	}
-
-	const float * Matrix::getElements() const
-	{
-		return e;
-	}
-
-	void Matrix::setIdentity()
-	{
-		memset(e, 0, sizeof(float)*16);
-		e[0] = e[5] = e[10] = e[15] = 1;
-	}
-
-	void Matrix::setTranslation(float x, float y)
-	{
-		setIdentity();
-		e[12] = x;
-		e[13] = y;
-	}
-
-	void Matrix::setRotation(float rad)
-	{
-		setIdentity();
-		float c = cos(rad), s = sin(rad);
-		e[0] = c; e[4] = -s;
-		e[1] = s; e[5] = c;
-	}
-
-	void Matrix::setScale(float sx, float sy)
-	{
-		setIdentity();
-		e[0] = sx;
-		e[5] = sy;
-	}
-
-	void Matrix::setShear(float kx, float ky)
-	{
-		setIdentity();
-		e[1] = ky;
-		e[4] = kx;
-	}
-
-	void Matrix::setTransformation(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky)
-	{
-		memset(e, 0, sizeof(float)*16); // zero out matrix
-		float c = cos(angle), s = sin(angle);
-		// matrix multiplication carried out on paper:
-		// |1     x| |c -s    | |sx       | | 1 ky    | |1     -ox|
-		// |  1   y| |s  c    | |   sy    | |kx  1    | |  1   -oy|
-		// |    1  | |     1  | |      1  | |      1  | |    1    |
-		// |      1| |       1| |        1| |        1| |       1 |
-		//   move      rotate      scale       skew       origin
-		e[10] = e[15] = 1.0f;
-		e[0]  = c * sx - ky * s * sy; // = a
-		e[1]  = s * sx + ky * c * sy; // = b
-		e[4]  = kx * c * sx - s * sy; // = c
-		e[5]  = kx * s * sx + c * sy; // = d
-		e[12] = x - ox * e[0] - oy * e[4];
-		e[13] = y - ox * e[1] - oy * e[5];
-	}
-
-	void Matrix::translate(float x, float y)
-	{
-		Matrix t;
-		t.setTranslation(x, y);
-		this->operator *=(t);
-	}
-
-	void Matrix::rotate(float rad)
-	{
-		Matrix t;
-		t.setRotation(rad);
-		this->operator *=(t);
-	}
-
-	void Matrix::scale(float sx, float sy)
-	{
-		Matrix t;
-		t.setScale(sx, sy);
-		this->operator *=(t);
-	}
-
-	void Matrix::shear(float kx, float ky)
-	{
-		Matrix t;
-		t.setShear(kx,ky);
-		this->operator *=(t);
-	}
-
-	//                 | x |
-	//                 | y |
-	//                 | 0 |
-	//                 | 1 |
-	// | e0 e4 e8  e12 |
-	// | e1 e5 e9  e13 |
-	// | e2 e6 e10 e14 |
-	// | e3 e7 e11 e15 |
-
-	void Matrix::transform(vertex * dst, const vertex * src, int size) const
-	{
-		for (int i = 0;i<size;i++)
-		{
-			// Store in temp variables in case src = dst
-			float x = (e[0]*src[i].x) + (e[4]*src[i].y) + (0) + (e[12]);
-			float y = (e[1]*src[i].x) + (e[5]*src[i].y) + (0) + (e[13]);
-
-			dst[i].x = x;
-			dst[i].y = y;
-		}
-	}
-
-
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "Matrix.h"
+
+// STD
+#include <cstring> // memcpy
+#include <cmath>
+
+namespace love
+{
+
+// | e0 e4 e8  e12 |
+// | e1 e5 e9  e13 |
+// | e2 e6 e10 e14 |
+// | e3 e7 e11 e15 |
+
+Matrix::Matrix()
+{
+	setIdentity();
+}
+
+Matrix::~Matrix()
+{
+}
+
+//                 | e0 e4 e8  e12 |
+//                 | e1 e5 e9  e13 |
+//                 | e2 e6 e10 e14 |
+//                 | e3 e7 e11 e15 |
+// | e0 e4 e8  e12 |
+// | e1 e5 e9  e13 |
+// | e2 e6 e10 e14 |
+// | e3 e7 e11 e15 |
+
+Matrix Matrix::operator * (const Matrix &m) const
+{
+	Matrix t;
+
+	t.e[0] = (e[0]*m.e[0]) + (e[4]*m.e[1]) + (e[8]*m.e[2]) + (e[12]*m.e[3]);
+	t.e[4] = (e[0]*m.e[4]) + (e[4]*m.e[5]) + (e[8]*m.e[6]) + (e[12]*m.e[7]);
+	t.e[8] = (e[0]*m.e[8]) + (e[4]*m.e[9]) + (e[8]*m.e[10]) + (e[12]*m.e[11]);
+	t.e[12] = (e[0]*m.e[12]) + (e[4]*m.e[13]) + (e[8]*m.e[14]) + (e[12]*m.e[15]);
+
+	t.e[1] = (e[1]*m.e[0]) + (e[5]*m.e[1]) + (e[9]*m.e[2]) + (e[13]*m.e[3]);
+	t.e[5] = (e[1]*m.e[4]) + (e[5]*m.e[5]) + (e[9]*m.e[6]) + (e[13]*m.e[7]);
+	t.e[9] = (e[1]*m.e[8]) + (e[5]*m.e[9]) + (e[9]*m.e[10]) + (e[13]*m.e[11]);
+	t.e[13] = (e[1]*m.e[12]) + (e[5]*m.e[13]) + (e[9]*m.e[14]) + (e[13]*m.e[15]);
+
+	t.e[2] = (e[2]*m.e[0]) + (e[6]*m.e[1]) + (e[10]*m.e[2]) + (e[14]*m.e[3]);
+	t.e[6] = (e[2]*m.e[4]) + (e[6]*m.e[5]) + (e[10]*m.e[6]) + (e[14]*m.e[7]);
+	t.e[10] = (e[2]*m.e[8]) + (e[6]*m.e[9]) + (e[10]*m.e[10]) + (e[14]*m.e[11]);
+	t.e[14] = (e[2]*m.e[12]) + (e[6]*m.e[13]) + (e[10]*m.e[14]) + (e[14]*m.e[15]);
+
+	t.e[3] = (e[3]*m.e[0]) + (e[7]*m.e[1]) + (e[11]*m.e[2]) + (e[15]*m.e[3]);
+	t.e[7] = (e[3]*m.e[4]) + (e[7]*m.e[5]) + (e[11]*m.e[6]) + (e[15]*m.e[7]);
+	t.e[11] = (e[3]*m.e[8]) + (e[7]*m.e[9]) + (e[11]*m.e[10]) + (e[15]*m.e[11]);
+	t.e[15] = (e[3]*m.e[12]) + (e[7]*m.e[13]) + (e[11]*m.e[14]) + (e[15]*m.e[15]);
+
+	return t;
+}
+
+void Matrix::operator *= (const Matrix &m)
+{
+	Matrix t = (*this) * m;
+	memcpy((void *)this->e, (void *)t.e, sizeof(float)*16);
+}
+
+const float *Matrix::getElements() const
+{
+	return e;
+}
+
+void Matrix::setIdentity()
+{
+	memset(e, 0, sizeof(float)*16);
+	e[0] = e[5] = e[10] = e[15] = 1;
+}
+
+void Matrix::setTranslation(float x, float y)
+{
+	setIdentity();
+	e[12] = x;
+	e[13] = y;
+}
+
+void Matrix::setRotation(float rad)
+{
+	setIdentity();
+	float c = cos(rad), s = sin(rad);
+	e[0] = c;
+	e[4] = -s;
+	e[1] = s;
+	e[5] = c;
+}
+
+void Matrix::setScale(float sx, float sy)
+{
+	setIdentity();
+	e[0] = sx;
+	e[5] = sy;
+}
+
+void Matrix::setShear(float kx, float ky)
+{
+	setIdentity();
+	e[1] = ky;
+	e[4] = kx;
+}
+
+void Matrix::setTransformation(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky)
+{
+	memset(e, 0, sizeof(float)*16); // zero out matrix
+	float c = cos(angle), s = sin(angle);
+	// matrix multiplication carried out on paper:
+	// |1     x| |c -s    | |sx       | | 1 ky    | |1     -ox|
+	// |  1   y| |s  c    | |   sy    | |kx  1    | |  1   -oy|
+	// |    1  | |     1  | |      1  | |      1  | |    1    |
+	// |      1| |       1| |        1| |        1| |       1 |
+	//   move      rotate      scale       skew       origin
+	e[10] = e[15] = 1.0f;
+	e[0]  = c * sx - ky * s * sy; // = a
+	e[1]  = s * sx + ky * c * sy; // = b
+	e[4]  = kx * c * sx - s * sy; // = c
+	e[5]  = kx * s * sx + c * sy; // = d
+	e[12] = x - ox * e[0] - oy * e[4];
+	e[13] = y - ox * e[1] - oy * e[5];
+}
+
+void Matrix::translate(float x, float y)
+{
+	Matrix t;
+	t.setTranslation(x, y);
+	this->operator *=(t);
+}
+
+void Matrix::rotate(float rad)
+{
+	Matrix t;
+	t.setRotation(rad);
+	this->operator *=(t);
+}
+
+void Matrix::scale(float sx, float sy)
+{
+	Matrix t;
+	t.setScale(sx, sy);
+	this->operator *=(t);
+}
+
+void Matrix::shear(float kx, float ky)
+{
+	Matrix t;
+	t.setShear(kx,ky);
+	this->operator *=(t);
+}
+
+//                 | x |
+//                 | y |
+//                 | 0 |
+//                 | 1 |
+// | e0 e4 e8  e12 |
+// | e1 e5 e9  e13 |
+// | e2 e6 e10 e14 |
+// | e3 e7 e11 e15 |
+
+void Matrix::transform(vertex *dst, const vertex *src, int size) const
+{
+	for (int i = 0; i<size; i++)
+	{
+		// Store in temp variables in case src = dst
+		float x = (e[0]*src[i].x) + (e[4]*src[i].y) + (0) + (e[12]);
+		float y = (e[1]*src[i].x) + (e[5]*src[i].y) + (0) + (e[13]);
+
+		dst[i].x = x;
+		dst[i].y = y;
+	}
+}
+
+
+} // love

+ 167 - 166
src/common/Matrix.h

@@ -1,166 +1,167 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_MATRIX_H
-#define LOVE_MATRIX_H
-
-// LOVE
-#include "math.h"
-
-namespace love
-{
-	/**
-	* This class is the basis for all transformations in LOVE. Althought not
-	* really needed for 2D, it contains 4x4 elements to be compatible with
-	* OpenGL without conversions.
-	**/
-	class Matrix
-	{
-	private:
-
-		/**
-		* | e0 e4 e8  e12 |
-		* | e1 e5 e9  e13 |
-		* | e2 e6 e10 e14 |
-		* | e3 e7 e11 e15 |
-		**/
-		float e[16];
-
-	public:
-
-		/**
-		* Creates a new identity matrix.
-		**/
-		Matrix();
-
-		/**
-		* Destructor.
-		**/
-		~Matrix();
-
-		/**
-		* Multiplies this Matrix with another Matrix, changing neither.
-		* @param m The Matrix to multiply with this Matrix.
-		* @return The combined matrix.
-		**/
-		Matrix operator * (const Matrix & m) const;
-
-		/**
-		* Multiplies a Matrix into this Matrix.
-		* @param m The Matrix to combine into this Matrix.
-		**/
-		void operator *= (const Matrix & m);
-
-		/**
-		* Gets a pointer to the 16 array elements.
-		* @return The array elements.
-		**/
-		const float * getElements() const;
-
-		/**
-		* Resets this Matrix to the identity matrix.
-		**/
-		void setIdentity();
-
-		/**
-		* Resets this Matrix to a translation.
-		* @param x Translation along x-axis.
-		* @param y Translation along y-axis.
-		**/
-		void setTranslation(float x, float y);
-
-		/**
-		* Resets this Matrix to a rotation.
-		* @param r The angle in radians.
-		**/
-		void setRotation(float r);
-
-		/**
-		* Resets this Matrix to a scale transformation.
-		* @param sx Scale factor along the x-axis.
-		* @param sy Scale factor along the y-axis.
-		**/
-		void setScale(float sx, float sy);
-
-		/**
-		* Resets this Matrix to a shear transformation.
-		* @param kx Shear along x-axis.
-		* @param ky Shear along y-axis.
-		**/
-		void setShear(float kx, float ky);
-
-		/**
-		* Creates a transformation with a certain position, orientation, scale
-		* and offset. Perfect for Drawables -- what a coincidence!
-		*
-		* @param x The translation along the x-axis.
-		* @param y The translation along the y-axis.
-		* @param angle The rotation (rad) around the center with offset (ox,oy).
-		* @param sx Scale along x-axis.
-		* @param sy Scale along y-axis.
-		* @param ox The offset for rotation along the x-axis.
-		* @param oy The offset for rotation along the y-axis.
-		* @param kx Shear along x-axis
-		* @param ky Shear along y-axis
-		**/
-		void setTransformation(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky);
-
-		/**
-		* Multiplies this Matrix with a translation.
-		* @param x Translation along x-axis.
-		* @param y Translation along y-axis.
-		**/
-		void translate(float x, float y);
-
-		/**
-		* Multiplies this Matrix with a rotation.
-		* @param r Angle in radians.
-		**/
-		void rotate(float r);
-
-		/**
-		* Multiplies this Matrix with a scale transformation.
-		* @param sx Scale factor along the x-axis.
-		* @param sy Scale factor along the y-axis.
-		**/
-		void scale(float sx, float sy);
-
-		/**
-		* Multiplies this Matrix with a shear transformation.
-		* @param kx Shear along the x-axis.
-		* @param ky Shear along the y-axis.
-		**/
-		void shear(float kx, float ky);
-
-		/**
-		* Transforms an array of vertices by this Matrix. The sources and
-		* destination arrays may be the same.
-		*
-		* @param dst Storage for the transformed vertices.
-		* @param src The source vertices.
-		* @param size The number of vertices.
-		**/
-		void transform(vertex * dst, const vertex * src, int size) const;
-
-	}; // Matrix
-
-} //love
-
-#endif// LOVE_MATRIX_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_MATRIX_H
+#define LOVE_MATRIX_H
+
+// LOVE
+#include "math.h"
+
+namespace love
+{
+
+/**
+ * This class is the basis for all transformations in LOVE. Althought not
+ * really needed for 2D, it contains 4x4 elements to be compatible with
+ * OpenGL without conversions.
+ **/
+class Matrix
+{
+public:
+
+	/**
+	 * Creates a new identity matrix.
+	 **/
+	Matrix();
+
+	/**
+	 * Destructor.
+	 **/
+	~Matrix();
+
+	/**
+	 * Multiplies this Matrix with another Matrix, changing neither.
+	 * @param m The Matrix to multiply with this Matrix.
+	 * @return The combined matrix.
+	 **/
+	Matrix operator * (const Matrix &m) const;
+
+	/**
+	 * Multiplies a Matrix into this Matrix.
+	 * @param m The Matrix to combine into this Matrix.
+	 **/
+	void operator *= (const Matrix &m);
+
+	/**
+	 * Gets a pointer to the 16 array elements.
+	 * @return The array elements.
+	 **/
+	const float *getElements() const;
+
+	/**
+	 * Resets this Matrix to the identity matrix.
+	 **/
+	void setIdentity();
+
+	/**
+	 * Resets this Matrix to a translation.
+	 * @param x Translation along x-axis.
+	 * @param y Translation along y-axis.
+	 **/
+	void setTranslation(float x, float y);
+
+	/**
+	 * Resets this Matrix to a rotation.
+	 * @param r The angle in radians.
+	 **/
+	void setRotation(float r);
+
+	/**
+	 * Resets this Matrix to a scale transformation.
+	 * @param sx Scale factor along the x-axis.
+	 * @param sy Scale factor along the y-axis.
+	 **/
+	void setScale(float sx, float sy);
+
+	/**
+	 * Resets this Matrix to a shear transformation.
+	 * @param kx Shear along x-axis.
+	 * @param ky Shear along y-axis.
+	 **/
+	void setShear(float kx, float ky);
+
+	/**
+	 * Creates a transformation with a certain position, orientation, scale
+	 * and offset. Perfect for Drawables -- what a coincidence!
+	 *
+	 * @param x The translation along the x-axis.
+	 * @param y The translation along the y-axis.
+	 * @param angle The rotation (rad) around the center with offset (ox,oy).
+	 * @param sx Scale along x-axis.
+	 * @param sy Scale along y-axis.
+	 * @param ox The offset for rotation along the x-axis.
+	 * @param oy The offset for rotation along the y-axis.
+	 * @param kx Shear along x-axis
+	 * @param ky Shear along y-axis
+	 **/
+	void setTransformation(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky);
+
+	/**
+	 * Multiplies this Matrix with a translation.
+	 * @param x Translation along x-axis.
+	 * @param y Translation along y-axis.
+	 **/
+	void translate(float x, float y);
+
+	/**
+	 * Multiplies this Matrix with a rotation.
+	 * @param r Angle in radians.
+	 **/
+	void rotate(float r);
+
+	/**
+	 * Multiplies this Matrix with a scale transformation.
+	 * @param sx Scale factor along the x-axis.
+	 * @param sy Scale factor along the y-axis.
+	 **/
+	void scale(float sx, float sy);
+
+	/**
+	 * Multiplies this Matrix with a shear transformation.
+	 * @param kx Shear along the x-axis.
+	 * @param ky Shear along the y-axis.
+	 **/
+	void shear(float kx, float ky);
+
+	/**
+	 * Transforms an array of vertices by this Matrix. The sources and
+	 * destination arrays may be the same.
+	 *
+	 * @param dst Storage for the transformed vertices.
+	 * @param src The source vertices.
+	 * @param size The number of vertices.
+	 **/
+	void transform(vertex *dst, const vertex *src, int size) const;
+
+private:
+
+	/**
+	 * | e0 e4 e8  e12 |
+	 * | e1 e5 e9  e13 |
+	 * | e2 e6 e10 e14 |
+	 * | e3 e7 e11 e15 |
+	 **/
+	float e[16];
+
+}; // Matrix
+
+} //love
+
+#endif// LOVE_MATRIX_H

+ 45 - 44
src/common/Memoizer.cpp

@@ -1,44 +1,45 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-#include "Memoizer.h"
-#include <cstddef>
-
-namespace love
-{
-
-	std::map<void *, void *> Memoizer::objectMap;
-
-	void Memoizer::add(void * key, void * val)
-	{
-		objectMap[key] = val;
-	}
-
-	void Memoizer::remove(void * key)
-	{
-		objectMap.erase(key);
-	}
-
-	void * Memoizer::find(void * key)
-	{
-		if (objectMap.count(key)) return objectMap[key];
-		return NULL;
-	}
-
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+ 
+#include "Memoizer.h"
+#include <cstddef>
+
+namespace love
+{
+
+std::map<void *, void *> Memoizer::objectMap;
+
+void Memoizer::add(void *key, void *val)
+{
+	objectMap[key] = val;
+}
+
+void Memoizer::remove(void *key)
+{
+	objectMap.erase(key);
+}
+
+void *Memoizer::find(void *key)
+{
+	if (objectMap.count(key)) return objectMap[key];
+	return NULL;
+}
+
+} // love

+ 46 - 46
src/common/Memoizer.h

@@ -1,46 +1,46 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_MEMOIZER_H
-#define LOVE_MEMOIZER_H
-
-#include <map>
-
-namespace love
-{
-	class Memoizer
-	{
-	private:
-
-		static std::map<void *, void *> objectMap;
-
-	public:
-
-		static void add(void * key, void * val);
-
-		static void remove(void * key);
-
-		static void * find(void * key);
-
-	}; // Memoizer
-
-} // love
-
-#endif // LOVE_MEMOIZER_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_MEMOIZER_H
+#define LOVE_MEMOIZER_H
+
+#include <map>
+
+namespace love
+{
+
+class Memoizer
+{
+public:
+
+	static void add(void *key, void *val);
+
+	static void remove(void *key);
+
+	static void *find(void *key);
+
+private:
+
+	static std::map<void *, void *> objectMap;
+}; // Memoizer
+
+} // love
+
+#endif // LOVE_MEMOIZER_H

+ 55 - 55
src/common/Module.h

@@ -1,55 +1,55 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_MODULE_H
-#define LOVE_MODULE_H
-
-// LOVE
-#include "runtime.h"
-#include "Exception.h"
-#include "Object.h"
-
-namespace love
-{
-	/**
-	* Abstract superclass for all modules.
-	**/
-	class Module : public Object
-	{
-	public:
-
-		/**
-		* Destructor.
-		**/
-		virtual ~Module(){};
-
-		/**
-		* Gets the name of the module. This is used in case of errors
-		* and other messages.
-		*
-		* @return The full name of the module, eg. love.graphics.opengl.
-		**/
-		virtual const char * getName() const = 0;
-
-	}; // Module
-
-} // love
-
-#endif // LOVE_MODULE_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_MODULE_H
+#define LOVE_MODULE_H
+
+// LOVE
+#include "runtime.h"
+#include "Exception.h"
+#include "Object.h"
+
+namespace love
+{
+/**
+ * Abstract superclass for all modules.
+ **/
+class Module : public Object
+{
+public:
+
+	/**
+	 * Destructor.
+	 **/
+	virtual ~Module() {};
+
+	/**
+	 * Gets the name of the module. This is used in case of errors
+	 * and other messages.
+	 *
+	 * @return The full name of the module, eg. love.graphics.opengl.
+	 **/
+	virtual const char *getName() const = 0;
+
+}; // Module
+
+} // love
+
+#endif // LOVE_MODULE_H

+ 52 - 52
src/common/Object.cpp

@@ -1,52 +1,52 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-// LOVE
-#include "Object.h"
-
-namespace love
-{
-
-	Object::Object()
-		: count(1)
-	{
-	}
-
-	Object::~Object()
-	{
-	}
-
-	int Object::getReferenceCount() const
-	{
-		return count;
-	}
-
-	void Object::retain()
-	{
-		++count;
-	}
-
-	void Object::release()
-	{
-		if (--count <= 0)
-			delete this;
-	}
-
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+// LOVE
+#include "Object.h"
+
+namespace love
+{
+
+Object::Object()
+	: count(1)
+{
+}
+
+Object::~Object()
+{
+}
+
+int Object::getReferenceCount() const
+{
+	return count;
+}
+
+void Object::retain()
+{
+	++count;
+}
+
+void Object::release()
+{
+	if (--count <= 0)
+		delete this;
+}
+
+} // love

+ 76 - 76
src/common/Object.h

@@ -1,76 +1,76 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_OBJECT_H
-#define LOVE_OBJECT_H
-
-namespace love
-{
-	/**
-	* Superclass for all object that should be able to  cross the Lua/C border
-	* (this pertains to most objects).
-	*
-	* This class is an alternative to using smart pointers; it contains retain/release
-	* methods, and will delete itself with the reference count hits zero. The wrapper
-	* code assumes that all userdata inherits from this class.
-	**/
-	class Object
-	{
-	private:
-
-		// The reference count.
-		int count;
-
-	public:
-
-		/**
-		* Constructor. Sets reference count to one.
-		**/
-		Object();
-
-		/**
-		* Destructor.
-		**/
-		virtual ~Object() = 0;
-
-		/**
-		* Gets the reference count of this Object.
-		* @returns The reference count.
-		**/
-		int getReferenceCount() const;
-
-		/**
-		* Retains the Object, i.e. increases the
-		* reference count by one.
-		**/
-		void retain();
-
-		/**
-		* Releases one reference to the Object, i.e. decrements the
-		* reference count by one, and potentially deletes the Object
-		* if there are no more references.
-		**/
-		void release();
-
-	}; // Object
-
-} // love
-
-#endif // LOVE_OBJECT_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_OBJECT_H
+#define LOVE_OBJECT_H
+
+namespace love
+{
+
+/**
+ * Superclass for all object that should be able to  cross the Lua/C border
+ * (this pertains to most objects).
+ *
+ * This class is an alternative to using smart pointers; it contains retain/release
+ * methods, and will delete itself with the reference count hits zero. The wrapper
+ * code assumes that all userdata inherits from this class.
+ **/
+class Object
+{
+public:
+
+	/**
+	 * Constructor. Sets reference count to one.
+	 **/
+	Object();
+
+	/**
+	 * Destructor.
+	 **/
+	virtual ~Object() = 0;
+
+	/**
+	 * Gets the reference count of this Object.
+	 * @returns The reference count.
+	 **/
+	int getReferenceCount() const;
+
+	/**
+	 * Retains the Object, i.e. increases the
+	 * reference count by one.
+	 **/
+	void retain();
+
+	/**
+	 * Releases one reference to the Object, i.e. decrements the
+	 * reference count by one, and potentially deletes the Object
+	 * if there are no more references.
+	 **/
+	void release();
+
+private:
+
+	// The reference count.
+	int count;
+}; // Object
+
+} // love
+
+#endif // LOVE_OBJECT_H

+ 82 - 81
src/common/Reference.cpp

@@ -1,81 +1,82 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "Reference.h"
-
-namespace love
-{
-	const char REFERENCE_TABLE_NAME[] = "love-references";
-
-	Reference::Reference()
-		: L(0), idx(LUA_REFNIL)
-	{
-	}
-
-	Reference::Reference(lua_State * L)
-		: L(0), idx(LUA_REFNIL)
-	{
-		ref(L);
-	}
-
-	Reference::~Reference()
-	{
-		unref();
-	}
-
-	void Reference::ref(lua_State * L)
-	{
-		unref(); // Just to be safe.
-		this->L = L;
-		luax_insist(L, LUA_REGISTRYINDEX, REFERENCE_TABLE_NAME);
-		lua_insert(L, -2); // Move reference table behind value.
-		idx = luaL_ref(L, -2);
-		lua_pop(L, 1);
-	}
-
-	void Reference::unref()
-	{
-		if (idx != LUA_REFNIL)
-		{
-			luax_insist(L, LUA_REGISTRYINDEX, REFERENCE_TABLE_NAME);
-			luaL_unref(L, -1, idx);
-			lua_pop(L, 1);
-			idx = LUA_REFNIL;
-		}
-	}
-
-	void Reference::push()
-	{
-		if (idx != LUA_REFNIL)
-		{
-			luax_insist(L, LUA_REGISTRYINDEX, REFERENCE_TABLE_NAME);
-			lua_rawgeti(L, -1, idx);
-			lua_remove(L, -2);
-		}
-		else
-			lua_pushnil(L);
-	}
-
-	lua_State * Reference::getL()
-	{
-		return L;
-	}
-
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "Reference.h"
+
+namespace love
+{
+
+const char REFERENCE_TABLE_NAME[] = "love-references";
+
+Reference::Reference()
+	: L(0), idx(LUA_REFNIL)
+{
+}
+
+Reference::Reference(lua_State *L)
+	: L(0), idx(LUA_REFNIL)
+{
+	ref(L);
+}
+
+Reference::~Reference()
+{
+	unref();
+}
+
+void Reference::ref(lua_State *L)
+{
+	unref(); // Just to be safe.
+	this->L = L;
+	luax_insist(L, LUA_REGISTRYINDEX, REFERENCE_TABLE_NAME);
+	lua_insert(L, -2); // Move reference table behind value.
+	idx = luaL_ref(L, -2);
+	lua_pop(L, 1);
+}
+
+void Reference::unref()
+{
+	if (idx != LUA_REFNIL)
+	{
+		luax_insist(L, LUA_REGISTRYINDEX, REFERENCE_TABLE_NAME);
+		luaL_unref(L, -1, idx);
+		lua_pop(L, 1);
+		idx = LUA_REFNIL;
+	}
+}
+
+void Reference::push()
+{
+	if (idx != LUA_REFNIL)
+	{
+		luax_insist(L, LUA_REGISTRYINDEX, REFERENCE_TABLE_NAME);
+		lua_rawgeti(L, -1, idx);
+		lua_remove(L, -2);
+	}
+	else
+		lua_pushnil(L);
+}
+
+lua_State *Reference::getL()
+{
+	return L;
+}
+
+} // love

+ 88 - 87
src/common/Reference.h

@@ -1,87 +1,88 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_REFERENCE_H
-#define LOVE_REFERENCE_H
-
-// LOVE
-#include "runtime.h"
-
-namespace love
-{
-	/**
-	* This class wraps the reference functionality built into
-	* Lua, which allows C++ code to refer to Lua variables.
-	**/
-	class Reference
-	{
-	private:
-
-		// The Lua state in which the reference resides.
-		lua_State * L;
-
-		// Index to the Lua reference.
-		int idx;
-
-	public:
-
-		/**
-		* Creates the reference object, but does not create
-		* the actual reference.
-		**/
-		Reference();
-
-		/**
-		* Creates the object and a reference to the value
-		* on the top of the stack.
-		**/
-		Reference(lua_State * L);
-
-		/**
-		* Deletes the reference, if any.
-		**/
-		virtual ~Reference();
-
-		/**
-		* Creates a reference to the value on the
-		* top of the stack.
-		**/
-		void ref(lua_State * L);
-
-		/**
-		* Unrefs the reference, if any.
-		**/
-		void unref();
-
-		/**
-		* Pushes the referred value onto the stack.
-		**/
-		void push();
-
-		/**
-		* Gets the Lua state associated with this
-		* reference.
-		**/
-		lua_State * getL();
-	};
-
-} // love
-
-#endif // LOVE_REFERENCE_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_REFERENCE_H
+#define LOVE_REFERENCE_H
+
+// LOVE
+#include "runtime.h"
+
+namespace love
+{
+
+/**
+ * This class wraps the reference functionality built into
+ * Lua, which allows C++ code to refer to Lua variables.
+ **/
+class Reference
+{
+public:
+
+	/**
+	 * Creates the reference object, but does not create
+	 * the actual reference.
+	 **/
+	Reference();
+
+	/**
+	 * Creates the object and a reference to the value
+	 * on the top of the stack.
+	 **/
+	Reference(lua_State *L);
+
+	/**
+	 * Deletes the reference, if any.
+	 **/
+	virtual ~Reference();
+
+	/**
+	 * Creates a reference to the value on the
+	 * top of the stack.
+	 **/
+	void ref(lua_State *L);
+
+	/**
+	 * Unrefs the reference, if any.
+	 **/
+	void unref();
+
+	/**
+	 * Pushes the referred value onto the stack.
+	 **/
+	void push();
+
+	/**
+	 * Gets the Lua state associated with this
+	 * reference.
+	 **/
+	lua_State *getL();
+
+private:
+
+	// The Lua state in which the reference resides.
+	lua_State *L;
+
+	// Index to the Lua reference.
+	int idx;
+};
+
+} // love
+
+#endif // LOVE_REFERENCE_H

+ 168 - 167
src/common/StringMap.h

@@ -1,167 +1,168 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_STRING_MAP_H
-#define LOVE_STRING_MAP_H
-
-#include "Exception.h"
-
-namespace love
-{
-	template<typename T, unsigned SIZE>
-	class StringMap
-	{
-	private:
-
-		struct Record
-		{
-			const char * key;
-			T value;
-			bool set;
-			Record() : set(false) {}
-		};
-
-		const static unsigned MAX = SIZE*2;
-
-		Record records[MAX];
-		const char * reverse[SIZE];
-
-	public:
-
-		struct Entry
-		{
-			const char * key;
-			T value;
-		};
-
-		StringMap(Entry * entries, unsigned num)
-		{
-
-			for (unsigned i = 0; i < SIZE; ++i)
-				reverse[i] = 0;
-
-			unsigned n = num/sizeof(Entry);
-
-			for (unsigned i = 0; i < n; ++i)
-			{
-				add(entries[i].key, entries[i].value);
-			}
-		}
-
-		bool streq(const char * a, const char * b)
-		{
-			while (*a != 0 && *b != 0)
-			{
-				if (*a != *b)
-					return false;
-				++a;
-				++b;
-			}
-
-			return (*a == 0 && *b == 0);
-		}
-
-		bool find(const char * key, T & t)
-		{
-			unsigned str_hash = djb2(key);
-
-			for (unsigned i = 0; i < MAX; ++i)
-			{
-				unsigned str_i = (str_hash + i) % MAX; //this isn't used, is this intentional?
-
-				if (!records[str_i].set)
-					return false;
-
-				if (streq(records[str_i].key, key))
-				{
-					t = records[str_i].value;
-					return true;
-				}
-			}
-
-			return false;
-		}
-
-		bool find(T key, const char *& str)
-		{
-			unsigned index = (unsigned)key;
-
-			if (index >= SIZE)
-				return false;
-
-			if (reverse[index] != 0)
-			{
-				str = reverse[index];
-				return true;
-			}
-			else
-			{
-				return false;
-			}
-		}
-
-		bool add(const char * key, T value)
-		{
-			unsigned str_hash = djb2(key);
-			bool inserted = false;
-
-			for (unsigned i = 0; i < MAX; ++i)
-			{
-				unsigned str_i = (str_hash + i) % MAX;
-
-				if (!records[str_i].set)
-				{
-					inserted = true;
-					records[str_i].set = true;
-					records[str_i].key = key;
-					records[str_i].value = value;
-					break;
-				}
-			}
-
-			unsigned index = (unsigned)value;
-
-			if (index >= SIZE)
-			{
-				printf("\nConstant %s out of bounds with %i!\n", key, index);
-				return false;
-			}
-
-			reverse[index] = key;
-
-			return inserted;
-		}
-
-		unsigned djb2(const char * key)
-		{
-			unsigned hash = 5381;
-			int c;
-
-			while ((c = *key++))
-				hash = ((hash << 5) + hash) + c;
-
-			return hash;
-		}
-
-	}; // StringMap
-
-} // love
-
-#endif // LOVE_STRING_MAP_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_STRING_MAP_H
+#define LOVE_STRING_MAP_H
+
+#include "Exception.h"
+
+namespace love
+{
+
+template<typename T, unsigned SIZE>
+class StringMap
+{
+public:
+
+	struct Entry
+	{
+		const char *key;
+		T value;
+	};
+
+	StringMap(Entry *entries, unsigned num)
+	{
+
+		for (unsigned i = 0; i < SIZE; ++i)
+			reverse[i] = 0;
+
+		unsigned n = num/sizeof(Entry);
+
+		for (unsigned i = 0; i < n; ++i)
+		{
+			add(entries[i].key, entries[i].value);
+		}
+	}
+
+	bool streq(const char *a, const char *b)
+	{
+		while (*a != 0 && *b != 0)
+		{
+			if (*a != *b)
+				return false;
+			++a;
+			++b;
+		}
+
+		return (*a == 0 && *b == 0);
+	}
+
+	bool find(const char *key, T &t)
+	{
+		unsigned str_hash = djb2(key);
+
+		for (unsigned i = 0; i < MAX; ++i)
+		{
+			unsigned str_i = (str_hash + i) % MAX; //this isn't used, is this intentional?
+
+			if (!records[str_i].set)
+				return false;
+
+			if (streq(records[str_i].key, key))
+			{
+				t = records[str_i].value;
+				return true;
+			}
+		}
+
+		return false;
+	}
+
+	bool find(T key, const char  *&str)
+	{
+		unsigned index = (unsigned)key;
+
+		if (index >= SIZE)
+			return false;
+
+		if (reverse[index] != 0)
+		{
+			str = reverse[index];
+			return true;
+		}
+		else
+		{
+			return false;
+		}
+	}
+
+	bool add(const char *key, T value)
+	{
+		unsigned str_hash = djb2(key);
+		bool inserted = false;
+
+		for (unsigned i = 0; i < MAX; ++i)
+		{
+			unsigned str_i = (str_hash + i) % MAX;
+
+			if (!records[str_i].set)
+			{
+				inserted = true;
+				records[str_i].set = true;
+				records[str_i].key = key;
+				records[str_i].value = value;
+				break;
+			}
+		}
+
+		unsigned index = (unsigned)value;
+
+		if (index >= SIZE)
+		{
+			printf("\nConstant %s out of bounds with %i!\n", key, index);
+			return false;
+		}
+
+		reverse[index] = key;
+
+		return inserted;
+	}
+
+	unsigned djb2(const char *key)
+	{
+		unsigned hash = 5381;
+		int c;
+
+		while ((c = *key++))
+			hash = ((hash << 5) + hash) + c;
+
+		return hash;
+	}
+
+private:
+
+	struct Record
+	{
+		const char *key;
+		T value;
+		bool set;
+		Record() : set(false) {}
+	};
+
+	const static unsigned MAX = SIZE*2;
+
+	Record records[MAX];
+	const char *reverse[SIZE];
+
+}; // StringMap
+
+} // love
+
+#endif // LOVE_STRING_MAP_H

+ 175 - 173
src/common/Variant.cpp

@@ -1,173 +1,175 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "Variant.h"
-#include <common/StringMap.h>
-
-namespace love
-{
-	extern StringMap<Type, TYPE_MAX_ENUM> types;
-
-	love::Type extractudatatype(lua_State * L, int idx)
-	{
-		Type t = INVALID_ID;
-		if (!lua_isuserdata(L, idx))
-			return t;
-		if (luaL_getmetafield (L, idx, "__tostring") == 0)
-			return t;
-		lua_pushvalue(L, idx);
-		int result = lua_pcall(L, 1, 1, 0);
-		if (result == 0)
-			types.find(lua_tostring(L, -1), t);
-		if (result == 0 || result == LUA_ERRRUN)
-			lua_pop(L, 1);
-		return t;
-	}
-
-	Variant::Variant(bool boolean)
-	{
-		type = BOOLEAN;
-		data.boolean = boolean;
-	}
-
-	Variant::Variant(double number)
-	{
-		type = NUMBER;
-		data.number = number;
-	}
-
-	Variant::Variant(const char *string, size_t len)
-	{
-		type = STRING;
-		char *buf = new char[len+1];
-		memset(buf, 0, len+1);
-		memcpy(buf, string, len);
-		data.string.str = buf;
-		data.string.len = len;
-	}
-
-	Variant::Variant(char c)
-	{
-		type = CHARACTER;
-		data.character = c;
-	}
-
-	Variant::Variant(void *userdata)
-	{
-		type = LUSERDATA;
-		data.userdata = userdata;
-	}
-
-	Variant::Variant(love::Type udatatype, void *userdata)
-	{
-		type = FUSERDATA;
-		this->udatatype = udatatype;
-		if (udatatype != INVALID_ID)
-		{
-			Proxy *p = (Proxy *) userdata;
-			flags = p->flags;
-			data.userdata = p->data;
-			((love::Object *) data.userdata)->retain();
-		}
-		else
-			data.userdata = userdata;
-	}
-
-	Variant::~Variant()
-	{
-		switch(type)
-		{
-			case STRING:
-				delete[] data.string.str;
-				break;
-			case FUSERDATA:
-				((love::Object *) data.userdata)->release();
-				break;
-			default:
-				break;
-		}
-	}
-
-	Variant *Variant::fromLua(lua_State *L, int n)
-	{
-		Variant *v = NULL;
-		size_t len;
-		const char *str;
-		switch(lua_type(L, n))
-		{
-			case LUA_TBOOLEAN:
-				v = new Variant(luax_toboolean(L, n));
-				break;
-			case LUA_TNUMBER:
-				v = new Variant(lua_tonumber(L, n));
-				break;
-			case LUA_TSTRING:
-				str = lua_tolstring(L, n, &len);
-				v = new Variant(str, len);
-				break;
-			case LUA_TLIGHTUSERDATA:
-				v = new Variant(lua_touserdata(L, n));
-				break;
-			case LUA_TUSERDATA:
-				v = new Variant(extractudatatype(L, n), lua_touserdata(L, n));
-				break;
-		}
-		return v;
-	}
-
-	void Variant::toLua(lua_State *L)
-	{
-		switch(type)
-		{
-			case BOOLEAN:
-				lua_pushboolean(L, data.boolean);
-				break;
-			case CHARACTER:
-				lua_pushlstring(L, &data.character, 1);
-				break;
-			case NUMBER:
-				lua_pushnumber(L, data.number);
-				break;
-			case STRING:
-				lua_pushlstring(L, data.string.str, data.string.len);
-				break;
-			case LUSERDATA:
-				lua_pushlightuserdata(L, data.userdata);
-				break;
-			case FUSERDATA:
-				if (udatatype != INVALID_ID)
-				{
-					const char *name = NULL;
-					love::types.find(udatatype, name);
-					((love::Object *) data.userdata)->retain();
-					luax_newtype(L, name, flags, data.userdata);
-				}
-				else
-					lua_pushlightuserdata(L, data.userdata);
-				// I know this is not the same
-				// sadly, however, it's the most
-				// I can do (at the moment).
-				break;
-			default:
-				lua_pushnil(L);
-				break;
-		}
-	}
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "Variant.h"
+#include "common/StringMap.h"
+
+namespace love
+{
+
+extern StringMap<Type, TYPE_MAX_ENUM> types;
+
+love::Type extractudatatype(lua_State *L, int idx)
+{
+	Type t = INVALID_ID;
+	if (!lua_isuserdata(L, idx))
+		return t;
+	if (luaL_getmetafield(L, idx, "__tostring") == 0)
+		return t;
+	lua_pushvalue(L, idx);
+	int result = lua_pcall(L, 1, 1, 0);
+	if (result == 0)
+		types.find(lua_tostring(L, -1), t);
+	if (result == 0 || result == LUA_ERRRUN)
+		lua_pop(L, 1);
+	return t;
+}
+
+Variant::Variant(bool boolean)
+{
+	type = BOOLEAN;
+	data.boolean = boolean;
+}
+
+Variant::Variant(double number)
+{
+	type = NUMBER;
+	data.number = number;
+}
+
+Variant::Variant(const char *string, size_t len)
+{
+	type = STRING;
+	char *buf = new char[len+1];
+	memset(buf, 0, len+1);
+	memcpy(buf, string, len);
+	data.string.str = buf;
+	data.string.len = len;
+}
+
+Variant::Variant(char c)
+{
+	type = CHARACTER;
+	data.character = c;
+}
+
+Variant::Variant(void *userdata)
+{
+	type = LUSERDATA;
+	data.userdata = userdata;
+}
+
+Variant::Variant(love::Type udatatype, void *userdata)
+{
+	type = FUSERDATA;
+	this->udatatype = udatatype;
+	if (udatatype != INVALID_ID)
+	{
+		Proxy *p = (Proxy *) userdata;
+		flags = p->flags;
+		data.userdata = p->data;
+		((love::Object *) data.userdata)->retain();
+	}
+	else
+		data.userdata = userdata;
+}
+
+Variant::~Variant()
+{
+	switch (type)
+	{
+	case STRING:
+		delete[] data.string.str;
+		break;
+	case FUSERDATA:
+		((love::Object *) data.userdata)->release();
+		break;
+	default:
+		break;
+	}
+}
+
+Variant *Variant::fromLua(lua_State *L, int n)
+{
+	Variant *v = NULL;
+	size_t len;
+	const char *str;
+	switch (lua_type(L, n))
+	{
+	case LUA_TBOOLEAN:
+		v = new Variant(luax_toboolean(L, n));
+		break;
+	case LUA_TNUMBER:
+		v = new Variant(lua_tonumber(L, n));
+		break;
+	case LUA_TSTRING:
+		str = lua_tolstring(L, n, &len);
+		v = new Variant(str, len);
+		break;
+	case LUA_TLIGHTUSERDATA:
+		v = new Variant(lua_touserdata(L, n));
+		break;
+	case LUA_TUSERDATA:
+		v = new Variant(extractudatatype(L, n), lua_touserdata(L, n));
+		break;
+	}
+	return v;
+}
+
+void Variant::toLua(lua_State *L)
+{
+	switch (type)
+	{
+	case BOOLEAN:
+		lua_pushboolean(L, data.boolean);
+		break;
+	case CHARACTER:
+		lua_pushlstring(L, &data.character, 1);
+		break;
+	case NUMBER:
+		lua_pushnumber(L, data.number);
+		break;
+	case STRING:
+		lua_pushlstring(L, data.string.str, data.string.len);
+		break;
+	case LUSERDATA:
+		lua_pushlightuserdata(L, data.userdata);
+		break;
+	case FUSERDATA:
+		if (udatatype != INVALID_ID)
+		{
+			const char *name = NULL;
+			love::types.find(udatatype, name);
+			((love::Object *) data.userdata)->retain();
+			luax_newtype(L, name, flags, data.userdata);
+		}
+		else
+			lua_pushlightuserdata(L, data.userdata);
+		// I know this is not the same
+		// sadly, however, it's the most
+		// I can do (at the moment).
+		break;
+	default:
+		lua_pushnil(L);
+		break;
+	}
+}
+
+} // love

+ 76 - 73
src/common/Variant.h

@@ -1,73 +1,76 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_VARIANT_H
-#define LOVE_VARIANT_H
-
-#include <common/runtime.h>
-#include <common/Object.h>
-
-#include <cstring>
-
-namespace love
-{
-	class Variant : public love::Object
-	{
-	private:
-		enum Type
-		{
-			UNKNOWN = 0,
-			BOOLEAN,
-			NUMBER,
-			CHARACTER,
-			STRING,
-			LUSERDATA,
-			FUSERDATA
-		} type;
-		union
-		{
-			bool boolean;
-			char character;
-			double number;
-			struct {
-				const char *str;
-				size_t len;
-			} string;
-			void *userdata;
-		} data;
-		love::Type udatatype;
-		bits flags;
-
-	public:
-		
-		Variant(bool boolean);
-		Variant(double number);
-		Variant(const char *string, size_t len);
-		Variant(char c);
-		Variant(void *userdata);
-		Variant(love::Type udatatype, void *userdata);
-		virtual ~Variant();
-
-		static Variant *fromLua(lua_State *L, int n);
-		void toLua(lua_State *L);
-	}; // Variant
-} // love
-
-#endif // LOVE_VARIANT_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_VARIANT_H
+#define LOVE_VARIANT_H
+
+#include "common/runtime.h"
+#include "common/Object.h"
+
+#include <cstring>
+
+namespace love
+{
+
+class Variant : public love::Object
+{
+public:
+
+	Variant(bool boolean);
+	Variant(double number);
+	Variant(const char *string, size_t len);
+	Variant(char c);
+	Variant(void *userdata);
+	Variant(love::Type udatatype, void *userdata);
+	virtual ~Variant();
+
+	static Variant *fromLua(lua_State *L, int n);
+	void toLua(lua_State *L);
+
+private:
+	enum Type
+	{
+		UNKNOWN = 0,
+		BOOLEAN,
+		NUMBER,
+		CHARACTER,
+		STRING,
+		LUSERDATA,
+		FUSERDATA
+	} type;
+	union
+	{
+		bool boolean;
+		char character;
+		double number;
+		struct
+		{
+			const char *str;
+			size_t len;
+		} string;
+		void *userdata;
+	} data;
+	love::Type udatatype;
+	bits flags;
+
+}; // Variant
+} // love
+
+#endif // LOVE_VARIANT_H

+ 25 - 25
src/common/Vector.cpp

@@ -1,26 +1,26 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "Vector.h"
-
-namespace love
-{
-	// Implementation in header.
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "Vector.h"
+
+namespace love
+{
+// Implementation in header.
 }

+ 311 - 310
src/common/Vector.h

@@ -1,310 +1,311 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_VECTOR_H
-#define LOVE_VECTOR_H
-
-// STD
-#include <cmath>
-
-// LOVE
-#include "Matrix.h"
-
-namespace love
-{
-	/**
-	* 2D Vector class.
-	*
-	* @author Anders Ruud
-	* @date 2006-05-13
-	**/
-	class Vector
-	{
-	public:
-
-		// The components.
-		float x, y;
-
-		/**
-		* Creates a new (1,1) Vector.
-		**/
-		Vector();
-
-		/**
-		* Creates a new Vector.
-		* @param x The x position/dimension.
-		* @param y The y position/dimension.
-		**/
-		Vector(float x, float y);
-
-		/**
-		* Gets the length of the Vector.
-		* @return The length of the Vector.
-		*
-		* This method requires sqrt() and should be used
-		* carefully.
-		**/
-		float getLength() const;
-
-		/**
-		* Normalizes the Vector.
-		* @return The old length of the Vector.
-		**/
-		float normalize();
-
-		/**
-		* Gets a normal to the Vector.
-		* @return A normal to the Vector.
-		**/
-
-		Vector getNormal() const;
-
-		/**
-		* Adds a Vector to this Vector.
-		* @param v The Vector we want to add to this Vector.
-		* @return The resulting Vector.
-		**/
-		Vector operator + (const Vector & v) const;
-
-		/**
-		* Substracts a Vector to this Vector.
-		* @param v The Vector we want to subtract to this Vector.
-		* @return The resulting Vector.
-		**/
-		Vector operator - (const Vector & v) const;
-
-		/**
-		* Resizes a Vector by a scalar.
-		* @param s The scalar with which to resize the Vector.
-		* @return The resulting Vector.
-		**/
-		Vector operator * (float s) const;
-
-		/**
-		* Resizes a Vector by a scalar.
-		* @param s The scalar with which to resize the Vector.
-		* @return The resulting Vector.
-		**/
-		Vector operator / (float s) const;
-
-		/**
-		* Reverses the Vector.
-		* @return The reversed Vector.
-		**/
-		Vector operator - () const;
-
-		/**
-		* Adds a Vector to this Vector, and also saves changes in the first Vector.
-		* @param v The Vector we want to add to this Vector.
-		**/
-		void operator += (const Vector & v);
-
-		/**
-		* Subtracts a Vector to this Vector, and also saves changes in the first Vector.
-		* @param v The Vector we want to subtract to this Vector.
-		**/
-		void operator -= (const Vector & v);
-
-		/**
-		* Resizes the Vector, and also saves changes in the first Vector.
-		* @param s The scalar by which we want to resize the Vector.
-		**/
-		void operator *= (float s);
-
-		/**
-		* Resizes the Vector, and also saves changes in the first Vector.
-		* @param s The scalar by which we want to resize the Vector.
-		**/
-		void operator /= (float s);
-
-		/**
-		* Calculates the dot product of two Vectors.
-		* @return The dot product of the two Vectors.
-		**/
-		float operator * (const Vector & v) const;
-
-		/**
-		* Calculates the cross product of two Vectors.
-		* @return The cross product of the two Vectors.
-		**/
-		float operator ^ (const Vector & v) const;
-
-		bool operator == (const Vector & v) const;
-
-		bool operator < (const Vector & v) const;
-		/**
-		* Gets the x value of the Vector.
-		* @return The x value of the Vector.
-		**/
-		float getX() const;
-
-		/**
-		* Gets the x value of the Vector.
-		* @return The x value of the Vector.
-		**/
-		float getY() const;
-
-		/**
-		* Sets the x value of the Vector.
-		* @param The x value of the Vector.
-		**/
-		void setX(float x);
-
-		/**
-		* Sets the x value of the Vector.
-		* @param The x value of the Vector.
-		**/
-		void setY(float y);
-
-	};
-
-	inline float Vector::getLength() const
-	{
-		return sqrt(x*x + y*y);
-	}
-
-	inline Vector Vector::getNormal() const
-	{
-		return Vector(-y, x);
-	}
-
-	inline float Vector::normalize()
-	{
-
-		float len = getLength();
-
-		if (len > 0)
-			(*this) /= len;
-
-		return len;
-	}
-
-	/**
-	* Inline methods must have body in header.
-	**/
-
-	inline Vector::Vector()
-	{
-		x = 1;
-		y = 1;
-	}
-
-	inline Vector::Vector(float x, float y)
-	{
-		this->x = x;
-		this->y = y;
-	}
-
-	inline Vector Vector::operator + (const Vector & v) const
-	{
-		return Vector(x + v.x, y + v.y);
-	}
-
-	inline Vector Vector::operator - (const Vector & v) const
-	{
-		return Vector(x - v.getX(), y - v.getY());
-	}
-
-	inline Vector Vector::operator * (float s) const
-	{
-		return Vector(x*s, y*s);
-	}
-
-	inline Vector Vector::operator / (float s) const
-	{
-		return Vector(x/s, y/s);
-	}
-
-	inline Vector Vector::operator - () const
-	{
-		return Vector(-x, -y);
-	}
-
-	inline void Vector::operator += (const Vector & v)
-	{
-		x += v.getX();
-		y += v.getY();
-	}
-
-	inline void Vector::operator -= (const Vector & v)
-	{
-		x -= v.getX();
-		y -= v.getY();
-	}
-
-	inline void Vector::operator *= (float s)
-	{
-		x *= s;
-		y *= s;
-	}
-
-	inline void Vector::operator /= (float s)
-	{
-		x /= s;
-		y /= s;
-	}
-
-	inline float Vector::operator * (const Vector & v) const
-	{
-		return x * v.getX() + y * v.getY();
-	}
-
-	inline float Vector::operator ^ (const Vector & v) const
-	{
-		return x * v.getY() - y * v.getX();
-	}
-
-	inline bool Vector::operator == (const Vector & v) const
-	{
-		return getLength() == v.getLength();
-	}
-
-	inline bool Vector::operator < (const Vector & v) const
-	{
-		return getLength() < v.getLength();
-	}
-
-	/**
-	* Accessor methods
-	**/
-
-	inline float Vector::getX() const
-	{
-		return x;
-	}
-
-	inline float Vector::getY() const
-	{
-		return y;
-	}
-
-	inline void Vector::setX(float x)
-	{
-		this->x = x;
-	}
-
-	inline void Vector::setY(float y)
-	{
-		this->y = y;
-	}
-
-} //love
-
-#endif// LOVE_VECTOR_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_VECTOR_H
+#define LOVE_VECTOR_H
+
+// STD
+#include <cmath>
+
+// LOVE
+#include "Matrix.h"
+
+namespace love
+{
+
+/**
+ * 2D Vector class.
+ *
+ * @author Anders Ruud
+ * @date 2006-05-13
+ **/
+class Vector
+{
+public:
+
+	// The components.
+	float x, y;
+
+	/**
+	 * Creates a new (1,1) Vector.
+	 **/
+	Vector();
+
+	/**
+	 * Creates a new Vector.
+	 * @param x The x position/dimension.
+	 * @param y The y position/dimension.
+	 **/
+	Vector(float x, float y);
+
+	/**
+	 * Gets the length of the Vector.
+	 * @return The length of the Vector.
+	 *
+	 * This method requires sqrt() and should be used
+	 * carefully.
+	 **/
+	float getLength() const;
+
+	/**
+	 * Normalizes the Vector.
+	 * @return The old length of the Vector.
+	 **/
+	float normalize();
+
+	/**
+	 * Gets a normal to the Vector.
+	 * @return A normal to the Vector.
+	 **/
+
+	Vector getNormal() const;
+
+	/**
+	 * Adds a Vector to this Vector.
+	 * @param v The Vector we want to add to this Vector.
+	 * @return The resulting Vector.
+	 **/
+	Vector operator + (const Vector &v) const;
+
+	/**
+	 * Substracts a Vector to this Vector.
+	 * @param v The Vector we want to subtract to this Vector.
+	 * @return The resulting Vector.
+	 **/
+	Vector operator - (const Vector &v) const;
+
+	/**
+	 * Resizes a Vector by a scalar.
+	 * @param s The scalar with which to resize the Vector.
+	 * @return The resulting Vector.
+	 **/
+	Vector operator * (float s) const;
+
+	/**
+	 * Resizes a Vector by a scalar.
+	 * @param s The scalar with which to resize the Vector.
+	 * @return The resulting Vector.
+	 **/
+	Vector operator / (float s) const;
+
+	/**
+	 * Reverses the Vector.
+	 * @return The reversed Vector.
+	 **/
+	Vector operator - () const;
+
+	/**
+	 * Adds a Vector to this Vector, and also saves changes in the first Vector.
+	 * @param v The Vector we want to add to this Vector.
+	 **/
+	void operator += (const Vector &v);
+
+	/**
+	 * Subtracts a Vector to this Vector, and also saves changes in the first Vector.
+	 * @param v The Vector we want to subtract to this Vector.
+	 **/
+	void operator -= (const Vector &v);
+
+	/**
+	 * Resizes the Vector, and also saves changes in the first Vector.
+	 * @param s The scalar by which we want to resize the Vector.
+	 **/
+	void operator *= (float s);
+
+	/**
+	 * Resizes the Vector, and also saves changes in the first Vector.
+	 * @param s The scalar by which we want to resize the Vector.
+	 **/
+	void operator /= (float s);
+
+	/**
+	 * Calculates the dot product of two Vectors.
+	 * @return The dot product of the two Vectors.
+	 **/
+	float operator * (const Vector &v) const;
+
+	/**
+	 * Calculates the cross product of two Vectors.
+	 * @return The cross product of the two Vectors.
+	 **/
+	float operator ^ (const Vector &v) const;
+
+	bool operator == (const Vector &v) const;
+
+	bool operator < (const Vector &v) const;
+	/**
+	 * Gets the x value of the Vector.
+	 * @return The x value of the Vector.
+	 **/
+	float getX() const;
+
+	/**
+	 * Gets the x value of the Vector.
+	 * @return The x value of the Vector.
+	 **/
+	float getY() const;
+
+	/**
+	 * Sets the x value of the Vector.
+	 * @param The x value of the Vector.
+	 **/
+	void setX(float x);
+
+	/**
+	 * Sets the x value of the Vector.
+	 * @param The x value of the Vector.
+	 **/
+	void setY(float y);
+
+};
+
+inline float Vector::getLength() const
+{
+	return sqrt(x*x + y*y);
+}
+
+inline Vector Vector::getNormal() const
+{
+	return Vector(-y, x);
+}
+
+inline float Vector::normalize()
+{
+
+	float len = getLength();
+
+	if (len > 0)
+		(*this) /= len;
+
+	return len;
+}
+
+/**
+ * Inline methods must have body in header.
+ **/
+
+inline Vector::Vector()
+{
+	x = 1;
+	y = 1;
+}
+
+inline Vector::Vector(float x, float y)
+{
+	this->x = x;
+	this->y = y;
+}
+
+inline Vector Vector::operator + (const Vector &v) const
+{
+	return Vector(x + v.x, y + v.y);
+}
+
+inline Vector Vector::operator - (const Vector &v) const
+{
+	return Vector(x - v.getX(), y - v.getY());
+}
+
+inline Vector Vector::operator * (float s) const
+{
+	return Vector(x*s, y*s);
+}
+
+inline Vector Vector::operator / (float s) const
+{
+	return Vector(x/s, y/s);
+}
+
+inline Vector Vector::operator - () const
+{
+	return Vector(-x, -y);
+}
+
+inline void Vector::operator += (const Vector &v)
+{
+	x += v.getX();
+	y += v.getY();
+}
+
+inline void Vector::operator -= (const Vector &v)
+{
+	x -= v.getX();
+	y -= v.getY();
+}
+
+inline void Vector::operator *= (float s)
+{
+	x *= s;
+	y *= s;
+}
+
+inline void Vector::operator /= (float s)
+{
+	x /= s;
+	y /= s;
+}
+
+inline float Vector::operator * (const Vector &v) const
+{
+	return x * v.getX() + y * v.getY();
+}
+
+inline float Vector::operator ^ (const Vector &v) const
+{
+	return x * v.getY() - y * v.getX();
+}
+
+inline bool Vector::operator == (const Vector &v) const
+{
+	return getLength() == v.getLength();
+}
+
+inline bool Vector::operator < (const Vector &v) const
+{
+	return getLength() < v.getLength();
+}
+
+/**
+ * Accessor methods
+ **/
+
+inline float Vector::getX() const
+{
+	return x;
+}
+
+inline float Vector::getY() const
+{
+	return y;
+}
+
+inline void Vector::setX(float x)
+{
+	this->x = x;
+}
+
+inline void Vector::setY(float y)
+{
+	this->y = y;
+}
+
+} //love
+
+#endif// LOVE_VECTOR_H

+ 80 - 78
src/common/b64.cpp

@@ -1,78 +1,80 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "b64.h"
-
-namespace love
-{
-	static const char cd64[]="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq";
-
-	void b64_decode_block(char in[4], char out[3])
-	{
-		out[0] = (char)(in[0] << 2 | in[1] >> 4);
-		out[1] = (char)(in[1] << 4 | in[2] >> 2);
-		out[2] = (char)(((in[2] << 6) & 0xc0) | in[3]);
-	}
-
-	char * b64_decode(const char * src, int slen, int & size)
-	{
-		size = (slen / 4) * 3;
-
-		char * dst = new char[size];
-		char * d = dst;
-
-		char in[4], out[3], v;
-		int i, len, pos = 0;
-
-		while (pos <= slen)
-		{
-			for (len = 0, i = 0; i < 4 && pos <= slen; i++ )
-			{
-				v = 0;
-
-				while (pos <= slen && v == 0 )
-				{
-					v = src[pos++];
-					v = (char)((v < 43 || v > 122) ? 0 : cd64[v - 43]);
-					if (v)
-						v = (char)((v == '$') ? 0 : v - 61);
-				}
-
-				if (pos <= slen)
-				{
-					len++;
-					if (v)
-						in[i] = (char)(v - 1);
-				}
-				else
-					in[i] = 0;
-			}
-
-			if (len)
-			{
-				b64_decode_block(in, out);
-				for (i = 0; i < len - 1; i++)
-					*(d++) = out[i];
-			}
-		}
-
-		return dst;
-	}
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "b64.h"
+
+namespace love
+{
+
+static const char cd64[]="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq";
+
+void b64_decode_block(char in[4], char out[3])
+{
+	out[0] = (char)(in[0] << 2 | in[1] >> 4);
+	out[1] = (char)(in[1] << 4 | in[2] >> 2);
+	out[2] = (char)(((in[2] << 6) & 0xc0) | in[3]);
+}
+
+char *b64_decode(const char *src, int slen, int &size)
+{
+	size = (slen / 4) * 3;
+
+	char *dst = new char[size];
+	char *d = dst;
+
+	char in[4], out[3], v;
+	int i, len, pos = 0;
+
+	while (pos <= slen)
+	{
+		for (len = 0, i = 0; i < 4 && pos <= slen; i++)
+		{
+			v = 0;
+
+			while (pos <= slen && v == 0)
+			{
+				v = src[pos++];
+				v = (char)((v < 43 || v > 122) ? 0 : cd64[v - 43]);
+				if (v)
+					v = (char)((v == '$') ? 0 : v - 61);
+			}
+
+			if (pos <= slen)
+			{
+				len++;
+				if (v)
+					in[i] = (char)(v - 1);
+			}
+			else
+				in[i] = 0;
+		}
+
+		if (len)
+		{
+			b64_decode_block(in, out);
+			for (i = 0; i < len - 1; i++)
+				 *(d++) = out[i];
+		}
+	}
+
+	return dst;
+}
+
+} // love

+ 40 - 38
src/common/b64.h

@@ -1,39 +1,41 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "config.h"
-
-#ifndef LOVE_B64_H
-#define LOVE_B64_H
-
-namespace love
-{
-	/**
-	* Decode base64 encoded data.
-	*
-	* @param src The string containing the base64 data.
-	* @param slen The length of the string.
-	* @param size The size of the binary data is stored here.
-	* @return A chunk of memory containing the binary data (allocated with new[]).
-	*/
-	char * b64_decode(const char * src, int slen, int & size);
-} // love
-
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "config.h"
+
+#ifndef LOVE_B64_H
+#define LOVE_B64_H
+
+namespace love
+{
+
+/**
+ * Decode base64 encoded data.
+ *
+ * @param src The string containing the base64 data.
+ * @param slen The length of the string.
+ * @param size The size of the binary data is stored here.
+ * @return A chunk of memory containing the binary data (allocated with new[]).
+ */
+char *b64_decode(const char *src, int slen, int &size);
+
+} // love
+
 #endif // LOVE_B64_H

+ 93 - 93
src/common/config.h

@@ -1,93 +1,93 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_CONFIG_H
-#define LOVE_CONFIG_H
-
-// Platform stuff.
-#if defined(WIN32) || defined(_WIN32)
-#	define LOVE_WINDOWS 1
-#endif
-#if defined(linux) || defined(__linux) || defined(__linux__)
-#	define LOVE_LINUX 1
-#endif
-#if defined(__APPLE__)
-#	define LOVE_MACOSX 1
-#endif
-#if defined(macintosh)
-#	define LOVE_MACOS 1
-#endif
-
-// Endianness.
-#if defined(__i386__) || defined(__i386)
-#	define LOVE_LITTLE_ENDIAN 1
-#endif
-#if defined(__ppc__) || defined(__ppc) || defined(__powerpc__) || defined(__powerpc)
-#	define LOVE_BIG_ENDIAN 1
-#endif
-
-// Warnings.
-#ifndef _CRT_SECURE_NO_WARNINGS
-#	define _CRT_SECURE_NO_WARNINGS
-#endif
-
-// Preferably, and ironically, this macro should go unused.
-#ifndef LOVE_UNUSED
-#	define LOVE_UNUSED(x) (void)sizeof(x)
-#endif
-
-#ifndef LOVE_BUILD
-#	define LOVE_BUILD
-#	define LOVE_BUILD_STANDALONE
-#	define LOVE_BUILD_EXE
-//#	define LOVE_BUILD_DLL
-#endif
-
-// DLL-stuff.
-#ifdef LOVE_WINDOWS
-#	define LOVE_EXPORT __declspec(dllexport)
-#else
-#	define LOVE_EXPORT
-#endif
-
-#if defined(LOVE_WINDOWS)
-#	define LOVE_LEGENDARY_UTF8_ARGV_HACK
-#	define LOVE_LEGENDARY_CONSOLE_IO_HACK
-#	define NOMINMAX
-#endif
-
-#if defined(LOVE_MACOSX)
-#	define LOVE_LEGENDARY_LIBSTDCXX_HACK
-#endif
-
-// Autotools config.h
-#ifdef HAVE_CONFIG_H
-#	include <../config.h>
-#	undef VERSION
-#	ifdef WORDS_BIGENDIAN
-#		undef LOVE_LITTLE_ENDIAN
-#		define LOVE_BIG_ENDIAN 1
-#	else
-#		undef LOVE_BIG_ENDIAN
-#		define LOVE_LITTLE_ENDIAN 1
-#	endif
-#endif
-
-#endif // LOVE_CONFIG_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_CONFIG_H
+#define LOVE_CONFIG_H
+
+// Platform stuff.
+#if defined(WIN32) || defined(_WIN32)
+#	define LOVE_WINDOWS 1
+#endif
+#if defined(linux) || defined(__linux) || defined(__linux__)
+#	define LOVE_LINUX 1
+#endif
+#if defined(__APPLE__)
+#	define LOVE_MACOSX 1
+#endif
+#if defined(macintosh)
+#	define LOVE_MACOS 1
+#endif
+
+// Endianness.
+#if defined(__i386__) || defined(__i386)
+#	define LOVE_LITTLE_ENDIAN 1
+#endif
+#if defined(__ppc__) || defined(__ppc) || defined(__powerpc__) || defined(__powerpc)
+#	define LOVE_BIG_ENDIAN 1
+#endif
+
+// Warnings.
+#ifndef _CRT_SECURE_NO_WARNINGS
+#	define _CRT_SECURE_NO_WARNINGS
+#endif
+
+// Preferably, and ironically, this macro should go unused.
+#ifndef LOVE_UNUSED
+#	define LOVE_UNUSED(x) (void)sizeof(x)
+#endif
+
+#ifndef LOVE_BUILD
+#	define LOVE_BUILD
+#	define LOVE_BUILD_STANDALONE
+#	define LOVE_BUILD_EXE
+//#	define LOVE_BUILD_DLL
+#endif
+
+// DLL-stuff.
+#ifdef LOVE_WINDOWS
+#	define LOVE_EXPORT __declspec(dllexport)
+#else
+#	define LOVE_EXPORT
+#endif
+
+#if defined(LOVE_WINDOWS)
+#	define LOVE_LEGENDARY_UTF8_ARGV_HACK
+#	define LOVE_LEGENDARY_CONSOLE_IO_HACK
+#	define NOMINMAX
+#endif
+
+#if defined(LOVE_MACOSX)
+#	define LOVE_LEGENDARY_LIBSTDCXX_HACK
+#endif
+
+// Autotools config.h
+#ifdef HAVE_CONFIG_H
+#	include <../config.h>
+#	undef VERSION
+#	ifdef WORDS_BIGENDIAN
+#		undef LOVE_LITTLE_ENDIAN
+#		define LOVE_BIG_ENDIAN 1
+#	else
+#		undef LOVE_BIG_ENDIAN
+#		define LOVE_LITTLE_ENDIAN 1
+#	endif
+#endif
+
+#endif // LOVE_CONFIG_H

+ 42 - 41
src/common/delay.cpp

@@ -1,41 +1,42 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-
-#include "delay.h"
-
-namespace love {
-
-	void delay(unsigned int ms) {
-#if LOVE_THREADS == LOVE_THREADS_POSIX
-		struct timespec ts1, ts2;
-
-		ts1.tv_sec = ms / 1000;
-		ts1.tv_nsec = (ms % 1000) * 1000000;
-		// FIXME: handle signals
-		nanosleep(&ts1, &ts2);
-#elif LOVE_THREADS == LOVE_THREADS_WIN32
-		Sleep(ms);
-#elif LOVE_THREADS == LOVE_THREADS_SDL
-		SDL_Delay(ms);
-#endif
-	}
-
-} // namespace love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "delay.h"
+
+namespace love
+{
+
+void delay(unsigned int ms)
+{
+#if LOVE_THREADS == LOVE_THREADS_POSIX
+	struct timespec ts1, ts2;
+
+	ts1.tv_sec = ms / 1000;
+	ts1.tv_nsec = (ms % 1000) * 1000000;
+	// FIXME: handle signals
+	nanosleep(&ts1, &ts2);
+#elif LOVE_THREADS == LOVE_THREADS_WIN32
+	Sleep(ms);
+#elif LOVE_THREADS == LOVE_THREADS_SDL
+	SDL_Delay(ms);
+#endif
+}
+
+} // love

+ 33 - 33
src/common/delay.h

@@ -1,33 +1,33 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef DELAY_H_
-#define DELAY_H_
-
-#include <thread/threads.h>
-
-
-namespace love {
-
-	void delay(unsigned int ms);
-
-}; // namespace love
-
-#endif /* DELAY_H_ */
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef DELAY_H_
+#define DELAY_H_
+
+#include <thread/threads.h>
+
+namespace love
+{
+
+void delay(unsigned int ms);
+
+}; // namespace love
+
+#endif // DELAY_H_

+ 65 - 64
src/common/int.h

@@ -1,64 +1,65 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_INT_H
-#define LOVE_INT_H
-
-#include <common/config.h>
-
-#ifndef LOVE_WINDOWS
-#include <stdint.h>
-#endif
-
-#define LOVE_INT8_MAX   0x7F
-#define LOVE_UINT8_MAX  0xFF
-#define LOVE_INT16_MAX  0x7FFF
-#define LOVE_UINT16_MAX 0xFFFF
-#define LOVE_INT32_MAX  0x7FFFFFFF
-#define LOVE_UINT32_MAX 0xFFFFFFFF
-#define LOVE_INT64_MAX  0x7FFFFFFFFFFFFFFF
-#define LOVE_UINT64_MAX 0xFFFFFFFFFFFFFFFF
-
-namespace love
-{
-// Blame Microsoft
-#ifdef LOVE_WINDOWS
-	typedef __int8 int8;
-	typedef unsigned __int8 uint8;
-	typedef __int16 int16;
-	typedef unsigned __int16 uint16;
-	typedef __int32 int32;
-	typedef unsigned __int32 uint32;
-	typedef __int64 int64;
-	typedef unsigned __int64 uint64;
-
-#else
-	typedef int8_t int8;
-	typedef uint8_t uint8;
-	typedef int16_t int16;
-	typedef uint16_t uint16;
-	typedef int32_t int32;
-	typedef uint32_t uint32;
-	typedef int64_t int64;
-	typedef uint64_t uint64;
-#endif
-} // love
-
-#endif // LOVE_INT_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_INT_H
+#define LOVE_INT_H
+
+#include "common/config.h"
+
+#ifndef LOVE_WINDOWS
+#include <stdint.h>
+#endif
+
+#define LOVE_INT8_MAX   0x7F
+#define LOVE_UINT8_MAX  0xFF
+#define LOVE_INT16_MAX  0x7FFF
+#define LOVE_UINT16_MAX 0xFFFF
+#define LOVE_INT32_MAX  0x7FFFFFFF
+#define LOVE_UINT32_MAX 0xFFFFFFFF
+#define LOVE_INT64_MAX  0x7FFFFFFFFFFFFFFF
+#define LOVE_UINT64_MAX 0xFFFFFFFFFFFFFFFF
+
+namespace love
+{
+
+// Blame Microsoft
+#ifdef LOVE_WINDOWS
+	typedef __int8 int8;
+	typedef unsigned __int8 uint8;
+	typedef __int16 int16;
+	typedef unsigned __int16 uint16;
+	typedef __int32 int32;
+	typedef unsigned __int32 uint32;
+	typedef __int64 int64;
+	typedef unsigned __int64 uint64;
+#else // LOVE_WINDOWS
+	typedef int8_t int8;
+	typedef uint8_t uint8;
+	typedef int16_t int16;
+	typedef uint16_t uint16;
+	typedef int32_t int32;
+	typedef uint32_t uint32;
+	typedef int64_t int64;
+	typedef uint64_t uint64;
+#endif // LOVE_WINDOWS
+
+} // love
+
+#endif // LOVE_INT_H

+ 85 - 85
src/common/math.h

@@ -1,85 +1,85 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_MATH_H
-#define LOVE_MATH_H
-
-#include <climits> // for CHAR_BIT
-
-/* Definitions of useful mathematical constants
- * M_E        - e
- * M_LOG2E    - log2(e)
- * M_LOG10E   - log10(e)
- * M_LN2      - ln(2)
- * M_LN10     - ln(10)
- * M_PI       - pi
- * M_PI_2     - pi/2
- * M_PI_4     - pi/4
- * M_1_PI     - 1/pi
- * M_2_PI     - 2/pi
- * M_2_SQRTPI - 2/sqrt(pi)
- * M_SQRT2    - sqrt(2)
- * M_SQRT1_2  - 1/sqrt(2)
- */
-
-#define LOVE_M_E        2.71828182845904523536
-#define LOVE_M_LOG2E    1.44269504088896340736
-#define LOVE_M_LOG10E   0.434294481903251827651
-#define LOVE_M_LN2      0.693147180559945309417
-#define LOVE_M_LN10     2.30258509299404568402
-#define LOVE_M_PI       3.14159265358979323846
-#define LOVE_M_PI_2     1.57079632679489661923
-#define LOVE_M_PI_4     0.785398163397448309616
-#define LOVE_M_1_PI     0.318309886183790671538
-#define LOVE_M_2_PI     0.636619772367581343076
-#define LOVE_M_2_SQRTPI 1.12837916709551257390
-#define LOVE_M_SQRT2    1.41421356237309504880
-#define LOVE_M_SQRT1_2  0.707106781186547524401
-#define LOVE_M_TORAD	(float)(LOVE_M_PI/180.0)
-#define LOVE_M_TODEG    (float)(180.0/LOVE_M_PI)
-#define LOVE_TORAD(x)	(float)(x*LOVE_M_TORAD)
-#define LOVE_TODEG(x)	(float)(x*LOVE_M_TODEG)
-
-namespace love
-{
-
-struct vertex
-{
-	unsigned char r, g, b, a;
-	float x, y;
-	float s, t;
-};
-
-inline int next_p2(int x)
-{
-	x += (x == 0);
-	x--;
-	for (unsigned int i = 1; i < sizeof(int)*CHAR_BIT; i <<= 1) x |= x >> i;
-	return ++x;
-}
-
-inline float next_p2(float x)
-{
-	return static_cast<float>(next_p2(static_cast<int>(x)));
-}
-
-} // love
-
-#endif // LOVE_MATH_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_MATH_H
+#define LOVE_MATH_H
+
+#include <climits> // for CHAR_BIT
+
+/* Definitions of useful mathematical constants
+ * M_E        - e
+ * M_LOG2E    - log2(e)
+ * M_LOG10E   - log10(e)
+ * M_LN2      - ln(2)
+ * M_LN10     - ln(10)
+ * M_PI       - pi
+ * M_PI_2     - pi/2
+ * M_PI_4     - pi/4
+ * M_1_PI     - 1/pi
+ * M_2_PI     - 2/pi
+ * M_2_SQRTPI - 2/sqrt(pi)
+ * M_SQRT2    - sqrt(2)
+ * M_SQRT1_2  - 1/sqrt(2)
+ */
+
+#define LOVE_M_E        2.71828182845904523536
+#define LOVE_M_LOG2E    1.44269504088896340736
+#define LOVE_M_LOG10E   0.434294481903251827651
+#define LOVE_M_LN2      0.693147180559945309417
+#define LOVE_M_LN10     2.30258509299404568402
+#define LOVE_M_PI       3.14159265358979323846
+#define LOVE_M_PI_2     1.57079632679489661923
+#define LOVE_M_PI_4     0.785398163397448309616
+#define LOVE_M_1_PI     0.318309886183790671538
+#define LOVE_M_2_PI     0.636619772367581343076
+#define LOVE_M_2_SQRTPI 1.12837916709551257390
+#define LOVE_M_SQRT2    1.41421356237309504880
+#define LOVE_M_SQRT1_2  0.707106781186547524401
+#define LOVE_M_TORAD	(float)(LOVE_M_PI/180.0)
+#define LOVE_M_TODEG    (float)(180.0/LOVE_M_PI)
+#define LOVE_TORAD(x)	(float)(x*LOVE_M_TORAD)
+#define LOVE_TODEG(x)	(float)(x*LOVE_M_TODEG)
+
+namespace love
+{
+
+struct vertex
+{
+	unsigned char r, g, b, a;
+	float x, y;
+	float s, t;
+};
+
+inline int next_p2(int x)
+{
+	x += (x == 0);
+	x--;
+	for (unsigned int i = 1; i < sizeof(int)*CHAR_BIT; i <<= 1) x |= x >> i;
+	return ++x;
+}
+
+inline float next_p2(float x)
+{
+	return static_cast<float>(next_p2(static_cast<int>(x)));
+}
+
+} // love
+
+#endif // LOVE_MATH_H

+ 481 - 480
src/common/runtime.cpp

@@ -1,480 +1,481 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "runtime.h"
-
-// LOVE
-#include "Module.h"
-#include "Object.h"
-#include "Reference.h"
-#include "StringMap.h"
-#include <thread/threads.h>
-
-// STD
-#include <iostream>
-
-
-namespace love
-{
-	static thread::Mutex *gcmutex = 0;
-	void *_gcmutex = 0;
-	unsigned int _gcthread = 0;
-	/**
-	* Called when an object is collected. The object is released
-	* once in this function, possibly deleting it.
-	**/
-	static int w__gc(lua_State * L)
-	{
-		if (!gcmutex)
-		{
-			gcmutex = new thread::Mutex();
-			_gcmutex = (void*) gcmutex;
-		}
-		Proxy * p = (Proxy *)lua_touserdata(L, 1);
-		Object * t = (Object *)p->data;
-		if (p->own)
-		{
-			thread::Lock lock(gcmutex);
-			_gcthread = thread::ThreadBase::threadId();
-			t->release();
-		}
-		return 0;
-	}
-
-	static int w__tostring(lua_State * L)
-	{
-		lua_pushvalue(L, lua_upvalueindex(1));
-		return 1;
-	}
-
-	static int w__typeOf(lua_State * L)
-	{
-		Proxy * p = (Proxy *)lua_touserdata(L, 1);
-		Type t = luax_type(L, 2);
-		luax_pushboolean(L, p->flags[t]);
-		return 1;
-	}
-
-	static int w__eq(lua_State * L)
-	{
-		Proxy * p1 = (Proxy *)lua_touserdata(L, 1);
-		Proxy * p2 = (Proxy *)lua_touserdata(L, 2);
-		luax_pushboolean(L, p1->data == p2->data);
-		return 1;
-	}
-
-	Reference * luax_refif(lua_State * L, int type)
-	{
-		Reference * r = 0;
-
-		// Create a reference only if the test succeeds.
-		if (lua_type(L, -1) == type)
-			r = new Reference(L);
-		else // Pop the value even if it fails (but also if it succeeds).
-			lua_pop(L, 1);
-
-		return r;
-	}
-
-	void luax_printstack(lua_State * L)
-	{
-		for (int i = 1;i<=lua_gettop(L);i++)
-		{
-			std::cout << i << " - " << luaL_typename(L, i) << std::endl;
-		}
-	}
-
-	bool luax_toboolean(lua_State * L, int idx)
-	{
-		return (lua_toboolean(L, idx) != 0);
-	}
-
-	void luax_pushboolean(lua_State * L, bool b)
-	{
-		lua_pushboolean(L, b ? 1 : 0);
-	}
-
-	bool luax_optboolean(lua_State * L, int idx, bool b)
-	{
-		if (lua_isboolean(L, idx) == 1)
-			return (lua_toboolean(L, idx) == 1 ? true : false);
-		return b;
-	}
-
-	std::string luax_checkstring(lua_State * L, int idx)
-	{
-		size_t len;
-		const char * str = luaL_checklstring(L, idx, &len);
-		return std::string(str, len);
-	}
-
-	void luax_pushstring(lua_State * L, std::string str)
-	{
-		lua_pushlstring(L, str.data(), str.size());
-	}
-
-	int luax_assert_argc(lua_State * L, int min)
-	{
-		int argc = lua_gettop(L);
-		if ( argc < min )
-			return luaL_error(L, "Incorrect number of arguments. Got [%d], expected at least [%d]", argc, min);
-		return 0;
-	}
-
-	int luax_assert_argc(lua_State * L, int min, int max)
-	{
-		int argc = lua_gettop(L);
-		if ( argc < min || argc > max)
-			return luaL_error(L, "Incorrect number of arguments. Got [%d], expected [%d-%d]", argc, min, max);
-		return 0;
-	}
-
-	int luax_assert_function(lua_State * L, int n)
-	{
-		if (!lua_isfunction(L, n))
-			return luaL_error(L, "Argument must be of type \"function\".");
-		return 0;
-	}
-
-	int luax_register_module(lua_State * L, const WrappedModule & m)
-	{
-		// Put a reference to the C++ module in Lua.
-		luax_getregistry(L, REGISTRY_MODULES);
-
-		Proxy * p = (Proxy *)lua_newuserdata(L, sizeof(Proxy));
-		p->own = true;
-		p->data = m.module;
-		p->flags = m.flags;
-
-		luaL_newmetatable(L, m.module->getName());
-		lua_pushvalue(L, -1);
-		lua_setfield(L, -2, "__index");
-		lua_pushcfunction(L, w__gc);
-		lua_setfield(L, -2, "__gc");
-
-		lua_setmetatable(L, -2);
-		lua_setfield(L, -2, m.name); // _modules[name] = proxy
-		lua_pop(L, 1);
-
-		// Gets the love table.
-		luax_insistglobal(L, "love");
-
-		// Create new table for module.
-		lua_newtable(L);
-
-		// Register all the functions.
-		luaL_register(L, 0, m.functions);
-
-		// Register types.
-		if (m.types != 0)
-			for (const lua_CFunction * t = m.types; *t != 0; t++)
-				(*t)(L);
-
-		lua_pushvalue(L, -1);
-		lua_setfield(L, -3, m.name); // love.graphics = table
-		lua_remove(L, -2); // love
-
-		return 1;
-	}
-
-	int luax_preload(lua_State * L, lua_CFunction f, const char * name)
-	{
-		lua_getglobal(L, "package");
-		lua_getfield(L, -1, "preload");
-		lua_pushcfunction(L, f);
-		lua_setfield(L, -2, name);
-		lua_pop(L, 2);
-		return 0;
-	}
-
-	int luax_register_type(lua_State * L, const char * tname, const luaL_Reg * f)
-	{
-		luaL_newmetatable(L, tname);
-
-		// m.__index = m
-		lua_pushvalue(L, -1);
-		lua_setfield(L, -2, "__index");
-
-		// setup gc
-		lua_pushcfunction(L, w__gc);
-		lua_setfield(L, -2, "__gc");
-
-		// Add equality
-		lua_pushcfunction(L, w__eq);
-		lua_setfield(L, -2, "__eq");
-
-		// Add tostring function.
-		lua_pushstring(L, tname);
-		lua_pushcclosure(L, w__tostring, 1);
-		lua_setfield(L, -2, "__tostring");
-
-		// Add tostring to as type() as well.
-		lua_pushstring(L, tname);
-		lua_pushcclosure(L, w__tostring, 1);
-		lua_setfield(L, -2, "type");
-
-		// Add typeOf
-		lua_pushcfunction(L, w__typeOf);
-		lua_setfield(L, -2, "typeOf");
-
-		if (f != 0)
-			luaL_register(L, 0, f);
-
-		lua_pop(L, 1); // Pops metatable.
-		return 0;
-	}
-
-	int luax_table_insert(lua_State * L, int tindex, int vindex, int pos)
-	{
-		if (tindex < 0)
-			tindex = lua_gettop(L)+1+tindex;
-		if (vindex < 0)
-			vindex = lua_gettop(L)+1+vindex;
-		if (pos == -1)
-		{
-			lua_pushvalue(L, vindex);
-			lua_rawseti(L, tindex, lua_objlen(L, tindex)+1);
-			return 0;
-		}
-		else if (pos < 0)
-			pos = lua_objlen(L, tindex)+1+pos;
-		for (int i = lua_objlen(L, tindex)+1; i > pos; i--)
-		{
-			lua_rawgeti(L, tindex, i-1);
-			lua_rawseti(L, tindex, i);
-		}
-		lua_pushvalue(L, vindex);
-		lua_rawseti(L, tindex, pos);
-		return 0;
-	}
-
-	int luax_register_searcher(lua_State * L, lua_CFunction f, int pos)
-	{
-		// Add the package loader to the package.loaders table.
-		lua_getglobal(L, "package");
-
-		if (lua_isnil(L, -1))
-			return luaL_error(L, "Can't register searcher: package table does not exist.");
-
-		lua_getfield(L, -1, "loaders");
-
-		if (lua_isnil(L, -1))
-			return luaL_error(L, "Can't register searcher: package.loaders table does not exist.");
-
-		lua_pushcfunction(L, f);
-		luax_table_insert(L, -2, -1, pos);
-		lua_pop(L, 3);
-		return 0;
-	}
-
-	void luax_newtype(lua_State * L, const char * name, bits flags, void * data, bool own)
-	{
-		Proxy * u = (Proxy *)lua_newuserdata(L, sizeof(Proxy));
-
-		u->data = data;
-		u->flags = flags;
-		u->own = own;
-
-		luaL_newmetatable(L, name);
-		lua_setmetatable(L, -2);
-	}
-
-	bool luax_istype(lua_State * L, int idx, love::bits type)
-	{
-		if (lua_isuserdata(L, idx) == 0)
-			return false;
-
-		return ((((Proxy *)lua_touserdata(L, idx))->flags & type) == type);
-	}
-
-	int luax_getfunction(lua_State * L, const char * mod, const char * fn)
-	{
-		lua_getglobal(L, "love");
-		if (lua_isnil(L, -1)) return luaL_error(L, "Could not find global love!");
-		lua_getfield(L, -1, mod);
-		if (lua_isnil(L, -1)) return luaL_error(L, "Could not find love.%s!", mod);
-		lua_getfield(L, -1, fn);
-		if (lua_isnil(L, -1)) return luaL_error(L, "Could not find love.%s.%s!", mod, fn);
-
-		lua_remove(L, -2); // remove mod
-		lua_remove(L, -2); // remove fn
-		return 0;
-	}
-
-	int luax_convobj(lua_State * L, int idx, const char * mod, const char * fn)
-	{
-		// Convert string to a file.
-		luax_getfunction(L, mod, fn);
-		lua_pushvalue(L, idx); // The initial argument.
-		lua_call(L, 1, 1); // Call the function, one arg, one return value.
-		lua_replace(L, idx); // Replace the initial argument with the new object.
-		return 0;
-	}
-
-	int luax_convobj(lua_State * L, int idxs[], int n, const char * mod, const char * fn)
-	{
-		luax_getfunction(L, mod, fn);
-		for (int i = 0; i < n; i++)
-		{
-			lua_pushvalue(L, idxs[i]); // The arguments.
-		}
-		lua_call(L, n, 1); // Call the function, n args, one return value.
-		lua_replace(L, idxs[0]); // Replace the initial argument with the new object.
-		return 0;
-	}
-
-	int luax_strtofile(lua_State * L, int idx)
-	{
-		return luax_convobj(L, idx, "filesystem", "newFile");
-	}
-
-	int luax_filetodata(lua_State * L, int idx)
-	{
-		return luax_convobj(L, idx, "filesystem", "read");
-	}
-
-	int luax_insist(lua_State * L, int idx, const char * k)
-	{
-		// Convert to absolute index if necessary.
-		if (idx < 0 && idx > LUA_REGISTRYINDEX)
-			idx = lua_gettop(L) + ++idx;
-
-		lua_getfield(L, idx, k);
-
-		// Create if necessary.
-		if (!lua_istable(L, -1))
-		{
-			lua_pop(L, 1); // Pop the non-table.
-			lua_newtable(L);
-			lua_pushvalue(L, -1); // Duplicate the table to leave on top.
-			lua_setfield(L, idx, k); // lua_stack[idx][k] = lua_stack[-1] (table)
-		}
-
-		return 1;
-	}
-
-	int luax_insistglobal(lua_State * L, const char * k)
-	{
-		lua_getglobal(L, k);
-
-		if (!lua_istable(L, -1))
-		{
-			lua_pop(L, 1); // Pop the non-table.
-			lua_newtable(L);
-			lua_pushvalue(L, -1);
-			lua_setglobal(L, k);
-		}
-
-		return 1;
-	}
-
-	int luax_insistlove(lua_State * L, const char * k)
-	{
-		luax_insistglobal(L, "love");
-		luax_insist(L, -1, k);
-
-		// The love table should be replaced with the top stack
-		// item. Only the reqested table should remain on the stack.
-		lua_replace(L, -2);
-
-		return 1;
-	}
-
-	int luax_getregistry(lua_State * L, Registry r)
-	{
-		switch(r)
-		{
-		case REGISTRY_GC:
-			return luax_insistlove(L, "_gc");
-		case REGISTRY_MODULES:
-			return luax_insistlove(L, "_modules");
-		default:
-			return luaL_error(L, "Attempted to use invalid registry.");
-		}
-	}
-
-	StringMap<Type, TYPE_MAX_ENUM>::Entry typeEntries[] =
-	{
-		{"Invalid", INVALID_ID},
-
-		{"Object", OBJECT_ID},
-		{"Data", DATA_ID},
-		{"Module", MODULE_ID},
-
-		// Filesystem
-		{"File", FILESYSTEM_FILE_ID},
-		{"FileData", FILESYSTEM_FILE_DATA_ID},
-
-		// Font
-		{"GlyphData", FONT_GLYPH_DATA_ID},
-		{"Rasterizer", FONT_RASTERIZER_ID},
-
-		// Graphics
-		{"Drawable", GRAPHICS_DRAWABLE_ID},
-		{"Image", GRAPHICS_IMAGE_ID},
-		{"Quad", GRAPHICS_QUAD_ID},
-		{"Font", GRAPHICS_FONT_ID},
-		{"ParticleSystem", GRAPHICS_PARTICLE_SYSTEM_ID},
-		{"SpriteBatch", GRAPHICS_SPRITE_BATCH_ID},
-		{"Canvas", GRAPHICS_CANVAS_ID},
-
-		// Image
-		{"ImageData", IMAGE_IMAGE_DATA_ID},
-
-		// Audio
-		{"Source", AUDIO_SOURCE_ID},
-
-		// Sound
-		{"SoundData", SOUND_SOUND_DATA_ID},
-		{"Decoder", SOUND_DECODER_ID},
-
-		// Physics
-		{"World", PHYSICS_WORLD_ID},
-		{"Contact", PHYSICS_CONTACT_ID},
-		{"Body", PHYSICS_BODY_ID},
-		{"Shape", PHYSICS_SHAPE_ID},
-		{"CircleShape", PHYSICS_CIRCLE_SHAPE_ID},
-		{"PolygonShape", PHYSICS_POLYGON_SHAPE_ID},
-		{"Joint", PHYSICS_JOINT_ID},
-		{"MouseJoint", PHYSICS_MOUSE_JOINT_ID},
-		{"DistanceJoint", PHYSICS_DISTANCE_JOINT_ID},
-		{"PrismaticJoint", PHYSICS_PRISMATIC_JOINT_ID},
-		{"RevoluteJoint", PHYSICS_REVOLUTE_JOINT_ID},
-		{"PulleyJoint", PHYSICS_PULLEY_JOINT_ID},
-		{"GearJoint", PHYSICS_GEAR_JOINT_ID},
-
-		// Thread
-		{"Thread", THREAD_THREAD_ID},
-
-		// The modules themselves. Only add abstracted modules here.
-		{"filesystem", MODULE_FILESYSTEM_ID},
-		{"image", MODULE_IMAGE_ID},
-		{"sound", MODULE_SOUND_ID},
-	};
-
-	StringMap<Type, TYPE_MAX_ENUM> types(typeEntries, sizeof(typeEntries));
-
-	Type luax_type(lua_State * L, int idx)
-	{
-		Type t = INVALID_ID;
-		types.find(luaL_checkstring(L, idx), t);
-		return t;
-	}
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "runtime.h"
+
+// LOVE
+#include "Module.h"
+#include "Object.h"
+#include "Reference.h"
+#include "StringMap.h"
+#include "thread/threads.h"
+
+// STD
+#include <iostream>
+
+namespace love
+{
+
+static thread::Mutex *gcmutex = 0;
+void *_gcmutex = 0;
+unsigned int _gcthread = 0;
+/**
+ * Called when an object is collected. The object is released
+ * once in this function, possibly deleting it.
+ **/
+static int w__gc(lua_State *L)
+{
+	if (!gcmutex)
+	{
+		gcmutex = new thread::Mutex();
+		_gcmutex = (void *) gcmutex;
+	}
+	Proxy *p = (Proxy *)lua_touserdata(L, 1);
+	Object *t = (Object *)p->data;
+	if (p->own)
+	{
+		thread::Lock lock(gcmutex);
+		_gcthread = thread::ThreadBase::threadId();
+		t->release();
+	}
+	return 0;
+}
+
+static int w__tostring(lua_State *L)
+{
+	lua_pushvalue(L, lua_upvalueindex(1));
+	return 1;
+}
+
+static int w__typeOf(lua_State *L)
+{
+	Proxy *p = (Proxy *)lua_touserdata(L, 1);
+	Type t = luax_type(L, 2);
+	luax_pushboolean(L, p->flags[t]);
+	return 1;
+}
+
+static int w__eq(lua_State *L)
+{
+	Proxy *p1 = (Proxy *)lua_touserdata(L, 1);
+	Proxy *p2 = (Proxy *)lua_touserdata(L, 2);
+	luax_pushboolean(L, p1->data == p2->data);
+	return 1;
+}
+
+Reference *luax_refif (lua_State *L, int type)
+{
+	Reference *r = 0;
+
+	// Create a reference only if the test succeeds.
+	if (lua_type(L, -1) == type)
+		r = new Reference(L);
+	else // Pop the value even if it fails (but also if it succeeds).
+		lua_pop(L, 1);
+
+	return r;
+}
+
+void luax_printstack(lua_State *L)
+{
+	for (int i = 1; i<=lua_gettop(L); i++)
+	{
+		std::cout << i << " - " << luaL_typename(L, i) << std::endl;
+	}
+}
+
+bool luax_toboolean(lua_State *L, int idx)
+{
+	return (lua_toboolean(L, idx) != 0);
+}
+
+void luax_pushboolean(lua_State *L, bool b)
+{
+	lua_pushboolean(L, b ? 1 : 0);
+}
+
+bool luax_optboolean(lua_State *L, int idx, bool b)
+{
+	if (lua_isboolean(L, idx) == 1)
+		return (lua_toboolean(L, idx) == 1 ? true : false);
+	return b;
+}
+
+std::string luax_checkstring(lua_State *L, int idx)
+{
+	size_t len;
+	const char *str = luaL_checklstring(L, idx, &len);
+	return std::string(str, len);
+}
+
+void luax_pushstring(lua_State *L, std::string str)
+{
+	lua_pushlstring(L, str.data(), str.size());
+}
+
+int luax_assert_argc(lua_State *L, int min)
+{
+	int argc = lua_gettop(L);
+	if (argc < min)
+		return luaL_error(L, "Incorrect number of arguments. Got [%d], expected at least [%d]", argc, min);
+	return 0;
+}
+
+int luax_assert_argc(lua_State *L, int min, int max)
+{
+	int argc = lua_gettop(L);
+	if (argc < min || argc > max)
+		return luaL_error(L, "Incorrect number of arguments. Got [%d], expected [%d-%d]", argc, min, max);
+	return 0;
+}
+
+int luax_assert_function(lua_State *L, int n)
+{
+	if (!lua_isfunction(L, n))
+		return luaL_error(L, "Argument must be of type \"function\".");
+	return 0;
+}
+
+int luax_register_module(lua_State *L, const WrappedModule &m)
+{
+	// Put a reference to the C++ module in Lua.
+	luax_getregistry(L, REGISTRY_MODULES);
+
+	Proxy *p = (Proxy *)lua_newuserdata(L, sizeof(Proxy));
+	p->own = true;
+	p->data = m.module;
+	p->flags = m.flags;
+
+	luaL_newmetatable(L, m.module->getName());
+	lua_pushvalue(L, -1);
+	lua_setfield(L, -2, "__index");
+	lua_pushcfunction(L, w__gc);
+	lua_setfield(L, -2, "__gc");
+
+	lua_setmetatable(L, -2);
+	lua_setfield(L, -2, m.name); // _modules[name] = proxy
+	lua_pop(L, 1);
+
+	// Gets the love table.
+	luax_insistglobal(L, "love");
+
+	// Create new table for module.
+	lua_newtable(L);
+
+	// Register all the functions.
+	luaL_register(L, 0, m.functions);
+
+	// Register types.
+	if (m.types != 0)
+		for (const lua_CFunction *t = m.types; *t != 0; t++)
+			(*t)(L);
+
+	lua_pushvalue(L, -1);
+	lua_setfield(L, -3, m.name); // love.graphics = table
+	lua_remove(L, -2); // love
+
+	return 1;
+}
+
+int luax_preload(lua_State *L, lua_CFunction f, const char *name)
+{
+	lua_getglobal(L, "package");
+	lua_getfield(L, -1, "preload");
+	lua_pushcfunction(L, f);
+	lua_setfield(L, -2, name);
+	lua_pop(L, 2);
+	return 0;
+}
+
+int luax_register_type(lua_State *L, const char *tname, const luaL_Reg *f)
+{
+	luaL_newmetatable(L, tname);
+
+	// m.__index = m
+	lua_pushvalue(L, -1);
+	lua_setfield(L, -2, "__index");
+
+	// setup gc
+	lua_pushcfunction(L, w__gc);
+	lua_setfield(L, -2, "__gc");
+
+	// Add equality
+	lua_pushcfunction(L, w__eq);
+	lua_setfield(L, -2, "__eq");
+
+	// Add tostring function.
+	lua_pushstring(L, tname);
+	lua_pushcclosure(L, w__tostring, 1);
+	lua_setfield(L, -2, "__tostring");
+
+	// Add tostring to as type() as well.
+	lua_pushstring(L, tname);
+	lua_pushcclosure(L, w__tostring, 1);
+	lua_setfield(L, -2, "type");
+
+	// Add typeOf
+	lua_pushcfunction(L, w__typeOf);
+	lua_setfield(L, -2, "typeOf");
+
+	if (f != 0)
+		luaL_register(L, 0, f);
+
+	lua_pop(L, 1); // Pops metatable.
+	return 0;
+}
+
+int luax_table_insert(lua_State *L, int tindex, int vindex, int pos)
+{
+	if (tindex < 0)
+		tindex = lua_gettop(L)+1+tindex;
+	if (vindex < 0)
+		vindex = lua_gettop(L)+1+vindex;
+	if (pos == -1)
+	{
+		lua_pushvalue(L, vindex);
+		lua_rawseti(L, tindex, lua_objlen(L, tindex)+1);
+		return 0;
+	}
+	else if (pos < 0)
+		pos = lua_objlen(L, tindex)+1+pos;
+	for (int i = lua_objlen(L, tindex)+1; i > pos; i--)
+	{
+		lua_rawgeti(L, tindex, i-1);
+		lua_rawseti(L, tindex, i);
+	}
+	lua_pushvalue(L, vindex);
+	lua_rawseti(L, tindex, pos);
+	return 0;
+}
+
+int luax_register_searcher(lua_State *L, lua_CFunction f, int pos)
+{
+	// Add the package loader to the package.loaders table.
+	lua_getglobal(L, "package");
+
+	if (lua_isnil(L, -1))
+		return luaL_error(L, "Can't register searcher: package table does not exist.");
+
+	lua_getfield(L, -1, "loaders");
+
+	if (lua_isnil(L, -1))
+		return luaL_error(L, "Can't register searcher: package.loaders table does not exist.");
+
+	lua_pushcfunction(L, f);
+	luax_table_insert(L, -2, -1, pos);
+	lua_pop(L, 3);
+	return 0;
+}
+
+void luax_newtype(lua_State *L, const char *name, bits flags, void *data, bool own)
+{
+	Proxy *u = (Proxy *)lua_newuserdata(L, sizeof(Proxy));
+
+	u->data = data;
+	u->flags = flags;
+	u->own = own;
+
+	luaL_newmetatable(L, name);
+	lua_setmetatable(L, -2);
+}
+
+bool luax_istype(lua_State *L, int idx, love::bits type)
+{
+	if (lua_isuserdata(L, idx) == 0)
+		return false;
+
+	return ((((Proxy *)lua_touserdata(L, idx))->flags & type) == type);
+}
+
+int luax_getfunction(lua_State *L, const char *mod, const char *fn)
+{
+	lua_getglobal(L, "love");
+	if (lua_isnil(L, -1)) return luaL_error(L, "Could not find global love!");
+	lua_getfield(L, -1, mod);
+	if (lua_isnil(L, -1)) return luaL_error(L, "Could not find love.%s!", mod);
+	lua_getfield(L, -1, fn);
+	if (lua_isnil(L, -1)) return luaL_error(L, "Could not find love.%s.%s!", mod, fn);
+
+	lua_remove(L, -2); // remove mod
+	lua_remove(L, -2); // remove fn
+	return 0;
+}
+
+int luax_convobj(lua_State *L, int idx, const char *mod, const char *fn)
+{
+	// Convert string to a file.
+	luax_getfunction(L, mod, fn);
+	lua_pushvalue(L, idx); // The initial argument.
+	lua_call(L, 1, 1); // Call the function, one arg, one return value.
+	lua_replace(L, idx); // Replace the initial argument with the new object.
+	return 0;
+}
+
+int luax_convobj(lua_State *L, int idxs[], int n, const char *mod, const char *fn)
+{
+	luax_getfunction(L, mod, fn);
+	for (int i = 0; i < n; i++)
+	{
+		lua_pushvalue(L, idxs[i]); // The arguments.
+	}
+	lua_call(L, n, 1); // Call the function, n args, one return value.
+	lua_replace(L, idxs[0]); // Replace the initial argument with the new object.
+	return 0;
+}
+
+int luax_strtofile(lua_State *L, int idx)
+{
+	return luax_convobj(L, idx, "filesystem", "newFile");
+}
+
+int luax_filetodata(lua_State *L, int idx)
+{
+	return luax_convobj(L, idx, "filesystem", "read");
+}
+
+int luax_insist(lua_State *L, int idx, const char *k)
+{
+	// Convert to absolute index if necessary.
+	if (idx < 0 && idx > LUA_REGISTRYINDEX)
+		idx = lua_gettop(L) + ++idx;
+
+	lua_getfield(L, idx, k);
+
+	// Create if necessary.
+	if (!lua_istable(L, -1))
+	{
+		lua_pop(L, 1); // Pop the non-table.
+		lua_newtable(L);
+		lua_pushvalue(L, -1); // Duplicate the table to leave on top.
+		lua_setfield(L, idx, k); // lua_stack[idx][k] = lua_stack[-1] (table)
+	}
+
+	return 1;
+}
+
+int luax_insistglobal(lua_State *L, const char *k)
+{
+	lua_getglobal(L, k);
+
+	if (!lua_istable(L, -1))
+	{
+		lua_pop(L, 1); // Pop the non-table.
+		lua_newtable(L);
+		lua_pushvalue(L, -1);
+		lua_setglobal(L, k);
+	}
+
+	return 1;
+}
+
+int luax_insistlove(lua_State *L, const char *k)
+{
+	luax_insistglobal(L, "love");
+	luax_insist(L, -1, k);
+
+	// The love table should be replaced with the top stack
+	// item. Only the reqested table should remain on the stack.
+	lua_replace(L, -2);
+
+	return 1;
+}
+
+int luax_getregistry(lua_State *L, Registry r)
+{
+	switch (r)
+	{
+	case REGISTRY_GC:
+		return luax_insistlove(L, "_gc");
+	case REGISTRY_MODULES:
+		return luax_insistlove(L, "_modules");
+	default:
+		return luaL_error(L, "Attempted to use invalid registry.");
+	}
+}
+
+StringMap<Type, TYPE_MAX_ENUM>::Entry typeEntries[] =
+{
+	{"Invalid", INVALID_ID},
+
+	{"Object", OBJECT_ID},
+	{"Data", DATA_ID},
+	{"Module", MODULE_ID},
+
+	// Filesystem
+	{"File", FILESYSTEM_FILE_ID},
+	{"FileData", FILESYSTEM_FILE_DATA_ID},
+
+	// Font
+	{"GlyphData", FONT_GLYPH_DATA_ID},
+	{"Rasterizer", FONT_RASTERIZER_ID},
+
+	// Graphics
+	{"Drawable", GRAPHICS_DRAWABLE_ID},
+	{"Image", GRAPHICS_IMAGE_ID},
+	{"Quad", GRAPHICS_QUAD_ID},
+	{"Font", GRAPHICS_FONT_ID},
+	{"ParticleSystem", GRAPHICS_PARTICLE_SYSTEM_ID},
+	{"SpriteBatch", GRAPHICS_SPRITE_BATCH_ID},
+	{"Canvas", GRAPHICS_CANVAS_ID},
+
+	// Image
+	{"ImageData", IMAGE_IMAGE_DATA_ID},
+
+	// Audio
+	{"Source", AUDIO_SOURCE_ID},
+
+	// Sound
+	{"SoundData", SOUND_SOUND_DATA_ID},
+	{"Decoder", SOUND_DECODER_ID},
+
+	// Physics
+	{"World", PHYSICS_WORLD_ID},
+	{"Contact", PHYSICS_CONTACT_ID},
+	{"Body", PHYSICS_BODY_ID},
+	{"Shape", PHYSICS_SHAPE_ID},
+	{"CircleShape", PHYSICS_CIRCLE_SHAPE_ID},
+	{"PolygonShape", PHYSICS_POLYGON_SHAPE_ID},
+	{"Joint", PHYSICS_JOINT_ID},
+	{"MouseJoint", PHYSICS_MOUSE_JOINT_ID},
+	{"DistanceJoint", PHYSICS_DISTANCE_JOINT_ID},
+	{"PrismaticJoint", PHYSICS_PRISMATIC_JOINT_ID},
+	{"RevoluteJoint", PHYSICS_REVOLUTE_JOINT_ID},
+	{"PulleyJoint", PHYSICS_PULLEY_JOINT_ID},
+	{"GearJoint", PHYSICS_GEAR_JOINT_ID},
+
+	// Thread
+	{"Thread", THREAD_THREAD_ID},
+
+	// The modules themselves. Only add abstracted modules here.
+	{"filesystem", MODULE_FILESYSTEM_ID},
+	{"image", MODULE_IMAGE_ID},
+	{"sound", MODULE_SOUND_ID},
+};
+
+StringMap<Type, TYPE_MAX_ENUM> types(typeEntries, sizeof(typeEntries));
+
+Type luax_type(lua_State *L, int idx)
+{
+	Type t = INVALID_ID;
+	types.find(luaL_checkstring(L, idx), t);
+	return t;
+}
+
+} // love

+ 384 - 383
src/common/runtime.h

@@ -1,383 +1,384 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_RUNTIME_H
-#define LOVE_RUNTIME_H
-
-// LOVE
-#include "types.h"
-
-// Lua
-extern "C" {
-	#include <lua.h>
-	#include <lualib.h>
-	#include <lauxlib.h>
-}
-
-namespace love
-{
-	// Forward declarations.
-	class Module;
-	class Reference;
-
-	// Exposed mutex of the GC
-	extern void *_gcmutex;
-	extern unsigned int _gcthread;
-
-	/**
-	* Registries represent special tables which can be accessed with
-	* luax_getregistry.
-	**/
-	enum Registry
-	{
-		REGISTRY_GC = 1,
-		REGISTRY_MODULES,
-	};
-
-	/**
-	* This structure wraps all Lua-exposed objects. It exists in the
-	* Lua state as a full userdata (so we can catch __gc "events"),
-	* though the Object it refers to is light userdata in the sense
-	* that it is not allocated by the Lua VM.
-	**/
-	struct Proxy
-	{
-		// Holds type information (see types.h).
-		bits flags;
-
-		// The light userdata.
-		void * data;
-
-		// True if Lua should delete on GC.
-		bool own;
-	};
-
-	/**
-	* A Module with Lua wrapper functions and other data.
-	**/
-	struct WrappedModule
-	{
-		// The module containing the functions.
-		Module * module;
-
-		// The name for the table to put the functions in, without the 'love'-prefix.
-		const char * name;
-
-		// The type flags of this module.
-		love::bits flags;
-
-		// The functions of the module (last element {0,0}).
-		const luaL_Reg * functions;
-
-		// A list of functions which expose the types of the modules (last element 0).
-		const lua_CFunction * types;
-
-	};
-
-	/**
-	* Returns a reference to the top stack element (-1) if the value
-	* is of the specified type. If the value is incorrect, zero is returned.
-	*
-	* In any case, the top stack element is popped, regardless of its type.
-	**/
-	Reference * luax_refif(lua_State * L, int type);
-
-	/**
-	* Prints the current contents of the stack. Only useful for debugging.
-	* @param L The Lua state.
-	**/
-	void luax_printstack(lua_State * L);
-
-	/**
-	* Converts the value at idx to a bool. It follow the same rules
-	* as lua_toboolean, but returns a bool instead of an int.
-	* @param L The Lua state.
-	* @param idx The index on the Lua stack.
-	* @return True if the value evaluates to true, false otherwise.
-	**/
-	bool luax_toboolean(lua_State * L, int idx);
-
-	/**
-	* Pushes a bool onto the stack. It's the same as lua_pushboolean,
-	* but with bool instead of int.
-	* @param L The Lua state.
-	* @param b The bool to push.
-	**/
-	void luax_pushboolean(lua_State * L, bool b);
-
-	/**
-	* Converts the value at idx to a bool, or if not present, b is returned.
-	* @param L The Lua state.
-	* @param idx The index of the Lua stack.
-	* @param b The value to return if no value exist at the specified index.
-	* @return True if the value evaluates to true, false otherwise.
-	**/
-	bool luax_optboolean(lua_State * L, int idx, bool b);
-
-	/**
-	* Converts the value at idx to a std::string. It takes care of the string
-	* size and possible embedded nulls.
-	* @param L The Lua state.
-	* @param idx The index on the Lua stack.
-	* @return Copy of the string at the specified index.
-	**/
-	std::string luax_checkstring(lua_State * L, int idx);
-
-	/**
-	* Pushes a std::string onto the stack. It uses the length of the string
-	* for lua_pushlstring's len argument.
-	* @param L The Lua state.
-	* @param str The string to push.
-	**/
-	void luax_pushstring(lua_State * L, std::string str);
-
-	/**
-	* Require at least 'min' number of items on the stack.
-	* @param L The Lua state.
-	* @param min The minimum number of items on the stack.
-	* @return Zero if conditions are met, otherwise a Lua error (longjmp).
-	**/
-	int luax_assert_argc(lua_State * L, int min);
-
-	/**
-	* Require at least 'min', but more than 'max' items on the stack.
-	* @param L The Lua state.
-	* @param min The minimum number of items on the stack.
-	* @param max The maximum number of items on the stack.
-	* @return Zero if conditions are met, otherwise a Lua error (longjmp).
-	**/
-	int luax_assert_argc(lua_State * L, int min, int max);
-
-	/**
-	* Require that the value at idx is a function.
-	* @param L The Lua state.
-	 *@param idx The index on the stack.
-	**/
-	int luax_assert_function(lua_State * L, int idx);
-
-	/**
-	* Register a module in the love table. The love table will be created if it does not exist.
-	* @param L The Lua state.
-	**/
-	int luax_register_module(lua_State * L, const WrappedModule & m);
-
-	/**
-	* Inserts a module with 'name' into the package.preloaded table.
-	* @param f The function to be called when the module is opened.
-	* @param name The name of the module, with 'love'-prefix, for instance 'love.graphics'.
-	**/
-	int luax_preload(lua_State * L, lua_CFunction f, const char * name);
-
-	/**
-	* Register a new type.
-	* @param tname The name of the type. This must not conflict with other type names,
-	* even from other modules.
-	* @param f The list of member functions for the type.
-	**/
-	int luax_register_type(lua_State * L, const char * tname, const luaL_Reg * f = 0);
-
-	/**
-	 * Do a table.insert from C
-	 * @param L the state
-	 * @param tindex the stack index of the table
-	 * @param vindex the stack index of the value
-	 * @param pos the position to insert it in
-	 **/
-	int luax_table_insert(lua_State * L, int tindex, int vindex, int pos = -1);
-
-	/**
-	* Register a new searcher function for package.loaders. This can for instance enable
-	* loading of files through love.filesystem using standard require.
-	* @param L The Lua state.
-	* @param f The searcher function.
-	* @param pos The position to insert the loader in.
-	**/
-	int luax_register_searcher(lua_State * L, lua_CFunction f, int pos = -1);
-
-	/**
-	* Creates a new Lua-accessible object of the given type, and put it on the stack.
-	* @param L The Lua state.
-	* @param name The name of the type. This must match the used earlier with luax_register_type.
-	* @param flags The type information.
-	* @param data The pointer to the actual object.
-	* @own Set this to true (default) if the object should be released upon garbage collection.
-	**/
-	void luax_newtype(lua_State * L, const char * name, bits flags, void * data, bool own = true);
-
-	/**
-	* Checks whether the value at idx is a certain type.
-	* @param L The Lua state.
-	* @param idx The index on the stack.
-	* @param type The type to check for.
-	* @return True if the value is Proxy of the specified type, false otherwise.
-	**/
-	bool luax_istype(lua_State * L, int idx, love::bits type);
-
-	/**
-	* Gets the function love.module.function and puts it on top of the stack (alone). If the
-	* love table, the module, or the function does not exist, an error is returned.
-	* @return An error if nonexistent, or 1 if successful.
-	**/
-	int luax_getfunction(lua_State * L, const char * module, const char * function);
-
-	/**
-	* Converts an object into another object by the specified function love.module.function.
-	* The conversion function must accept a single object of the relevant type as a parameter,
-	* and returnone value. If the function does not exist (see luax_getfunction), an error is returned.
-	*
-	* Note that the initial object at idx is replaced by the new object.
-	*
-	* @param L The Lua state.
-	* @param idx The index on the stack.
-	* @param module The module in the love table.
-	* @param function The function in the module.
-	**/
-	int luax_convobj(lua_State * L, int idx, const char * module, const char * function);
-
-	/**
-	* Converts an object into another object by the specified function love.module.function.
-	* The conversion function must accept a single object of the relevant type as its first parameter,
-	* and return one value. If the function does not exist (see luax_getfunction), an error is returned.
-	*
-	* Note that the initial object at idx is replaced by the new object.
-	*
-	* @param L The Lua state.
-	* @param idxs An array of indices on the stack.
-	* @param n How many arguments are being passed.
-	* @param module The module in the love table.
-	* @param function The function in the module.
-	**/
-	int luax_convobj(lua_State * L, int idxs[], int n, const char * module, const char * function);
-
-	/**
-	* 'Insist' that a table 'k' exists in the table at idx. Insistence involves that the
-	* table (k) is created if it does not exist in the table at idx. The table at idx must
-	* pre-exist, however. Also note that if the a non-table value exists at the specified
-	* location, it will be overwritten with a new table. The insisted table, and only the
-	* insisted table, will be placed on top of the stack.
-	*
-	* @param idx The index on the stack containing a table.
-	* @param k The name of the table we are insisting exist.
-	**/
-	int luax_insist(lua_State * L, int idx, const char * k);
-
-	/**
-	* Insist that a global table 'k' exists. See luax_insist.
-	* @param k The name of the table we are insisting exist.
-	**/
-	int luax_insistglobal(lua_State * L, const char * k);
-
-	/**
-	* Insists that a table 'k' exists inside the 'love' table. See luax_insist.
-	* @param k The name of the table we are insisting exist.
-	**/
-	int luax_insistlove(lua_State * L, const char * k);
-
-	/**
-	* Gets (creates if needed) the specified Registry, and puts it on top
-	* of the stack.
-	* @param L The Lua state.
-	* @param r The Registry to get.
-	**/
-	int luax_getregistry(lua_State * L, Registry r);
-
-	Type luax_type(lua_State * L, int idx);
-
-	/**
-	 * Convert the value at the specified index to an Lua number, and then
-	 * convert to a float.
-	 *
-	 * @param L The Lua state.
-	 * @param idx The index on the stack.
-	 */
-	inline float luax_tofloat(lua_State *L, int idx)
-	{
-		return static_cast<float>(lua_tonumber(L, idx));
-	}
-
-	/**
-	 * Like luax_tofloat, but checks that the value is a number.
-	 *
-	 * @see luax_tofloat
-	 */
-	inline float luax_checkfloat(lua_State *L, int idx)
-	{
-		return static_cast<float>(luaL_checknumber(L, idx));
-	}
-
-	/**
-	* Converts the value at idx to the specified type without checking that
-	* this conversion is valid. If the type has been previously verified with
-	* luax_istype, then this can be safely used. Otherwise, use luax_checktype.
-	* @param L The Lua state.
-	* @param idx The index on the stack.
-	* @param name The name of the type.
-	* @param type The type bit.
-	**/
-	template <typename T>
-	T * luax_totype(lua_State * L, int idx, const char *, love::bits)
-	{
-		return (T*)(((Proxy *)lua_touserdata(L, idx))->data);
-	}
-
-	/**
-	* Like luax_totype, but causes an error if the value at idx is not Proxy,
-	* or is not the specified type.
-	* @param L The Lua state.
-	* @param idx The index on the stack.
-	* @param name The name of the type.
-	* @param type The type bit.
-	**/
-	template <typename T>
-	T * luax_checktype(lua_State * L, int idx, const char * name, love::bits type)
-	{
-		if (lua_isuserdata(L, idx) == 0)
-			luaL_error(L, "Incorrect parameter type: expected userdata.");
-
-		Proxy * u = (Proxy *)lua_touserdata(L, idx);
-
-		if ((u->flags & type) != type)
-			luaL_error(L, "Incorrect parameter type: expected %s", name);
-
-		return (T *)u->data;
-	}
-
-	template <typename T>
-	T * luax_getmodule(lua_State * L, const char * k, love::bits type)
-	{
-		luax_getregistry(L, REGISTRY_MODULES);
-		lua_getfield(L, -1, k);
-
-		if (!lua_isuserdata(L, -1))
-			luaL_error(L, "Tried to get nonexisting module %s.", k);
-
-		Proxy * u = (Proxy *)lua_touserdata(L, -1);
-
-		if ((u->flags & type) != type)
-			luaL_error(L, "Incorrect module %s", k);
-
-		lua_pop(L, 2);
-
-		return (T*)u->data;
-	}
-
-} // love
-
-#endif // LOVE_RUNTIME_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_RUNTIME_H
+#define LOVE_RUNTIME_H
+
+// LOVE
+#include "types.h"
+
+// Lua
+extern "C" {
+	#include <lua.h>
+	#include <lualib.h>
+	#include <lauxlib.h>
+}
+
+namespace love
+{
+
+// Forward declarations.
+class Module;
+class Reference;
+
+// Exposed mutex of the GC
+extern void *_gcmutex;
+extern unsigned int _gcthread;
+
+/**
+ * Registries represent special tables which can be accessed with
+ * luax_getregistry.
+ **/
+enum Registry
+{
+	REGISTRY_GC = 1,
+	REGISTRY_MODULES,
+};
+
+/**
+ * This structure wraps all Lua-exposed objects. It exists in the
+ * Lua state as a full userdata (so we can catch __gc "events"),
+ * though the Object it refers to is light userdata in the sense
+ * that it is not allocated by the Lua VM.
+ **/
+struct Proxy
+{
+	// Holds type information (see types.h).
+	bits flags;
+
+	// The light userdata.
+	void *data;
+
+	// True if Lua should delete on GC.
+	bool own;
+};
+
+/**
+ * A Module with Lua wrapper functions and other data.
+ **/
+struct WrappedModule
+{
+	// The module containing the functions.
+	Module *module;
+
+	// The name for the table to put the functions in, without the 'love'-prefix.
+	const char *name;
+
+	// The type flags of this module.
+	love::bits flags;
+
+	// The functions of the module (last element {0,0}).
+	const luaL_Reg *functions;
+
+	// A list of functions which expose the types of the modules (last element 0).
+	const lua_CFunction *types;
+
+};
+
+/**
+ * Returns a reference to the top stack element (-1) if the value
+ * is of the specified type. If the value is incorrect, zero is returned.
+ *
+ * In any case, the top stack element is popped, regardless of its type.
+ **/
+Reference *luax_refif (lua_State *L, int type);
+
+/**
+ * Prints the current contents of the stack. Only useful for debugging.
+ * @param L The Lua state.
+ **/
+void luax_printstack(lua_State *L);
+
+/**
+ * Converts the value at idx to a bool. It follow the same rules
+ * as lua_toboolean, but returns a bool instead of an int.
+ * @param L The Lua state.
+ * @param idx The index on the Lua stack.
+ * @return True if the value evaluates to true, false otherwise.
+ **/
+bool luax_toboolean(lua_State *L, int idx);
+
+/**
+ * Pushes a bool onto the stack. It's the same as lua_pushboolean,
+ * but with bool instead of int.
+ * @param L The Lua state.
+ * @param b The bool to push.
+ **/
+void luax_pushboolean(lua_State *L, bool b);
+
+/**
+ * Converts the value at idx to a bool, or if not present, b is returned.
+ * @param L The Lua state.
+ * @param idx The index of the Lua stack.
+ * @param b The value to return if no value exist at the specified index.
+ * @return True if the value evaluates to true, false otherwise.
+ **/
+bool luax_optboolean(lua_State *L, int idx, bool b);
+
+/**
+ * Converts the value at idx to a std::string. It takes care of the string
+ * size and possible embedded nulls.
+ * @param L The Lua state.
+ * @param idx The index on the Lua stack.
+ * @return Copy of the string at the specified index.
+ **/
+std::string luax_checkstring(lua_State *L, int idx);
+
+/**
+ * Pushes a std::string onto the stack. It uses the length of the string
+ * for lua_pushlstring's len argument.
+ * @param L The Lua state.
+ * @param str The string to push.
+ **/
+void luax_pushstring(lua_State *L, std::string str);
+
+/**
+ * Require at least 'min' number of items on the stack.
+ * @param L The Lua state.
+ * @param min The minimum number of items on the stack.
+ * @return Zero if conditions are met, otherwise a Lua error (longjmp).
+ **/
+int luax_assert_argc(lua_State *L, int min);
+
+/**
+ * Require at least 'min', but more than 'max' items on the stack.
+ * @param L The Lua state.
+ * @param min The minimum number of items on the stack.
+ * @param max The maximum number of items on the stack.
+ * @return Zero if conditions are met, otherwise a Lua error (longjmp).
+ **/
+int luax_assert_argc(lua_State *L, int min, int max);
+
+/**
+ * Require that the value at idx is a function.
+ * @param L The Lua state.
+ *@param idx The index on the stack.
+ **/
+int luax_assert_function(lua_State *L, int idx);
+
+/**
+ * Register a module in the love table. The love table will be created if it does not exist.
+ * @param L The Lua state.
+ **/
+int luax_register_module(lua_State *L, const WrappedModule &m);
+
+/**
+ * Inserts a module with 'name' into the package.preloaded table.
+ * @param f The function to be called when the module is opened.
+ * @param name The name of the module, with 'love'-prefix, for instance 'love.graphics'.
+ **/
+int luax_preload(lua_State *L, lua_CFunction f, const char *name);
+
+/**
+ * Register a new type.
+ * @param tname The name of the type. This must not conflict with other type names,
+ * even from other modules.
+ * @param f The list of member functions for the type.
+ **/
+int luax_register_type(lua_State *L, const char *tname, const luaL_Reg *f = 0);
+
+/**
+ * Do a table.insert from C
+ * @param L the state
+ * @param tindex the stack index of the table
+ * @param vindex the stack index of the value
+ * @param pos the position to insert it in
+ **/
+int luax_table_insert(lua_State *L, int tindex, int vindex, int pos = -1);
+
+/**
+ * Register a new searcher function for package.loaders. This can for instance enable
+ * loading of files through love.filesystem using standard require.
+ * @param L The Lua state.
+ * @param f The searcher function.
+ * @param pos The position to insert the loader in.
+ **/
+int luax_register_searcher(lua_State *L, lua_CFunction f, int pos = -1);
+
+/**
+ * Creates a new Lua-accessible object of the given type, and put it on the stack.
+ * @param L The Lua state.
+ * @param name The name of the type. This must match the used earlier with luax_register_type.
+ * @param flags The type information.
+ * @param data The pointer to the actual object.
+ * @own Set this to true (default) if the object should be released upon garbage collection.
+ **/
+void luax_newtype(lua_State *L, const char *name, bits flags, void *data, bool own = true);
+
+/**
+ * Checks whether the value at idx is a certain type.
+ * @param L The Lua state.
+ * @param idx The index on the stack.
+ * @param type The type to check for.
+ * @return True if the value is Proxy of the specified type, false otherwise.
+ **/
+bool luax_istype(lua_State *L, int idx, love::bits type);
+
+/**
+ * Gets the function love.module.function and puts it on top of the stack (alone). If the
+ * love table, the module, or the function does not exist, an error is returned.
+ * @return An error if nonexistent, or 1 if successful.
+ **/
+int luax_getfunction(lua_State *L, const char *module, const char *function);
+
+/**
+ * Converts an object into another object by the specified function love.module.function.
+ * The conversion function must accept a single object of the relevant type as a parameter,
+ * and returnone value. If the function does not exist (see luax_getfunction), an error is returned.
+ *
+ * Note that the initial object at idx is replaced by the new object.
+ *
+ * @param L The Lua state.
+ * @param idx The index on the stack.
+ * @param module The module in the love table.
+ * @param function The function in the module.
+ **/
+int luax_convobj(lua_State *L, int idx, const char *module, const char *function);
+
+/**
+ * Converts an object into another object by the specified function love.module.function.
+ * The conversion function must accept a single object of the relevant type as its first parameter,
+ * and return one value. If the function does not exist (see luax_getfunction), an error is returned.
+ *
+ * Note that the initial object at idx is replaced by the new object.
+ *
+ * @param L The Lua state.
+ * @param idxs An array of indices on the stack.
+ * @param n How many arguments are being passed.
+ * @param module The module in the love table.
+ * @param function The function in the module.
+ **/
+int luax_convobj(lua_State *L, int idxs[], int n, const char *module, const char *function);
+
+/**
+ * 'Insist' that a table 'k' exists in the table at idx. Insistence involves that the
+ * table (k) is created if it does not exist in the table at idx. The table at idx must
+ * pre-exist, however. Also note that if the a non-table value exists at the specified
+ * location, it will be overwritten with a new table. The insisted table, and only the
+ * insisted table, will be placed on top of the stack.
+ *
+ * @param idx The index on the stack containing a table.
+ * @param k The name of the table we are insisting exist.
+ **/
+int luax_insist(lua_State *L, int idx, const char *k);
+
+/**
+ * Insist that a global table 'k' exists. See luax_insist.
+ * @param k The name of the table we are insisting exist.
+ **/
+int luax_insistglobal(lua_State *L, const char *k);
+
+/**
+ * Insists that a table 'k' exists inside the 'love' table. See luax_insist.
+ * @param k The name of the table we are insisting exist.
+ **/
+int luax_insistlove(lua_State *L, const char *k);
+
+/**
+ * Gets (creates if needed) the specified Registry, and puts it on top
+ * of the stack.
+ * @param L The Lua state.
+ * @param r The Registry to get.
+ **/
+int luax_getregistry(lua_State *L, Registry r);
+
+Type luax_type(lua_State *L, int idx);
+
+/**
+ * Convert the value at the specified index to an Lua number, and then
+ * convert to a float.
+ *
+ * @param L The Lua state.
+ * @param idx The index on the stack.
+ */
+inline float luax_tofloat(lua_State *L, int idx)
+{
+	return static_cast<float>(lua_tonumber(L, idx));
+}
+
+/**
+ * Like luax_tofloat, but checks that the value is a number.
+ *
+ * @see luax_tofloat
+ */
+inline float luax_checkfloat(lua_State *L, int idx)
+{
+	return static_cast<float>(luaL_checknumber(L, idx));
+}
+
+/**
+ * Converts the value at idx to the specified type without checking that
+ * this conversion is valid. If the type has been previously verified with
+ * luax_istype, then this can be safely used. Otherwise, use luax_checktype.
+ * @param L The Lua state.
+ * @param idx The index on the stack.
+ * @param name The name of the type.
+ * @param type The type bit.
+ **/
+template <typename T>
+T *luax_totype(lua_State *L, int idx, const char *, love::bits)
+{
+	return (T *)(((Proxy *)lua_touserdata(L, idx))->data);
+}
+
+/**
+ * Like luax_totype, but causes an error if the value at idx is not Proxy,
+ * or is not the specified type.
+ * @param L The Lua state.
+ * @param idx The index on the stack.
+ * @param name The name of the type.
+ * @param type The type bit.
+ **/
+template <typename T>
+T *luax_checktype(lua_State *L, int idx, const char *name, love::bits type)
+{
+	if (lua_isuserdata(L, idx) == 0)
+		luaL_error(L, "Incorrect parameter type: expected userdata.");
+
+	Proxy *u = (Proxy *)lua_touserdata(L, idx);
+
+	if ((u->flags & type) != type)
+		luaL_error(L, "Incorrect parameter type: expected %s", name);
+
+	return (T *)u->data;
+}
+
+template <typename T>
+T *luax_getmodule(lua_State *L, const char *k, love::bits type)
+{
+	luax_getregistry(L, REGISTRY_MODULES);
+	lua_getfield(L, -1, k);
+
+	if (!lua_isuserdata(L, -1))
+		luaL_error(L, "Tried to get nonexisting module %s.", k);
+
+	Proxy *u = (Proxy *)lua_touserdata(L, -1);
+
+	if ((u->flags & type) != type)
+		luaL_error(L, "Incorrect module %s", k);
+
+	lua_pop(L, 2);
+
+	return (T *)u->data;
+}
+
+} // love
+
+#endif // LOVE_RUNTIME_H

+ 174 - 173
src/common/types.h

@@ -1,173 +1,174 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_TYPES_H
-#define LOVE_TYPES_H
-
-// STD
-#include <bitset>
-
-namespace love
-{
-	enum Type
-	{
-		INVALID_ID = 0,
-		// Cross-module types.
-		OBJECT_ID,
-		DATA_ID,
-		MODULE_ID,
-
-		// Filesystem.
-		FILESYSTEM_FILE_ID,
-		FILESYSTEM_FILE_DATA_ID,
-
-		// Font
-		FONT_GLYPH_DATA_ID,
-		FONT_RASTERIZER_ID,
-
-		// Graphics
-		GRAPHICS_DRAWABLE_ID,
-		GRAPHICS_DRAWQABLE_ID,
-		GRAPHICS_IMAGE_ID,
-		GRAPHICS_QUAD_ID,
-		GRAPHICS_FONT_ID,
-		GRAPHICS_PARTICLE_SYSTEM_ID,
-		GRAPHICS_SPRITE_BATCH_ID,
-		GRAPHICS_CANVAS_ID,
-		GRAPHICS_PIXELEFFECT_ID,
-
-		// Image
-		IMAGE_IMAGE_DATA_ID,
-		IMAGE_ENCODED_IMAGE_DATA_ID,
-
-		// Audio
-		AUDIO_SOURCE_ID,
-
-		// Sound
-		SOUND_SOUND_DATA_ID,
-		SOUND_DECODER_ID,
-
-		// Physics
-		PHYSICS_WORLD_ID,
-		PHYSICS_CONTACT_ID,
-		PHYSICS_BODY_ID,
-		PHYSICS_FIXTURE_ID,
-		PHYSICS_SHAPE_ID,
-		PHYSICS_CIRCLE_SHAPE_ID,
-		PHYSICS_POLYGON_SHAPE_ID,
-		PHYSICS_EDGE_SHAPE_ID,
-		PHYSICS_CHAIN_SHAPE_ID,
-		PHYSICS_JOINT_ID,
-		PHYSICS_MOUSE_JOINT_ID,
-		PHYSICS_DISTANCE_JOINT_ID,
-		PHYSICS_PRISMATIC_JOINT_ID,
-		PHYSICS_REVOLUTE_JOINT_ID,
-		PHYSICS_PULLEY_JOINT_ID,
-		PHYSICS_GEAR_JOINT_ID,
-		PHYSICS_FRICTION_JOINT_ID,
-		PHYSICS_WELD_JOINT_ID,
-		PHYSICS_ROPE_JOINT_ID,
-		PHYSICS_WHEEL_JOINT_ID,
-
-		// Thread
-		THREAD_THREAD_ID,
-
-		// The modules themselves. Only add abstracted modules here.
-		MODULE_FILESYSTEM_ID,
-		MODULE_IMAGE_ID,
-		MODULE_SOUND_ID,
-
-		// Count the number of bits needed.
-		TYPE_MAX_ENUM
-	};
-
-	typedef std::bitset<TYPE_MAX_ENUM> bits;
-
-	const bits INVALID_T = bits(1) << INVALID_ID;
-
-	const bits OBJECT_T = bits(1) << OBJECT_ID;
-	const bits DATA_T = (bits(1) << DATA_ID) | OBJECT_T;
-	const bits MODULE_T = (bits(1) << MODULE_ID) | OBJECT_T;
-
-	// Filesystem.
-	const bits FILESYSTEM_FILE_T = (bits(1) << FILESYSTEM_FILE_ID) | OBJECT_T;
-	const bits FILESYSTEM_FILE_DATA_T = (bits(1) << FILESYSTEM_FILE_DATA_ID) | DATA_T;
-
-	const bits FONT_GLYPH_DATA_T = (bits(1) << FONT_GLYPH_DATA_ID) | DATA_T;
-	const bits FONT_RASTERIZER_T = (bits(1) << FONT_RASTERIZER_ID) | OBJECT_T;
-
-	// Graphics.
-	const bits GRAPHICS_DRAWABLE_T = (bits(1) << GRAPHICS_DRAWABLE_ID) | OBJECT_T;
-	const bits GRAPHICS_DRAWQABLE_T = (bits(1) << GRAPHICS_DRAWQABLE_ID) | GRAPHICS_DRAWABLE_T;
-	const bits GRAPHICS_IMAGE_T = (bits(1) << GRAPHICS_IMAGE_ID) | GRAPHICS_DRAWQABLE_T;
-	const bits GRAPHICS_QUAD_T = (bits(1) << GRAPHICS_QUAD_ID) | OBJECT_T;
-	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;
-
-	// Image.
-	const bits IMAGE_IMAGE_DATA_T = (bits(1) << IMAGE_IMAGE_DATA_ID) | DATA_T;
-	const bits IMAGE_ENCODED_IMAGE_DATA_T = (bits(1) << IMAGE_ENCODED_IMAGE_DATA_ID) | DATA_T;
-
-	// Audio.
-	const bits AUDIO_SOURCE_T = (bits(1) << AUDIO_SOURCE_ID) | OBJECT_T;
-
-	// Sound.
-	const bits SOUND_SOUND_DATA_T = (bits(1) << SOUND_SOUND_DATA_ID) | DATA_T;
-	const bits SOUND_DECODER_T = bits(1) << SOUND_DECODER_ID;
-
-	// Physics.
-	const bits PHYSICS_WORLD_T = (bits(1) << PHYSICS_WORLD_ID) | OBJECT_T;
-	const bits PHYSICS_CONTACT_T = (bits(1) << PHYSICS_CONTACT_ID) | OBJECT_T;
-	const bits PHYSICS_BODY_T = (bits(1) << PHYSICS_BODY_ID) | OBJECT_T;
-	const bits PHYSICS_FIXTURE_T = (bits(1) << PHYSICS_FIXTURE_ID) | OBJECT_T;
-	const bits PHYSICS_SHAPE_T = (bits(1) << PHYSICS_SHAPE_ID) | OBJECT_T;
-	const bits PHYSICS_CIRCLE_SHAPE_T = (bits(1) << PHYSICS_CIRCLE_SHAPE_ID) | PHYSICS_SHAPE_T;
-	const bits PHYSICS_POLYGON_SHAPE_T = (bits(1) << PHYSICS_POLYGON_SHAPE_ID) | PHYSICS_SHAPE_T;
-	const bits PHYSICS_EDGE_SHAPE_T = (bits(1) << PHYSICS_EDGE_SHAPE_ID) | PHYSICS_SHAPE_T;
-	const bits PHYSICS_CHAIN_SHAPE_T = (bits(1) << PHYSICS_CHAIN_SHAPE_ID) | PHYSICS_SHAPE_T;
-	const bits PHYSICS_JOINT_T = (bits(1) << PHYSICS_JOINT_ID) | OBJECT_T;
-	const bits PHYSICS_MOUSE_JOINT_T = (bits(1) << PHYSICS_MOUSE_JOINT_ID) | PHYSICS_JOINT_T;
-	const bits PHYSICS_DISTANCE_JOINT_T = (bits(1) << PHYSICS_DISTANCE_JOINT_ID) | PHYSICS_JOINT_T;
-	const bits PHYSICS_PRISMATIC_JOINT_T = (bits(1) << PHYSICS_PRISMATIC_JOINT_ID) | PHYSICS_JOINT_T;
-	const bits PHYSICS_REVOLUTE_JOINT_T = (bits(1) << PHYSICS_REVOLUTE_JOINT_ID) | PHYSICS_JOINT_T;
-	const bits PHYSICS_PULLEY_JOINT_T = (bits(1) << PHYSICS_PULLEY_JOINT_ID) | PHYSICS_JOINT_T;
-	const bits PHYSICS_GEAR_JOINT_T = (bits(1) << PHYSICS_GEAR_JOINT_ID) | PHYSICS_JOINT_T;
-	const bits PHYSICS_FRICTION_JOINT_T = (bits(1) << PHYSICS_FRICTION_JOINT_ID) | PHYSICS_JOINT_T;
-	const bits PHYSICS_WELD_JOINT_T = (bits(1) << PHYSICS_WELD_JOINT_ID) | PHYSICS_JOINT_T;
-	const bits PHYSICS_ROPE_JOINT_T = (bits(1) << PHYSICS_ROPE_JOINT_ID) | PHYSICS_JOINT_T;
-	const bits PHYSICS_WHEEL_JOINT_T = (bits(1) << PHYSICS_WHEEL_JOINT_ID) | PHYSICS_JOINT_T;
-
-	// Thread.
-	const bits THREAD_THREAD_T = (bits(1) << THREAD_THREAD_ID) | OBJECT_T;
-
-	// Modules.
-	const bits MODULE_FILESYSTEM_T = (bits(1) << MODULE_FILESYSTEM_ID) | MODULE_T;
-	const bits MODULE_IMAGE_T = (bits(1) << MODULE_IMAGE_ID) | MODULE_T;
-	const bits MODULE_SOUND_T = (bits(1) << MODULE_SOUND_ID) | MODULE_T;
-
-	bool getType(const char * in, Type & out);
-	bool getType(Type in, const char *& out);
-
-} // love
-
-#endif // LOVE_TYPES_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_TYPES_H
+#define LOVE_TYPES_H
+
+// STD
+#include <bitset>
+
+namespace love
+{
+
+enum Type
+{
+	INVALID_ID = 0,
+	// Cross-module types.
+	OBJECT_ID,
+	DATA_ID,
+	MODULE_ID,
+
+	// Filesystem.
+	FILESYSTEM_FILE_ID,
+	FILESYSTEM_FILE_DATA_ID,
+
+	// Font
+	FONT_GLYPH_DATA_ID,
+	FONT_RASTERIZER_ID,
+
+	// Graphics
+	GRAPHICS_DRAWABLE_ID,
+	GRAPHICS_DRAWQABLE_ID,
+	GRAPHICS_IMAGE_ID,
+	GRAPHICS_QUAD_ID,
+	GRAPHICS_FONT_ID,
+	GRAPHICS_PARTICLE_SYSTEM_ID,
+	GRAPHICS_SPRITE_BATCH_ID,
+	GRAPHICS_CANVAS_ID,
+	GRAPHICS_PIXELEFFECT_ID,
+
+	// Image
+	IMAGE_IMAGE_DATA_ID,
+	IMAGE_ENCODED_IMAGE_DATA_ID,
+
+	// Audio
+	AUDIO_SOURCE_ID,
+
+	// Sound
+	SOUND_SOUND_DATA_ID,
+	SOUND_DECODER_ID,
+
+	// Physics
+	PHYSICS_WORLD_ID,
+	PHYSICS_CONTACT_ID,
+	PHYSICS_BODY_ID,
+	PHYSICS_FIXTURE_ID,
+	PHYSICS_SHAPE_ID,
+	PHYSICS_CIRCLE_SHAPE_ID,
+	PHYSICS_POLYGON_SHAPE_ID,
+	PHYSICS_EDGE_SHAPE_ID,
+	PHYSICS_CHAIN_SHAPE_ID,
+	PHYSICS_JOINT_ID,
+	PHYSICS_MOUSE_JOINT_ID,
+	PHYSICS_DISTANCE_JOINT_ID,
+	PHYSICS_PRISMATIC_JOINT_ID,
+	PHYSICS_REVOLUTE_JOINT_ID,
+	PHYSICS_PULLEY_JOINT_ID,
+	PHYSICS_GEAR_JOINT_ID,
+	PHYSICS_FRICTION_JOINT_ID,
+	PHYSICS_WELD_JOINT_ID,
+	PHYSICS_ROPE_JOINT_ID,
+	PHYSICS_WHEEL_JOINT_ID,
+
+	// Thread
+	THREAD_THREAD_ID,
+
+	// The modules themselves. Only add abstracted modules here.
+	MODULE_FILESYSTEM_ID,
+	MODULE_IMAGE_ID,
+	MODULE_SOUND_ID,
+
+	// Count the number of bits needed.
+	TYPE_MAX_ENUM
+};
+
+typedef std::bitset<TYPE_MAX_ENUM> bits;
+
+const bits INVALID_T = bits(1) << INVALID_ID;
+
+const bits OBJECT_T = bits(1) << OBJECT_ID;
+const bits DATA_T = (bits(1) << DATA_ID) | OBJECT_T;
+const bits MODULE_T = (bits(1) << MODULE_ID) | OBJECT_T;
+
+// Filesystem.
+const bits FILESYSTEM_FILE_T = (bits(1) << FILESYSTEM_FILE_ID) | OBJECT_T;
+const bits FILESYSTEM_FILE_DATA_T = (bits(1) << FILESYSTEM_FILE_DATA_ID) | DATA_T;
+
+const bits FONT_GLYPH_DATA_T = (bits(1) << FONT_GLYPH_DATA_ID) | DATA_T;
+const bits FONT_RASTERIZER_T = (bits(1) << FONT_RASTERIZER_ID) | OBJECT_T;
+
+// Graphics.
+const bits GRAPHICS_DRAWABLE_T = (bits(1) << GRAPHICS_DRAWABLE_ID) | OBJECT_T;
+const bits GRAPHICS_DRAWQABLE_T = (bits(1) << GRAPHICS_DRAWQABLE_ID) | GRAPHICS_DRAWABLE_T;
+const bits GRAPHICS_IMAGE_T = (bits(1) << GRAPHICS_IMAGE_ID) | GRAPHICS_DRAWQABLE_T;
+const bits GRAPHICS_QUAD_T = (bits(1) << GRAPHICS_QUAD_ID) | OBJECT_T;
+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;
+
+// Image.
+const bits IMAGE_IMAGE_DATA_T = (bits(1) << IMAGE_IMAGE_DATA_ID) | DATA_T;
+const bits IMAGE_ENCODED_IMAGE_DATA_T = (bits(1) << IMAGE_ENCODED_IMAGE_DATA_ID) | DATA_T;
+
+// Audio.
+const bits AUDIO_SOURCE_T = (bits(1) << AUDIO_SOURCE_ID) | OBJECT_T;
+
+// Sound.
+const bits SOUND_SOUND_DATA_T = (bits(1) << SOUND_SOUND_DATA_ID) | DATA_T;
+const bits SOUND_DECODER_T = bits(1) << SOUND_DECODER_ID;
+
+// Physics.
+const bits PHYSICS_WORLD_T = (bits(1) << PHYSICS_WORLD_ID) | OBJECT_T;
+const bits PHYSICS_CONTACT_T = (bits(1) << PHYSICS_CONTACT_ID) | OBJECT_T;
+const bits PHYSICS_BODY_T = (bits(1) << PHYSICS_BODY_ID) | OBJECT_T;
+const bits PHYSICS_FIXTURE_T = (bits(1) << PHYSICS_FIXTURE_ID) | OBJECT_T;
+const bits PHYSICS_SHAPE_T = (bits(1) << PHYSICS_SHAPE_ID) | OBJECT_T;
+const bits PHYSICS_CIRCLE_SHAPE_T = (bits(1) << PHYSICS_CIRCLE_SHAPE_ID) | PHYSICS_SHAPE_T;
+const bits PHYSICS_POLYGON_SHAPE_T = (bits(1) << PHYSICS_POLYGON_SHAPE_ID) | PHYSICS_SHAPE_T;
+const bits PHYSICS_EDGE_SHAPE_T = (bits(1) << PHYSICS_EDGE_SHAPE_ID) | PHYSICS_SHAPE_T;
+const bits PHYSICS_CHAIN_SHAPE_T = (bits(1) << PHYSICS_CHAIN_SHAPE_ID) | PHYSICS_SHAPE_T;
+const bits PHYSICS_JOINT_T = (bits(1) << PHYSICS_JOINT_ID) | OBJECT_T;
+const bits PHYSICS_MOUSE_JOINT_T = (bits(1) << PHYSICS_MOUSE_JOINT_ID) | PHYSICS_JOINT_T;
+const bits PHYSICS_DISTANCE_JOINT_T = (bits(1) << PHYSICS_DISTANCE_JOINT_ID) | PHYSICS_JOINT_T;
+const bits PHYSICS_PRISMATIC_JOINT_T = (bits(1) << PHYSICS_PRISMATIC_JOINT_ID) | PHYSICS_JOINT_T;
+const bits PHYSICS_REVOLUTE_JOINT_T = (bits(1) << PHYSICS_REVOLUTE_JOINT_ID) | PHYSICS_JOINT_T;
+const bits PHYSICS_PULLEY_JOINT_T = (bits(1) << PHYSICS_PULLEY_JOINT_ID) | PHYSICS_JOINT_T;
+const bits PHYSICS_GEAR_JOINT_T = (bits(1) << PHYSICS_GEAR_JOINT_ID) | PHYSICS_JOINT_T;
+const bits PHYSICS_FRICTION_JOINT_T = (bits(1) << PHYSICS_FRICTION_JOINT_ID) | PHYSICS_JOINT_T;
+const bits PHYSICS_WELD_JOINT_T = (bits(1) << PHYSICS_WELD_JOINT_ID) | PHYSICS_JOINT_T;
+const bits PHYSICS_ROPE_JOINT_T = (bits(1) << PHYSICS_ROPE_JOINT_ID) | PHYSICS_JOINT_T;
+const bits PHYSICS_WHEEL_JOINT_T = (bits(1) << PHYSICS_WHEEL_JOINT_ID) | PHYSICS_JOINT_T;
+
+// Thread.
+const bits THREAD_THREAD_T = (bits(1) << THREAD_THREAD_ID) | OBJECT_T;
+
+// Modules.
+const bits MODULE_FILESYSTEM_T = (bits(1) << MODULE_FILESYSTEM_ID) | MODULE_T;
+const bits MODULE_IMAGE_T = (bits(1) << MODULE_IMAGE_ID) | MODULE_T;
+const bits MODULE_SOUND_T = (bits(1) << MODULE_SOUND_ID) | MODULE_T;
+
+bool getType(const char *in, Type &out);
+bool getType(Type in, const char  *&out);
+
+} // love
+
+#endif // LOVE_TYPES_H

+ 61 - 60
src/common/utf8.cpp

@@ -1,60 +1,61 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "utf8.h"
-
-#ifdef LOVE_WINDOWS
-
-namespace love
-{
-	std::string to_utf8(LPCWSTR wstr)
-	{
-		size_t wide_len = wcslen(wstr)+1;
-
-		// Get size in UTF-8.
-		int utf8_size = WideCharToMultiByte(CP_UTF8, 0, wstr, wide_len, 0, 0, 0, 0);
-
-		char * utf8_str = new char[utf8_size];
-
-		// Convert to UTF-8.
-		int ok = WideCharToMultiByte(CP_UTF8, 0, wstr, wide_len, utf8_str, utf8_size, 0, 0);
-
-		std::string ret;
-		if (ok)
-			ret = utf8_str;
-
-		delete utf8_str;
-		return ret;
-	}
-
-	void replace_char(std::string & str, char find, char replace)
-	{
-		int length = str.length();
-
-		for (int i = 0; i<length; i++)
-		{
-			if (str[i] == find)
-				str[i] = replace;
-		}
-	}
-
-} // love
-
-#endif // LOVE_WINDOWS
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "utf8.h"
+
+#ifdef LOVE_WINDOWS
+
+namespace love
+{
+
+std::string to_utf8(LPCWSTR wstr)
+{
+	size_t wide_len = wcslen(wstr)+1;
+
+	// Get size in UTF-8.
+	int utf8_size = WideCharToMultiByte(CP_UTF8, 0, wstr, wide_len, 0, 0, 0, 0);
+
+	char *utf8_str = new char[utf8_size];
+
+	// Convert to UTF-8.
+	int ok = WideCharToMultiByte(CP_UTF8, 0, wstr, wide_len, utf8_str, utf8_size, 0, 0);
+
+	std::string ret;
+	if (ok)
+		ret = utf8_str;
+
+	delete utf8_str;
+	return ret;
+}
+
+void replace_char(std::string &str, char find, char replace)
+{
+	int length = str.length();
+
+	for (int i = 0; i<length; i++)
+	{
+		if (str[i] == find)
+			str[i] = replace;
+	}
+}
+
+} // love
+
+#endif // LOVE_WINDOWS

+ 47 - 46
src/common/utf8.h

@@ -1,47 +1,48 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "config.h"
-
-#ifdef LOVE_WINDOWS
-
-#include <string>
-#include <windows.h>
-
-namespace love
-{
-	/**
-	* Convert the wide string to a UTF-8 encoded string.
-	* @param wstr The wide-char string.
-	* @return A UTF-8 string.
-	**/
-	std::string to_utf8(LPCWSTR wstr);
-
-	/**
-	* Replace all occurences of 'find' with 'replace' in a string.
-	* @param str The string to modify.
-	* @param find The character to match.
-	* @param replace The character to replace matches.
-	**/
-	void replace_char(std::string & str, char find, char replace);
-
-} // love
-
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "config.h"
+
+#ifdef LOVE_WINDOWS
+
+#include <string>
+#include <windows.h>
+
+namespace love
+{
+
+/**
+ * Convert the wide string to a UTF-8 encoded string.
+ * @param wstr The wide-char string.
+ * @return A UTF-8 string.
+ **/
+std::string to_utf8(LPCWSTR wstr);
+
+/**
+ * Replace all occurences of 'find' with 'replace' in a string.
+ * @param str The string to modify.
+ * @param find The character to match.
+ * @param replace The character to replace matches.
+ **/
+void replace_char(std::string &str, char find, char replace);
+
+} // love
+
 #endif // LOVE_WINDOWS

+ 37 - 36
src/common/version.h

@@ -1,36 +1,37 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_VERSION_H
-#define LOVE_VERSION_H
-
-namespace love
-{
-	// Version stuff.
-	const int VERSION_MAJOR = 0;
-	const int VERSION_MINOR = 8;
-	const int VERSION_REV = 0;
-	const char * VERSION = "0.8.0";
-	const char * VERSION_COMPATIBILITY[] =  { VERSION, 0 };
-	const char * VERSION_CODENAME = "Rubber Piggy";
-
-} // love
-
-#endif // LOVE_VERSION_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_VERSION_H
+#define LOVE_VERSION_H
+
+namespace love
+{
+
+// Version stuff.
+const int VERSION_MAJOR = 0;
+const int VERSION_MINOR = 8;
+const int VERSION_REV = 0;
+const char *VERSION = "0.8.0";
+const char *VERSION_COMPATIBILITY[] =  { VERSION, 0 };
+const char *VERSION_CODENAME = "Rubber Piggy";
+
+} // love
+
+#endif // LOVE_VERSION_H

+ 58 - 56
src/common/wrap_Data.cpp

@@ -1,56 +1,58 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "wrap_Data.h"
-
-namespace love
-{
-	Data * luax_checkdata(lua_State * L, int idx)
-	{
-		return luax_checktype<Data>(L, idx, "Data", DATA_T);
-	}
-
-	int w_Data_getPointer(lua_State * L)
-	{
-		Data * t = luax_checkdata(L, 1);
-		lua_pushlightuserdata(L, t->getData());
-		return 1;
-	}
-
-	int w_Data_getSize(lua_State * L)
-	{
-		Data * t = luax_checkdata(L, 1);
-		lua_pushinteger(L, t->getSize());
-		return 1;
-	}
-
-	const luaL_Reg w_Data_functions[] = {
-		{ "getPointer", w_Data_getPointer },
-		{ "getSize", w_Data_getSize },
-		{ 0, 0 }
-	};
-
-	int w_Data_open(lua_State * L)
-	{
-		luax_register_type(L, "Data", w_Data_functions);
-		return 0;
-	}
-
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "wrap_Data.h"
+
+namespace love
+{
+
+Data *luax_checkdata(lua_State *L, int idx)
+{
+	return luax_checktype<Data>(L, idx, "Data", DATA_T);
+}
+
+int w_Data_getPointer(lua_State *L)
+{
+	Data *t = luax_checkdata(L, 1);
+	lua_pushlightuserdata(L, t->getData());
+	return 1;
+}
+
+int w_Data_getSize(lua_State *L)
+{
+	Data *t = luax_checkdata(L, 1);
+	lua_pushinteger(L, t->getSize());
+	return 1;
+}
+
+const luaL_Reg w_Data_functions[] =
+{
+	{ "getPointer", w_Data_getPointer },
+	{ "getSize", w_Data_getSize },
+	{ 0, 0 }
+};
+
+int w_Data_open(lua_State *L)
+{
+	luax_register_type(L, "Data", w_Data_functions);
+	return 0;
+}
+
+} // love

+ 38 - 37
src/common/wrap_Data.h

@@ -1,37 +1,38 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_WRAP_DATA_H
-#define LOVE_WRAP_DATA_H
-
-// LOVE
-#include "runtime.h"
-#include "Data.h"
-
-namespace love
-{
-	Data * luax_checkdata(lua_State * L, int idx);
-	int w_Data_getPointer(lua_State * L);
-	int w_Data_getSize(lua_State * L);
-	int w_Data_open(lua_State * L);
-
-} // love
-
-#endif // LOVE_WRAP_DATA_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_WRAP_DATA_H
+#define LOVE_WRAP_DATA_H
+
+// LOVE
+#include "runtime.h"
+#include "Data.h"
+
+namespace love
+{
+
+Data *luax_checkdata(lua_State *L, int idx);
+int w_Data_getPointer(lua_State *L);
+int w_Data_getSize(lua_State *L);
+int w_Data_open(lua_State *L);
+
+} // love
+
+#endif // LOVE_WRAP_DATA_H

+ 34 - 34
src/launcher.cpp

@@ -1,34 +1,34 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include <common/config.h>
-#include <SDL.h>
-
-extern "C"
-{
-	extern int lovemain(int argc, char **argv);
-}
-
-#ifdef LOVE_BUILD_EXE
-int main(int argc, char **argv)
-{
-	return lovemain(argc, argv);
-}
-#endif // LOVE_BUILD_EXE
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "common/config.h"
+#include <SDL.h>
+
+extern "C"
+{
+	extern int lovemain(int argc, char **argv);
+}
+
+#ifdef LOVE_BUILD_EXE
+int main(int argc, char **argv)
+{
+	return lovemain(argc, argv);
+}
+#endif // LOVE_BUILD_EXE

+ 363 - 363
src/love.cpp

@@ -1,363 +1,363 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-// LOVE
-#include <common/config.h>
-#include <common/version.h>
-#include <common/runtime.h>
-
-#ifdef LOVE_WINDOWS
-#include <windows.h>
-#endif // LOVE_WINDOWS
-
-#ifdef LOVE_LEGENDARY_CONSOLE_IO_HACK
-#include <fcntl.h>
-#include <io.h>
-#include <iostream>
-#include <fstream>
-#endif // LOVE_LEGENDARY_CONSOLE_IO_HACK
-
-#ifdef LOVE_BUILD_EXE
-
-// SDL
-#include <SDL.h>
-
-// Libraries.
-#include "libraries/luasocket/luasocket.h"
-
-// Scripts
-#include "scripts/boot.lua.h"
-
-#endif // LOVE_BUILD_EXE
-
-#ifdef LOVE_BUILD_STANDALONE
-
-// All modules define a c-accessible luaopen
-// so let's make use of those, instead
-// of addressing implementations directly.
-extern "C"
-{
-	extern int luaopen_love_audio(lua_State*);
-	extern int luaopen_love_event(lua_State*);
-	extern int luaopen_love_filesystem(lua_State*);
-	extern int luaopen_love_font(lua_State*);
-	extern int luaopen_love_graphics(lua_State*);
-	extern int luaopen_love_image(lua_State*);
-	extern int luaopen_love_joystick(lua_State*);
-	extern int luaopen_love_keyboard(lua_State*);
-	extern int luaopen_love_mouse(lua_State*);
-	extern int luaopen_love_physics(lua_State*);
-	extern int luaopen_love_sound(lua_State*);
-	extern int luaopen_love_timer(lua_State*);
-	extern int luaopen_love_thread(lua_State*);
-	extern int luaopen_love_boot(lua_State*);
-}
-
-static const luaL_Reg modules[] = {
-	{ "love.audio", luaopen_love_audio },
-	{ "love.event", luaopen_love_event },
-	{ "love.filesystem", luaopen_love_filesystem },
-	{ "love.font", luaopen_love_font },
-	{ "love.graphics", luaopen_love_graphics },
-	{ "love.image", luaopen_love_image },
-	{ "love.joystick", luaopen_love_joystick },
-	{ "love.keyboard", luaopen_love_keyboard },
-	{ "love.mouse", luaopen_love_mouse },
-	{ "love.physics", luaopen_love_physics },
-	{ "love.sound", luaopen_love_sound },
-	{ "love.timer", luaopen_love_timer },
-	{ "love.thread", luaopen_love_thread },
-	{ "love.boot", luaopen_love_boot },
-	{ 0, 0 }
-};
-
-#endif // LOVE_BUILD_STANDALONE
-
-#ifdef LOVE_LEGENDARY_CONSOLE_IO_HACK
-int w__openConsole(lua_State * L);
-#endif // LOVE_LEGENDARY_CONSOLE_IO_HACK
-
-extern "C" LOVE_EXPORT int luaopen_love(lua_State * L)
-{
-	love::luax_insistglobal(L, "love");
-
-	// Set version information.
-	lua_pushstring(L, love::VERSION);
-	lua_setfield(L, -2, "_version");
-
-	lua_pushnumber(L, love::VERSION_MAJOR);
-	lua_setfield(L, -2, "_version_major");
-	lua_pushnumber(L, love::VERSION_MINOR);
-	lua_setfield(L, -2, "_version_minor");
-	lua_pushnumber(L, love::VERSION_REV);
-	lua_setfield(L, -2, "_version_revision");
-
-	lua_pushstring(L, love::VERSION_CODENAME);
-	lua_setfield(L, -2, "_version_codename");
-
-#ifdef LOVE_LEGENDARY_CONSOLE_IO_HACK
-	lua_pushcfunction(L, w__openConsole);
-	lua_setfield(L, -2, "_openConsole");
-#endif // LOVE_LEGENDARY_CONSOLE_IO_HACK
-
-	lua_newtable(L);
-
-	for (int i = 0; love::VERSION_COMPATIBILITY[i] != 0; ++i)
-	{
-		lua_pushstring(L, love::VERSION_COMPATIBILITY[i]);
-		lua_rawseti(L, -2, i+1);
-	}
-
-	lua_setfield(L, -2, "_version_compat");
-
-#ifdef LOVE_WINDOWS
-	lua_pushstring(L, "Windows");
-#elif defined(LOVE_MACOSX)
-	lua_pushstring(L, "OS X");
-#elif defined(LOVE_LINUX)
-	lua_pushstring(L, "Linux");
-#else
-	lua_pushstring(L, "Unknown");
-#endif
-	lua_setfield(L, -2, "_os");
-
-#ifdef LOVE_BUILD_STANDALONE
-
-	// Preload module loaders.
-	for (int i = 0; modules[i].name != 0; i++)
-	{
-		love::luax_preload(L, modules[i].func, modules[i].name);
-	}
-
-	love::luasocket::__open(L);
-
-#endif // LOVE_BUILD_STANDALONE
-
-	return 1;
-}
-
-#ifdef LOVE_LEGENDARY_UTF8_ARGV_HACK
-
-void get_utf8_arguments(int & argc, char **& argv)
-{
-	LPWSTR cmd = GetCommandLineW();
-
-	if (!cmd)
-		return;
-
-	LPWSTR * argv_w = CommandLineToArgvW(cmd, &argc);
-
-	argv = new char*[argc];
-
-	for (int i = 0; i<argc; ++i)
-	{
-		// Size of wide char buffer (plus one for trailing '\0').
-		size_t wide_len = wcslen(argv_w[i])+1;
-
-		// Get size in UTF-8.
-		int utf8_size = WideCharToMultiByte(CP_UTF8, 0, argv_w[i], wide_len, argv[i], 0, 0, 0);
-
-		argv[i] = new char[utf8_size];
-
-		// Convert to UTF-8.
-		int ok = WideCharToMultiByte(CP_UTF8, 0, argv_w[i], wide_len, argv[i], utf8_size, 0, 0);
-
-		int len = strlen(argv[i]);
-
-		if (!ok)
-			printf("Warning: could not convert to UTF8.\n");
-	}
-
-	LocalFree(argv_w);
-}
-
-#endif // LOVE_LEGENDARY_UTF8_ARGV_HACK
-
-#ifdef LOVE_LEGENDARY_CONSOLE_IO_HACK
-
-int w__openConsole(lua_State * L)
-{
-	static bool is_open = false;
-	if (is_open)
-		return 0;
-	is_open = true;
-
-	if (GetConsoleWindow() != NULL || AllocConsole() == 0)
-		return 0;
-
-	const int MAX_CONSOLE_LINES = 5000;
-	CONSOLE_SCREEN_BUFFER_INFO console_info;
-
-	// Set size.
-	GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &console_info);
-	console_info.dwSize.Y = MAX_CONSOLE_LINES;
-	SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), console_info.dwSize);
-
-	SetConsoleTitle(TEXT("LOVE Console"));
-
-	FILE * fp;
-
-	// Redirect stdout.
-	fp = freopen("CONOUT$", "w", stdout);
-	if (L && fp == NULL)
-		luaL_error(L, "Console redirection of stdout failed.");
-
-	// Redirect stdin.
-	fp = freopen("CONIN$", "r", stdin);
-	if (L && fp == NULL)
-		luaL_error(L, "Console redirection of stdin failed.");
-
-	// Redirect stderr.
-	fp = freopen("CONOUT$", "w", stderr);
-	if (L && fp == NULL)
-		luaL_error(L, "Console redirection of stderr failed.");
-
-	return 0;
-}
-
-#endif // LOVE_LEGENDARY_CONSOLE_IO_HACK
-
-#ifdef LOVE_LEGENDARY_LIBSTDCXX_HACK
-
-// Workarounds for symbols that are missing from Leopard stdlibc++.dylib.
-// http://stackoverflow.com/questions/3484043/os-x-program-runs-on-dev-machine-crashing-horribly-on-others
-_GLIBCXX_BEGIN_NAMESPACE(std)
-// From ostream_insert.h
-template ostream& __ostream_insert(ostream&, const char*, streamsize);
-
-#ifdef _GLIBCXX_USE_WCHAR_T
-template wostream& __ostream_insert(wostream&, const wchar_t*, streamsize);
-#endif
-
-// From ostream.tcc
-template ostream& ostream::_M_insert(long);
-template ostream& ostream::_M_insert(unsigned long);
-template ostream& ostream::_M_insert(bool);
-#ifdef _GLIBCXX_USE_LONG_LONG
-template ostream& ostream::_M_insert(long long);
-template ostream& ostream::_M_insert(unsigned long long);
-#endif
-template ostream& ostream::_M_insert(double);
-template ostream& ostream::_M_insert(long double);
-template ostream& ostream::_M_insert(const void*);
-
-#ifdef _GLIBCXX_USE_WCHAR_T
-template wostream& wostream::_M_insert(long);
-template wostream& wostream::_M_insert(unsigned long);
-template wostream& wostream::_M_insert(bool);
-#ifdef _GLIBCXX_USE_LONG_LONG
-template wostream& wostream::_M_insert(long long);
-template wostream& wostream::_M_insert(unsigned long long);
-#endif
-template wostream& wostream::_M_insert(double);
-template wostream& wostream::_M_insert(long double);
-template wostream& wostream::_M_insert(const void*);
-#endif
-
-_GLIBCXX_END_NAMESPACE
-
-#endif // LOVE_LEGENDARY_LIBSTDCXX_HACK
-
-extern "C" int luaopen_love_boot(lua_State *L)
-{
-	if (luaL_loadbuffer(L, (const char *)love::boot_lua, sizeof(love::boot_lua), "boot.lua") == 0)
-	lua_call(L, 0, 1);
-	return 1;
-}
-
-extern "C" LOVE_EXPORT int lovemain(int argc, char ** argv)
-{
-#ifdef LOVE_LEGENDARY_UTF8_ARGV_HACK
-	int hack_argc = 0;
-	char ** hack_argv = 0;
-	get_utf8_arguments(hack_argc, hack_argv);
-	argc = hack_argc;
-	argv = hack_argv;
-#endif // LOVE_LEGENDARY_UTF8_ARGV_HACK
-
-	// Oh, you just want the version? Okay!
-	if (argc > 1 && strcmp(argv[1],"--version") == 0)
-	{
-		printf("LOVE %s (%s)\n", love::VERSION, love::VERSION_CODENAME);
-		return 0;
-	}
-
-	// Create the virtual machine.
-	lua_State * L = lua_open();
-	luaL_openlibs(L);
-
-	love::luax_preload(L, luaopen_love, "love");
-
-	luaopen_love(L);
-
-	// Add command line arguments to global arg (like stand-alone Lua).
-	{
-		lua_newtable(L);
-
-		if (argc > 0)
-		{
-			lua_pushstring(L, argv[0]);
-			lua_rawseti(L, -2, -2);
-		}
-
-		lua_pushstring(L, "embedded boot.lua");
-		lua_rawseti(L, -2, -1);
-
-		for (int i = 1; i<argc; i++)
-		{
-			lua_pushstring(L, argv[i]);
-			lua_rawseti(L, -2, i);
-		}
-
-		lua_setglobal(L, "arg");
-	}
-
-	// Add love.__exe = true.
-	// This indicates that we're running the
-	// standalone version of love, and not the
-	// DLL version.
-	{
-		lua_getglobal(L, "love");
-		lua_pushboolean(L, 1);
-		lua_setfield(L, -2, "_exe");
-		lua_pop(L, 1);
-	}
-
-	// Boot
-	luaopen_love_boot(L);
-	lua_call(L, 0, 1);
-
-	int retval = 0;
-	if (lua_isnumber(L, 1))
-		retval = (int) lua_tonumber(L, 1);
-
-	lua_close(L);
-
-#ifdef LOVE_LEGENDARY_UTF8_ARGV_HACK
-	if (hack_argv)
-	{
-		for (int i = 0; i<hack_argc; ++i)
-			delete [] hack_argv[i];
-		delete [] hack_argv;
-	}
-#endif // LOVE_LEGENDARY_UTF8_ARGV_HACK
-	return retval;
-}
-
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+// LOVE
+#include "common/config.h"
+#include "common/version.h"
+#include "common/runtime.h"
+
+#ifdef LOVE_WINDOWS
+#include <windows.h>
+#endif // LOVE_WINDOWS
+
+#ifdef LOVE_LEGENDARY_CONSOLE_IO_HACK
+#include <fcntl.h>
+#include <io.h>
+#include <iostream>
+#include <fstream>
+#endif // LOVE_LEGENDARY_CONSOLE_IO_HACK
+
+#ifdef LOVE_BUILD_EXE
+
+// SDL
+#include <SDL.h>
+
+// Libraries.
+#include "libraries/luasocket/luasocket.h"
+
+// Scripts
+#include "scripts/boot.lua.h"
+
+#endif // LOVE_BUILD_EXE
+
+#ifdef LOVE_BUILD_STANDALONE
+
+// All modules define a c-accessible luaopen
+// so let's make use of those, instead
+// of addressing implementations directly.
+extern "C"
+{
+	extern int luaopen_love_audio(lua_State*);
+	extern int luaopen_love_event(lua_State*);
+	extern int luaopen_love_filesystem(lua_State*);
+	extern int luaopen_love_font(lua_State*);
+	extern int luaopen_love_graphics(lua_State*);
+	extern int luaopen_love_image(lua_State*);
+	extern int luaopen_love_joystick(lua_State*);
+	extern int luaopen_love_keyboard(lua_State*);
+	extern int luaopen_love_mouse(lua_State*);
+	extern int luaopen_love_physics(lua_State*);
+	extern int luaopen_love_sound(lua_State*);
+	extern int luaopen_love_timer(lua_State*);
+	extern int luaopen_love_thread(lua_State*);
+	extern int luaopen_love_boot(lua_State*);
+}
+
+static const luaL_Reg modules[] = {
+	{ "love.audio", luaopen_love_audio },
+	{ "love.event", luaopen_love_event },
+	{ "love.filesystem", luaopen_love_filesystem },
+	{ "love.font", luaopen_love_font },
+	{ "love.graphics", luaopen_love_graphics },
+	{ "love.image", luaopen_love_image },
+	{ "love.joystick", luaopen_love_joystick },
+	{ "love.keyboard", luaopen_love_keyboard },
+	{ "love.mouse", luaopen_love_mouse },
+	{ "love.physics", luaopen_love_physics },
+	{ "love.sound", luaopen_love_sound },
+	{ "love.timer", luaopen_love_timer },
+	{ "love.thread", luaopen_love_thread },
+	{ "love.boot", luaopen_love_boot },
+	{ 0, 0 }
+};
+
+#endif // LOVE_BUILD_STANDALONE
+
+#ifdef LOVE_LEGENDARY_CONSOLE_IO_HACK
+int w__openConsole(lua_State * L);
+#endif // LOVE_LEGENDARY_CONSOLE_IO_HACK
+
+extern "C" LOVE_EXPORT int luaopen_love(lua_State * L)
+{
+	love::luax_insistglobal(L, "love");
+
+	// Set version information.
+	lua_pushstring(L, love::VERSION);
+	lua_setfield(L, -2, "_version");
+
+	lua_pushnumber(L, love::VERSION_MAJOR);
+	lua_setfield(L, -2, "_version_major");
+	lua_pushnumber(L, love::VERSION_MINOR);
+	lua_setfield(L, -2, "_version_minor");
+	lua_pushnumber(L, love::VERSION_REV);
+	lua_setfield(L, -2, "_version_revision");
+
+	lua_pushstring(L, love::VERSION_CODENAME);
+	lua_setfield(L, -2, "_version_codename");
+
+#ifdef LOVE_LEGENDARY_CONSOLE_IO_HACK
+	lua_pushcfunction(L, w__openConsole);
+	lua_setfield(L, -2, "_openConsole");
+#endif // LOVE_LEGENDARY_CONSOLE_IO_HACK
+
+	lua_newtable(L);
+
+	for (int i = 0; love::VERSION_COMPATIBILITY[i] != 0; ++i)
+	{
+		lua_pushstring(L, love::VERSION_COMPATIBILITY[i]);
+		lua_rawseti(L, -2, i+1);
+	}
+
+	lua_setfield(L, -2, "_version_compat");
+
+#ifdef LOVE_WINDOWS
+	lua_pushstring(L, "Windows");
+#elif defined(LOVE_MACOSX)
+	lua_pushstring(L, "OS X");
+#elif defined(LOVE_LINUX)
+	lua_pushstring(L, "Linux");
+#else
+	lua_pushstring(L, "Unknown");
+#endif
+	lua_setfield(L, -2, "_os");
+
+#ifdef LOVE_BUILD_STANDALONE
+
+	// Preload module loaders.
+	for (int i = 0; modules[i].name != 0; i++)
+	{
+		love::luax_preload(L, modules[i].func, modules[i].name);
+	}
+
+	love::luasocket::__open(L);
+
+#endif // LOVE_BUILD_STANDALONE
+
+	return 1;
+}
+
+#ifdef LOVE_LEGENDARY_UTF8_ARGV_HACK
+
+void get_utf8_arguments(int & argc, char **& argv)
+{
+	LPWSTR cmd = GetCommandLineW();
+
+	if (!cmd)
+		return;
+
+	LPWSTR * argv_w = CommandLineToArgvW(cmd, &argc);
+
+	argv = new char*[argc];
+
+	for (int i = 0; i<argc; ++i)
+	{
+		// Size of wide char buffer (plus one for trailing '\0').
+		size_t wide_len = wcslen(argv_w[i])+1;
+
+		// Get size in UTF-8.
+		int utf8_size = WideCharToMultiByte(CP_UTF8, 0, argv_w[i], wide_len, argv[i], 0, 0, 0);
+
+		argv[i] = new char[utf8_size];
+
+		// Convert to UTF-8.
+		int ok = WideCharToMultiByte(CP_UTF8, 0, argv_w[i], wide_len, argv[i], utf8_size, 0, 0);
+
+		int len = strlen(argv[i]);
+
+		if (!ok)
+			printf("Warning: could not convert to UTF8.\n");
+	}
+
+	LocalFree(argv_w);
+}
+
+#endif // LOVE_LEGENDARY_UTF8_ARGV_HACK
+
+#ifdef LOVE_LEGENDARY_CONSOLE_IO_HACK
+
+int w__openConsole(lua_State * L)
+{
+	static bool is_open = false;
+	if (is_open)
+		return 0;
+	is_open = true;
+
+	if (GetConsoleWindow() != NULL || AllocConsole() == 0)
+		return 0;
+
+	const int MAX_CONSOLE_LINES = 5000;
+	CONSOLE_SCREEN_BUFFER_INFO console_info;
+
+	// Set size.
+	GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &console_info);
+	console_info.dwSize.Y = MAX_CONSOLE_LINES;
+	SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), console_info.dwSize);
+
+	SetConsoleTitle(TEXT("LOVE Console"));
+
+	FILE * fp;
+
+	// Redirect stdout.
+	fp = freopen("CONOUT$", "w", stdout);
+	if (L && fp == NULL)
+		luaL_error(L, "Console redirection of stdout failed.");
+
+	// Redirect stdin.
+	fp = freopen("CONIN$", "r", stdin);
+	if (L && fp == NULL)
+		luaL_error(L, "Console redirection of stdin failed.");
+
+	// Redirect stderr.
+	fp = freopen("CONOUT$", "w", stderr);
+	if (L && fp == NULL)
+		luaL_error(L, "Console redirection of stderr failed.");
+
+	return 0;
+}
+
+#endif // LOVE_LEGENDARY_CONSOLE_IO_HACK
+
+#ifdef LOVE_LEGENDARY_LIBSTDCXX_HACK
+
+// Workarounds for symbols that are missing from Leopard stdlibc++.dylib.
+// http://stackoverflow.com/questions/3484043/os-x-program-runs-on-dev-machine-crashing-horribly-on-others
+_GLIBCXX_BEGIN_NAMESPACE(std)
+// From ostream_insert.h
+template ostream& __ostream_insert(ostream&, const char*, streamsize);
+
+#ifdef _GLIBCXX_USE_WCHAR_T
+template wostream& __ostream_insert(wostream&, const wchar_t*, streamsize);
+#endif
+
+// From ostream.tcc
+template ostream& ostream::_M_insert(long);
+template ostream& ostream::_M_insert(unsigned long);
+template ostream& ostream::_M_insert(bool);
+#ifdef _GLIBCXX_USE_LONG_LONG
+template ostream& ostream::_M_insert(long long);
+template ostream& ostream::_M_insert(unsigned long long);
+#endif
+template ostream& ostream::_M_insert(double);
+template ostream& ostream::_M_insert(long double);
+template ostream& ostream::_M_insert(const void*);
+
+#ifdef _GLIBCXX_USE_WCHAR_T
+template wostream& wostream::_M_insert(long);
+template wostream& wostream::_M_insert(unsigned long);
+template wostream& wostream::_M_insert(bool);
+#ifdef _GLIBCXX_USE_LONG_LONG
+template wostream& wostream::_M_insert(long long);
+template wostream& wostream::_M_insert(unsigned long long);
+#endif
+template wostream& wostream::_M_insert(double);
+template wostream& wostream::_M_insert(long double);
+template wostream& wostream::_M_insert(const void*);
+#endif
+
+_GLIBCXX_END_NAMESPACE
+
+#endif // LOVE_LEGENDARY_LIBSTDCXX_HACK
+
+extern "C" int luaopen_love_boot(lua_State *L)
+{
+	if (luaL_loadbuffer(L, (const char *)love::boot_lua, sizeof(love::boot_lua), "boot.lua") == 0)
+	lua_call(L, 0, 1);
+	return 1;
+}
+
+extern "C" LOVE_EXPORT int lovemain(int argc, char ** argv)
+{
+#ifdef LOVE_LEGENDARY_UTF8_ARGV_HACK
+	int hack_argc = 0;
+	char ** hack_argv = 0;
+	get_utf8_arguments(hack_argc, hack_argv);
+	argc = hack_argc;
+	argv = hack_argv;
+#endif // LOVE_LEGENDARY_UTF8_ARGV_HACK
+
+	// Oh, you just want the version? Okay!
+	if (argc > 1 && strcmp(argv[1],"--version") == 0)
+	{
+		printf("LOVE %s (%s)\n", love::VERSION, love::VERSION_CODENAME);
+		return 0;
+	}
+
+	// Create the virtual machine.
+	lua_State * L = lua_open();
+	luaL_openlibs(L);
+
+	love::luax_preload(L, luaopen_love, "love");
+
+	luaopen_love(L);
+
+	// Add command line arguments to global arg (like stand-alone Lua).
+	{
+		lua_newtable(L);
+
+		if (argc > 0)
+		{
+			lua_pushstring(L, argv[0]);
+			lua_rawseti(L, -2, -2);
+		}
+
+		lua_pushstring(L, "embedded boot.lua");
+		lua_rawseti(L, -2, -1);
+
+		for (int i = 1; i<argc; i++)
+		{
+			lua_pushstring(L, argv[i]);
+			lua_rawseti(L, -2, i);
+		}
+
+		lua_setglobal(L, "arg");
+	}
+
+	// Add love.__exe = true.
+	// This indicates that we're running the
+	// standalone version of love, and not the
+	// DLL version.
+	{
+		lua_getglobal(L, "love");
+		lua_pushboolean(L, 1);
+		lua_setfield(L, -2, "_exe");
+		lua_pop(L, 1);
+	}
+
+	// Boot
+	luaopen_love_boot(L);
+	lua_call(L, 0, 1);
+
+	int retval = 0;
+	if (lua_isnumber(L, 1))
+		retval = (int) lua_tonumber(L, 1);
+
+	lua_close(L);
+
+#ifdef LOVE_LEGENDARY_UTF8_ARGV_HACK
+	if (hack_argv)
+	{
+		for (int i = 0; i<hack_argc; ++i)
+			delete [] hack_argv[i];
+		delete [] hack_argv;
+	}
+#endif // LOVE_LEGENDARY_UTF8_ARGV_HACK
+	return retval;
+}
+

+ 52 - 51
src/modules/audio/Audio.cpp

@@ -1,51 +1,52 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered Audio versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any Audio distribution.
-**/
-
-#include "Audio.h"
-
-namespace love
-{
-namespace audio
-{
-	StringMap<Audio::DistanceModel, Audio::DISTANCE_MAX_ENUM>::Entry Audio::distanceModelEntries[] =
-	{
-		{"none", Audio::DISTANCE_NONE},
-		{"inverse", Audio::DISTANCE_INVERSE},
-		{"inverse clamped", Audio::DISTANCE_INVERSE_CLAMPED},
-		{"linear", Audio::DISTANCE_LINEAR},
-		{"linear clamped", Audio::DISTANCE_LINEAR_CLAMPED},
-		{"exponent", Audio::DISTANCE_EXPONENT},
-		{"exponent clamped", Audio::DISTANCE_EXPONENT_CLAMPED}
-	};
-
-	StringMap<Audio::DistanceModel, Audio::DISTANCE_MAX_ENUM> Audio::distanceModels(Audio::distanceModelEntries, sizeof(Audio::distanceModelEntries));
-
-	bool Audio::getConstant(const char * in, DistanceModel & out)
-	{
-		return distanceModels.find(in, out);
-	}
-
-	bool Audio::getConstant(DistanceModel in, const char *& out)
-	{
-		return distanceModels.find(in, out);
-	}
-
-} // audio
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered Audio versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any Audio distribution.
+ **/
+
+#include "Audio.h"
+
+namespace love
+{
+namespace audio
+{
+
+StringMap<Audio::DistanceModel, Audio::DISTANCE_MAX_ENUM>::Entry Audio::distanceModelEntries[] =
+{
+	{"none", Audio::DISTANCE_NONE},
+	{"inverse", Audio::DISTANCE_INVERSE},
+	{"inverse clamped", Audio::DISTANCE_INVERSE_CLAMPED},
+	{"linear", Audio::DISTANCE_LINEAR},
+	{"linear clamped", Audio::DISTANCE_LINEAR_CLAMPED},
+	{"exponent", Audio::DISTANCE_EXPONENT},
+	{"exponent clamped", Audio::DISTANCE_EXPONENT_CLAMPED}
+};
+
+StringMap<Audio::DistanceModel, Audio::DISTANCE_MAX_ENUM> Audio::distanceModels(Audio::distanceModelEntries, sizeof(Audio::distanceModelEntries));
+
+bool Audio::getConstant(const char *in, DistanceModel &out)
+{
+	return distanceModels.find(in, out);
+}
+
+bool Audio::getConstant(DistanceModel in, const char  *&out)
+{
+	return distanceModels.find(in, out);
+}
+
+} // audio
+} // love

+ 239 - 234
src/modules/audio/Audio.h

@@ -1,234 +1,239 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented = 0; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_AUDIO_AUDIO_H
-#define LOVE_AUDIO_AUDIO_H
-
-#include <common/Module.h>
-#include <common/StringMap.h>
-#include "Source.h"
-
-namespace love
-{
-namespace sound
-{
-	class Decoder;
-	class SoundData;
-}
-namespace audio
-{
-	/**
-	* The Audio module is responsible for playing back raw sound samples.
-	**/
-	class Audio : public Module
-	{
-	public:
-
-		/**
-		* Attenuation by distance.
-		*/
-		enum DistanceModel
-		{
-			DISTANCE_NONE = 1,
-			DISTANCE_INVERSE,
-			DISTANCE_INVERSE_CLAMPED,
-			DISTANCE_LINEAR,
-			DISTANCE_LINEAR_CLAMPED,
-			DISTANCE_EXPONENT,
-			DISTANCE_EXPONENT_CLAMPED,
-			DISTANCE_MAX_ENUM
-		};
-		
-		static bool getConstant(const char * in, DistanceModel & out);
-		static bool getConstant(DistanceModel in, const char *& out);
-
-		/**
-		* Destructor.
-		**/
-		virtual ~Audio(){};
-
-		virtual Source * newSource(love::sound::Decoder * decoder) = 0;
-		virtual Source * newSource(love::sound::SoundData * soundData) = 0;
-
-		/**
-		* Gets the current number of simultaneous playing sources.
-		* @return The current number of simultaneous playing sources.
-		**/
-		virtual int getNumSources() const = 0;
-
-		/**
-		* Gets the maximum supported number of simultaneous playing sources.
-		* @return The maximum supported number of simultaneous playing sources.
-		**/
-		virtual int getMaxSources() const = 0;
-
-		/**
-		* Play the specified Source.
-		* @param source The Source to play.
-		**/
-		virtual void play(Source * source) = 0;
-
-		/**
-		* Stops playback on the specified source.
-		* @param source The source on which to stop the playback.
-		**/
-		virtual void stop(Source * source) = 0;
-
-		/**
-		* Stops all playing audio.
-		**/
-		virtual void stop() = 0;
-
-		/**
-		* Pauses playback on the specified source.
-		* @param source The source on which to pause the playback.
-		**/
-		virtual void pause(Source * source) = 0;
-
-		/**
-		* Pauses all audio.
-		**/
-		virtual void pause() = 0;
-
-		/**
-		* Resumes playback on the specified source.
-		* @param source The source on which to resume the playback.
-		**/
-		virtual void resume(Source * source) = 0;
-
-		/**
-		* Resumes all audio.
-		**/
-		virtual void resume() = 0;
-
-		/**
-		* Rewinds the specified source. Whatever is playing on this
-		* source gets rewound to the start.
-		* @param source The source to rewind.
-		**/
-		virtual void rewind(Source * source) = 0;
-
-		/**
-		* Rewinds all playing audio.
-		**/
-		virtual void rewind() = 0;
-
-		/**
-		* Sets the master volume, where 0.0f is min (off) and 1.0f is max.
-		* @param volume The new master volume.
-		**/
-		virtual void setVolume(float volume) = 0;
-
-		/**
-		* Gets the master volume.
-		* @return The current master volume.
-		**/
-		virtual float getVolume() const = 0;
-
-		/**
-		* Gets the position of the listener.
-		* @param v A float array of size 3 containing (x,y,z) in that order.
-		**/
-		virtual void getPosition(float * v) const = 0;
-
-		/**
-		* Sets the position of the listener.
-		* @param v A float array of size 3 containing [x,y,z] in that order.
-		**/
-		virtual void setPosition(float * v) = 0;
-
-		/**
-		* Gets the orientation of the listener.
-		* @param v A float array of size 6 containing [x,y,z] for the forward
-		* vector, followed by [x,y,z] for the up vector.
-		**/
-		virtual void getOrientation(float * v) const = 0;
-
-		/**
-		* Sets the orientation of the listener.
-		* @param v A float array of size 6 containing [x,y,z] for the forward
-		* vector, followed by [x,y,z] for the up vector.
-		**/
-		virtual void setOrientation(float * v) = 0;
-
-		/**
-		* Gets the velocity of the listener.
-		* @param v A float array of size 3 containing [x,y,z] in that order.
-		**/
-		virtual void getVelocity(float * v) const = 0;
-
-		/**
-		* Sets the velocity of the listener.
-		* @param v A float array of size 3 containing [x,y,z] in that order.
-		**/
-		virtual void setVelocity(float * v) = 0;
-
-		/**
-		* Begins recording audio input from the microphone.
-		**/
-		virtual void record() = 0;
-
-		/**
-		* Gets a section of recorded audio.
-		* Per OpenAL, the measurement begins from the start of the
-		* audio data in memory, which is after the last time this function
-		* was called. If this function has not been called yet this recording
-		* session, it just grabs from the beginning.
-		* @return All the recorded SoundData thus far.
-		**/
-		virtual love::sound::SoundData * getRecordedData() = 0;
-
-		/**
-		* Stops recording and, if passed true, returns all the recorded audio
-		* not already gotten by getRecordedData.
-		* @param returnData Whether to return recorded audio.
-		* @return if returnData, all the recorded audio yet to be gotten,
-		* otherwise NULL.
-		**/
-		virtual love::sound::SoundData * stopRecording(bool returnData) = 0;
-
-		/**
-		* Checks whether LOVE is able to record audio input.
-		* @return hasMic Whether LOVE has a microphone enabled.
-		**/
-		virtual bool canRecord() = 0;
-
-		/**
-		* Gets the distance model used for attenuation.
-		* @return Distance model.
-		*/
-		virtual DistanceModel getDistanceModel() const = 0;
-
-		/**
-		* Sets the distance model used for attenuation.
-		* @param distanceModel Distance model.
-		*/
-		virtual void setDistanceModel(DistanceModel distanceModel) = 0;
-
-	private:
-			
-		static StringMap<DistanceModel, DISTANCE_MAX_ENUM>::Entry distanceModelEntries[];
-		static StringMap<DistanceModel, DISTANCE_MAX_ENUM> distanceModels;
-	}; // Audio
-
-} // audio
-} // love
-
-#endif // LOVE_AUDIO_AUDIO_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented = 0; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_AUDIO_AUDIO_H
+#define LOVE_AUDIO_AUDIO_H
+
+#include "common/Module.h"
+#include "common/StringMap.h"
+#include "Source.h"
+
+namespace love
+{
+
+namespace sound
+{
+
+class Decoder;
+class SoundData;
+
+} // sound
+
+namespace audio
+{
+
+/**
+ * The Audio module is responsible for playing back raw sound samples.
+ **/
+class Audio : public Module
+{
+public:
+
+	/**
+	 * Attenuation by distance.
+	 */
+	enum DistanceModel
+	{
+		DISTANCE_NONE = 1,
+		DISTANCE_INVERSE,
+		DISTANCE_INVERSE_CLAMPED,
+		DISTANCE_LINEAR,
+		DISTANCE_LINEAR_CLAMPED,
+		DISTANCE_EXPONENT,
+		DISTANCE_EXPONENT_CLAMPED,
+		DISTANCE_MAX_ENUM
+	};
+
+	static bool getConstant(const char *in, DistanceModel &out);
+	static bool getConstant(DistanceModel in, const char  *&out);
+
+	/**
+	 * Destructor.
+	 **/
+	virtual ~Audio() {};
+
+	virtual Source *newSource(love::sound::Decoder *decoder) = 0;
+	virtual Source *newSource(love::sound::SoundData *soundData) = 0;
+
+	/**
+	 * Gets the current number of simultaneous playing sources.
+	 * @return The current number of simultaneous playing sources.
+	 **/
+	virtual int getNumSources() const = 0;
+
+	/**
+	 * Gets the maximum supported number of simultaneous playing sources.
+	 * @return The maximum supported number of simultaneous playing sources.
+	 **/
+	virtual int getMaxSources() const = 0;
+
+	/**
+	 * Play the specified Source.
+	 * @param source The Source to play.
+	 **/
+	virtual void play(Source *source) = 0;
+
+	/**
+	 * Stops playback on the specified source.
+	 * @param source The source on which to stop the playback.
+	 **/
+	virtual void stop(Source *source) = 0;
+
+	/**
+	 * Stops all playing audio.
+	 **/
+	virtual void stop() = 0;
+
+	/**
+	 * Pauses playback on the specified source.
+	 * @param source The source on which to pause the playback.
+	 **/
+	virtual void pause(Source *source) = 0;
+
+	/**
+	 * Pauses all audio.
+	 **/
+	virtual void pause() = 0;
+
+	/**
+	 * Resumes playback on the specified source.
+	 * @param source The source on which to resume the playback.
+	 **/
+	virtual void resume(Source *source) = 0;
+
+	/**
+	 * Resumes all audio.
+	 **/
+	virtual void resume() = 0;
+
+	/**
+	 * Rewinds the specified source. Whatever is playing on this
+	 * source gets rewound to the start.
+	 * @param source The source to rewind.
+	 **/
+	virtual void rewind(Source *source) = 0;
+
+	/**
+	 * Rewinds all playing audio.
+	 **/
+	virtual void rewind() = 0;
+
+	/**
+	 * Sets the master volume, where 0.0f is min (off) and 1.0f is max.
+	 * @param volume The new master volume.
+	 **/
+	virtual void setVolume(float volume) = 0;
+
+	/**
+	 * Gets the master volume.
+	 * @return The current master volume.
+	 **/
+	virtual float getVolume() const = 0;
+
+	/**
+	 * Gets the position of the listener.
+	 * @param v A float array of size 3 containing (x,y,z) in that order.
+	 **/
+	virtual void getPosition(float *v) const = 0;
+
+	/**
+	 * Sets the position of the listener.
+	 * @param v A float array of size 3 containing [x,y,z] in that order.
+	 **/
+	virtual void setPosition(float *v) = 0;
+
+	/**
+	 * Gets the orientation of the listener.
+	 * @param v A float array of size 6 containing [x,y,z] for the forward
+	 * vector, followed by [x,y,z] for the up vector.
+	 **/
+	virtual void getOrientation(float *v) const = 0;
+
+	/**
+	 * Sets the orientation of the listener.
+	 * @param v A float array of size 6 containing [x,y,z] for the forward
+	 * vector, followed by [x,y,z] for the up vector.
+	 **/
+	virtual void setOrientation(float *v) = 0;
+
+	/**
+	 * Gets the velocity of the listener.
+	 * @param v A float array of size 3 containing [x,y,z] in that order.
+	 **/
+	virtual void getVelocity(float *v) const = 0;
+
+	/**
+	 * Sets the velocity of the listener.
+	 * @param v A float array of size 3 containing [x,y,z] in that order.
+	 **/
+	virtual void setVelocity(float *v) = 0;
+
+	/**
+	 * Begins recording audio input from the microphone.
+	 **/
+	virtual void record() = 0;
+
+	/**
+	 * Gets a section of recorded audio.
+	 * Per OpenAL, the measurement begins from the start of the
+	 * audio data in memory, which is after the last time this function
+	 * was called. If this function has not been called yet this recording
+	 * session, it just grabs from the beginning.
+	 * @return All the recorded SoundData thus far.
+	 **/
+	virtual love::sound::SoundData *getRecordedData() = 0;
+
+	/**
+	 * Stops recording and, if passed true, returns all the recorded audio
+	 * not already gotten by getRecordedData.
+	 * @param returnData Whether to return recorded audio.
+	 * @return if returnData, all the recorded audio yet to be gotten,
+	 * otherwise NULL.
+	 **/
+	virtual love::sound::SoundData *stopRecording(bool returnData) = 0;
+
+	/**
+	 * Checks whether LOVE is able to record audio input.
+	 * @return hasMic Whether LOVE has a microphone enabled.
+	 **/
+	virtual bool canRecord() = 0;
+
+	/**
+	 * Gets the distance model used for attenuation.
+	 * @return Distance model.
+	 */
+	virtual DistanceModel getDistanceModel() const = 0;
+
+	/**
+	 * Sets the distance model used for attenuation.
+	 * @param distanceModel Distance model.
+	 */
+	virtual void setDistanceModel(DistanceModel distanceModel) = 0;
+
+private:
+
+	static StringMap<DistanceModel, DISTANCE_MAX_ENUM>::Entry distanceModelEntries[];
+	static StringMap<DistanceModel, DISTANCE_MAX_ENUM> distanceModels;
+}; // Audio
+
+} // audio
+} // love
+
+#endif // LOVE_AUDIO_AUDIO_H

+ 74 - 73
src/modules/audio/Source.cpp

@@ -1,73 +1,74 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "Source.h"
-
-namespace love
-{
-namespace audio
-{
-	Source::Source(Type type)
-		: type(type)
-	{
-	}
-
-	Source::~Source()
-	{
-	}
-
-	bool Source::getConstant(const char * in, Type & out)
-	{
-		return types.find(in, out);
-	}
-
-	bool Source::getConstant(Type in, const char *& out)
-	{
-		return types.find(in, out);
-	}
-
-	bool Source::getConstant(const char * in, Unit & out)
-	{
-		return units.find(in, out);
-	}
-
-	bool Source::getConstant(Unit in, const char *& out)
-	{
-		return units.find(in, out);
-	}
-
-	StringMap<Source::Type, Source::TYPE_MAX_ENUM>::Entry Source::typeEntries[] =
-	{
-		{"static", Source::TYPE_STATIC},
-		{"stream", Source::TYPE_STREAM},
-	};
-
-	StringMap<Source::Type, Source::TYPE_MAX_ENUM> Source::types(Source::typeEntries, sizeof(Source::typeEntries));
-
-	StringMap<Source::Unit, Source::UNIT_MAX_ENUM>::Entry Source::unitEntries[] =
-	{
-		{"seconds", Source::UNIT_SECONDS},
-		{"samples", Source::UNIT_SAMPLES},
-	};
-
-	StringMap<Source::Unit, Source::UNIT_MAX_ENUM> Source::units(Source::unitEntries, sizeof(Source::unitEntries));
-
-} // audio
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "Source.h"
+
+namespace love
+{
+namespace audio
+{
+
+Source::Source(Type type)
+	: type(type)
+{
+}
+
+Source::~Source()
+{
+}
+
+bool Source::getConstant(const char *in, Type &out)
+{
+	return types.find(in, out);
+}
+
+bool Source::getConstant(Type in, const char  *&out)
+{
+	return types.find(in, out);
+}
+
+bool Source::getConstant(const char *in, Unit &out)
+{
+	return units.find(in, out);
+}
+
+bool Source::getConstant(Unit in, const char  *&out)
+{
+	return units.find(in, out);
+}
+
+StringMap<Source::Type, Source::TYPE_MAX_ENUM>::Entry Source::typeEntries[] =
+{
+	{"static", Source::TYPE_STATIC},
+	{"stream", Source::TYPE_STREAM},
+};
+
+StringMap<Source::Type, Source::TYPE_MAX_ENUM> Source::types(Source::typeEntries, sizeof(Source::typeEntries));
+
+StringMap<Source::Unit, Source::UNIT_MAX_ENUM>::Entry Source::unitEntries[] =
+{
+	{"seconds", Source::UNIT_SECONDS},
+	{"samples", Source::UNIT_SAMPLES},
+};
+
+StringMap<Source::Unit, Source::UNIT_MAX_ENUM> Source::units(Source::unitEntries, sizeof(Source::unitEntries));
+
+} // audio
+} // love

+ 119 - 119
src/modules/audio/Source.h

@@ -1,119 +1,119 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_AUDIO_SOURCE_H
-#define LOVE_AUDIO_SOURCE_H
-
-// LOVE
-#include <common/Object.h>
-#include <common/StringMap.h>
-
-namespace love
-{
-namespace audio
-{
-	class Source : public Object
-	{
-	public:
-
-		enum Type
-		{
-			TYPE_STATIC = 1,
-			TYPE_STREAM,
-			TYPE_MAX_ENUM
-		}; // Type
-
-		enum Unit
-		{
-			UNIT_SECONDS = 1,
-			UNIT_SAMPLES,
-			UNIT_MAX_ENUM
-		};
-
-	protected:
-		Type type;
-	public:
-
-		Source(Type type);
-		virtual ~Source();
-
-		virtual Source * copy() = 0;
-
-		virtual void play() = 0;
-		virtual void stop() = 0;
-		virtual void pause() = 0;
-		virtual void resume() = 0;
-		virtual void rewind() = 0;
-		virtual bool isStopped() const = 0;
-		virtual bool isPaused() const = 0;
-		virtual bool isFinished() const = 0;
-		virtual bool update() = 0;
-
-		virtual void setPitch(float pitch) = 0;
-		virtual float getPitch() const = 0;
-
-		virtual void setVolume(float volume) = 0;
-		virtual float getVolume() const = 0;
-
-		virtual void seek(float offset, Unit unit) = 0;
-		virtual float tell(Unit unit) = 0;
-
-		// all float * v must be of size 3
-		virtual void setPosition(float * v) = 0;
-		virtual void getPosition(float * v) const = 0;
-		virtual void setVelocity(float * v) = 0;
-		virtual void getVelocity(float * v) const = 0;
-		virtual void setDirection(float * v) = 0;
-		virtual void getDirection(float * v) const = 0;
-
-		virtual void setLooping(bool looping) = 0;
-		virtual bool isLooping() const = 0;
-		virtual bool isStatic() const = 0;
-		
-		virtual void setMinVolume(float volume) = 0;
-		virtual float getMinVolume() const = 0;
-		virtual void setMaxVolume(float volume) = 0;
-		virtual float getMaxVolume() const = 0;
-
-		virtual void setReferenceDistance(float distance) = 0;
-		virtual float getReferenceDistance() const = 0;
-		virtual void setRolloffFactor(float factor) = 0;
-		virtual float getRolloffFactor() const = 0;
-		virtual void setMaxDistance(float distance) = 0;
-		virtual float getMaxDistance() const = 0;
-
-		static bool getConstant(const char * in, Type & out);
-		static bool getConstant(Type in, const char *& out);
-		static bool getConstant(const char * in, Unit & out);
-		static bool getConstant(Unit in, const char *& out);
-
-	private:
-
-		static StringMap<Type, TYPE_MAX_ENUM>::Entry typeEntries[];
-		static StringMap<Type, TYPE_MAX_ENUM> types;
-		static StringMap<Unit, UNIT_MAX_ENUM>::Entry unitEntries[];
-		static StringMap<Unit, UNIT_MAX_ENUM> units;
-
-	}; // Source
-
-} // audio
-} // love
-
-#endif // LOVE_AUDIO_SOURCE_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_AUDIO_SOURCE_H
+#define LOVE_AUDIO_SOURCE_H
+
+// LOVE
+#include "common/Object.h"
+#include "common/StringMap.h"
+
+namespace love
+{
+namespace audio
+{
+
+class Source : public Object
+{
+public:
+
+	enum Type
+	{
+		TYPE_STATIC = 1,
+		TYPE_STREAM,
+		TYPE_MAX_ENUM
+	}; // Type
+
+	enum Unit
+	{
+		UNIT_SECONDS = 1,
+		UNIT_SAMPLES,
+		UNIT_MAX_ENUM
+	};
+
+	Source(Type type);
+	virtual ~Source();
+
+	virtual Source *copy() = 0;
+
+	virtual void play() = 0;
+	virtual void stop() = 0;
+	virtual void pause() = 0;
+	virtual void resume() = 0;
+	virtual void rewind() = 0;
+	virtual bool isStopped() const = 0;
+	virtual bool isPaused() const = 0;
+	virtual bool isFinished() const = 0;
+	virtual bool update() = 0;
+
+	virtual void setPitch(float pitch) = 0;
+	virtual float getPitch() const = 0;
+
+	virtual void setVolume(float volume) = 0;
+	virtual float getVolume() const = 0;
+
+	virtual void seek(float offset, Unit unit) = 0;
+	virtual float tell(Unit unit) = 0;
+
+	// all float * v must be of size 3
+	virtual void setPosition(float *v) = 0;
+	virtual void getPosition(float *v) const = 0;
+	virtual void setVelocity(float *v) = 0;
+	virtual void getVelocity(float *v) const = 0;
+	virtual void setDirection(float *v) = 0;
+	virtual void getDirection(float *v) const = 0;
+
+	virtual void setLooping(bool looping) = 0;
+	virtual bool isLooping() const = 0;
+	virtual bool isStatic() const = 0;
+
+	virtual void setMinVolume(float volume) = 0;
+	virtual float getMinVolume() const = 0;
+	virtual void setMaxVolume(float volume) = 0;
+	virtual float getMaxVolume() const = 0;
+
+	virtual void setReferenceDistance(float distance) = 0;
+	virtual float getReferenceDistance() const = 0;
+	virtual void setRolloffFactor(float factor) = 0;
+	virtual float getRolloffFactor() const = 0;
+	virtual void setMaxDistance(float distance) = 0;
+	virtual float getMaxDistance() const = 0;
+
+	static bool getConstant(const char *in, Type &out);
+	static bool getConstant(Type in, const char  *&out);
+	static bool getConstant(const char *in, Unit &out);
+	static bool getConstant(Unit in, const char  *&out);
+
+protected:
+	Type type;
+
+private:
+
+	static StringMap<Type, TYPE_MAX_ENUM>::Entry typeEntries[];
+	static StringMap<Type, TYPE_MAX_ENUM> types;
+	static StringMap<Unit, UNIT_MAX_ENUM>::Entry unitEntries[];
+	static StringMap<Unit, UNIT_MAX_ENUM> units;
+
+}; // Source
+
+} // audio
+} // love
+
+#endif // LOVE_AUDIO_SOURCE_H

+ 168 - 167
src/modules/audio/null/Audio.cpp

@@ -1,167 +1,168 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "Audio.h"
-
-namespace love
-{
-namespace audio
-{
-namespace null
-{
-	Audio::Audio() : distanceModel(DISTANCE_NONE)
-	{
-	}
-
-	Audio::~Audio()
-	{
-	}
-
-	const char * Audio::getName() const
-	{
-		return "love.audio.null";
-	}
-
-	love::audio::Source * Audio::newSource(love::sound::Decoder *)
-	{
-		return new Source();
-	}
-
-	love::audio::Source * Audio::newSource(love::sound::SoundData *)
-	{
-		return new Source();
-	}
-
-	int Audio::getNumSources() const
-	{
-		return 0;
-	}
-
-	int Audio::getMaxSources() const
-	{
-		return 0;
-	}
-
-	void Audio::play(love::audio::Source *)
-	{
-	}
-
-	void Audio::play()
-	{
-	}
-
-	void Audio::stop(love::audio::Source *)
-	{
-	}
-
-	void Audio::stop()
-	{
-	}
-
-	void Audio::pause(love::audio::Source *)
-	{
-	}
-
-	void Audio::pause()
-	{
-	}
-
-	void Audio::resume(love::audio::Source *)
-	{
-	}
-
-	void Audio::resume()
-	{
-	}
-
-	void Audio::rewind(love::audio::Source *)
-	{
-	}
-
-	void Audio::rewind()
-	{
-	}
-
-	void Audio::setVolume(float volume)
-	{
-		this->volume = volume;
-	}
-
-	float Audio::getVolume() const
-	{
-		return volume;
-	}
-
-	void Audio::getPosition(float *) const
-	{
-	}
-
-	void Audio::setPosition(float *)
-	{
-	}
-
-	void Audio::getOrientation(float *) const
-	{
-	}
-
-	void Audio::setOrientation(float *)
-	{
-	}
-
-	void Audio::getVelocity(float *) const
-	{
-	}
-
-	void Audio::setVelocity(float *)
-	{
-	}
-
-	void Audio::record()
-	{
-	}
-
-	love::sound::SoundData * Audio::getRecordedData()
-	{
-		return NULL;
-	}
-
-	love::sound::SoundData * Audio::stopRecording(bool)
-	{
-		return NULL;
-	}
-
-	bool Audio::canRecord()
-	{
-		return false;
-	}
-	
-	Audio::DistanceModel Audio::getDistanceModel() const
-	{
-		return this->distanceModel;
-	}
-
-	void Audio::setDistanceModel(DistanceModel distanceModel)
-	{
-		this->distanceModel = distanceModel;
-	}
-
-} // null
-} // audio
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "Audio.h"
+
+namespace love
+{
+namespace audio
+{
+namespace null
+{
+
+Audio::Audio() : distanceModel(DISTANCE_NONE)
+{
+}
+
+Audio::~Audio()
+{
+}
+
+const char *Audio::getName() const
+{
+	return "love.audio.null";
+}
+
+love::audio::Source *Audio::newSource(love::sound::Decoder *)
+{
+	return new Source();
+}
+
+love::audio::Source *Audio::newSource(love::sound::SoundData *)
+{
+	return new Source();
+}
+
+int Audio::getNumSources() const
+{
+	return 0;
+}
+
+int Audio::getMaxSources() const
+{
+	return 0;
+}
+
+void Audio::play(love::audio::Source *)
+{
+}
+
+void Audio::play()
+{
+}
+
+void Audio::stop(love::audio::Source *)
+{
+}
+
+void Audio::stop()
+{
+}
+
+void Audio::pause(love::audio::Source *)
+{
+}
+
+void Audio::pause()
+{
+}
+
+void Audio::resume(love::audio::Source *)
+{
+}
+
+void Audio::resume()
+{
+}
+
+void Audio::rewind(love::audio::Source *)
+{
+}
+
+void Audio::rewind()
+{
+}
+
+void Audio::setVolume(float volume)
+{
+	this->volume = volume;
+}
+
+float Audio::getVolume() const
+{
+	return volume;
+}
+
+void Audio::getPosition(float *) const
+{
+}
+
+void Audio::setPosition(float *)
+{
+}
+
+void Audio::getOrientation(float *) const
+{
+}
+
+void Audio::setOrientation(float *)
+{
+}
+
+void Audio::getVelocity(float *) const
+{
+}
+
+void Audio::setVelocity(float *)
+{
+}
+
+void Audio::record()
+{
+}
+
+love::sound::SoundData *Audio::getRecordedData()
+{
+	return NULL;
+}
+
+love::sound::SoundData *Audio::stopRecording(bool)
+{
+	return NULL;
+}
+
+bool Audio::canRecord()
+{
+	return false;
+}
+
+Audio::DistanceModel Audio::getDistanceModel() const
+{
+	return this->distanceModel;
+}
+
+void Audio::setDistanceModel(DistanceModel distanceModel)
+{
+	this->distanceModel = distanceModel;
+}
+
+} // null
+} // audio
+} // love

+ 89 - 87
src/modules/audio/null/Audio.h

@@ -1,87 +1,89 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_AUDIO_NULL_AUDIO_H
-#define LOVE_AUDIO_NULL_AUDIO_H
-
-// LOVE
-#include <audio/Audio.h>
-
-#include "Source.h"
-
-namespace love
-{
-namespace audio
-{
-namespace null
-{
-	class Audio : public love::audio::Audio
-	{
-	private:
-		float volume;
-		DistanceModel distanceModel;
-	public:
-
-		Audio();
-		virtual ~Audio();
-
-		// Implements Module.
-		const char * getName() const;
-
-		// Implements Audio.
-		love::audio::Source * newSource(love::sound::Decoder * decoder);
-		love::audio::Source * newSource(love::sound::SoundData * soundData);
-		int getNumSources() const;
-		int getMaxSources() const;
-		void play(love::audio::Source * source);
-		void play();
-		void stop(love::audio::Source * source);
-		void stop();
-		void pause(love::audio::Source * source);
-		void pause();
-		void resume(love::audio::Source * source);
-		void resume();
-		void rewind(love::audio::Source * source);
-		void rewind();
-		void setVolume(float volume);
-		float getVolume() const;
-
-		void getPosition(float * v) const;
-		void setPosition(float * v);
-		void getOrientation(float * v) const;
-		void setOrientation(float * v);
-		void getVelocity(float * v) const;
-		void setVelocity(float * v);
-
-		void record();
-		love::sound::SoundData * getRecordedData();
-		love::sound::SoundData * stopRecording(bool returnData);
-		bool canRecord();
-
-		DistanceModel getDistanceModel() const;
-		void setDistanceModel(DistanceModel distanceModel);
-
-	}; // Audio
-
-} // null
-} // audio
-} // love
-
-#endif // LOVE_AUDIO_NULL_AUDIO_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_AUDIO_NULL_AUDIO_H
+#define LOVE_AUDIO_NULL_AUDIO_H
+
+// LOVE
+#include "audio/Audio.h"
+
+#include "Source.h"
+
+namespace love
+{
+namespace audio
+{
+namespace null
+{
+
+class Audio : public love::audio::Audio
+{
+public:
+
+	Audio();
+	virtual ~Audio();
+
+	// Implements Module.
+	const char *getName() const;
+
+	// Implements Audio.
+	love::audio::Source *newSource(love::sound::Decoder *decoder);
+	love::audio::Source *newSource(love::sound::SoundData *soundData);
+	int getNumSources() const;
+	int getMaxSources() const;
+	void play(love::audio::Source *source);
+	void play();
+	void stop(love::audio::Source *source);
+	void stop();
+	void pause(love::audio::Source *source);
+	void pause();
+	void resume(love::audio::Source *source);
+	void resume();
+	void rewind(love::audio::Source *source);
+	void rewind();
+	void setVolume(float volume);
+	float getVolume() const;
+
+	void getPosition(float *v) const;
+	void setPosition(float *v);
+	void getOrientation(float *v) const;
+	void setOrientation(float *v);
+	void getVelocity(float *v) const;
+	void setVelocity(float *v);
+
+	void record();
+	love::sound::SoundData *getRecordedData();
+	love::sound::SoundData *stopRecording(bool returnData);
+	bool canRecord();
+
+	DistanceModel getDistanceModel() const;
+	void setDistanceModel(DistanceModel distanceModel);
+
+private:
+	float volume;
+	DistanceModel distanceModel;
+
+}; // Audio
+
+} // null
+} // audio
+} // love
+
+#endif // LOVE_AUDIO_NULL_AUDIO_H

+ 205 - 205
src/modules/audio/null/Source.cpp

@@ -1,205 +1,205 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "Source.h"
-
-namespace love
-{
-namespace audio
-{
-namespace null
-{
-
-	Source::Source()
-		: love::audio::Source(Source::TYPE_STATIC)
-	{
-	}
-
-	Source::~Source()
-	{
-	}
-
-	love::audio::Source * Source::copy()
-	{
-		this->retain();
-		return this;
-	}
-
-	void Source::play()
-	{
-	}
-
-	void Source::stop()
-	{
-	}
-
-	void Source::pause()
-	{
-	}
-
-	void Source::resume()
-	{
-	}
-
-	void Source::rewind()
-	{
-	}
-
-	bool Source::isStopped() const
-	{
-		return true;
-	}
-
-	bool Source::isPaused() const
-	{
-		return false;
-	}
-
-	bool Source::isFinished() const
-	{
-		return true;
-	}
-
-	bool Source::update()
-	{
-		return false;
-	}
-
-	void Source::setPitch(float pitch)
-	{
-		this->pitch = pitch;
-	}
-
-	float Source::getPitch() const
-	{
-		return pitch;
-	}
-
-	void Source::setVolume(float volume)
-	{
-		this->volume = volume;
-	}
-
-	float Source::getVolume() const
-	{
-		return volume;
-	}
-
-	void Source::seek(float, Source::Unit)
-	{
-	}
-
-	float Source::tell(Source::Unit)
-	{
-		return 0.0f;
-	}
-
-	void Source::setPosition(float *)
-	{
-	}
-
-	void Source::getPosition(float *) const
-	{
-	}
-
-	void Source::setVelocity(float *)
-	{
-	}
-
-	void Source::getVelocity(float *) const
-	{
-	}
-
-	void Source::setDirection(float *)
-	{
-	}
-
-	void Source::getDirection(float *) const
-	{
-	}
-
-	void Source::setLooping(bool looping)
-	{
-		this->looping = looping;
-	}
-
-	bool Source::isLooping() const
-	{
-		return looping;
-	}
-
-	bool Source::isStatic() const
-	{
-		return (type == TYPE_STATIC);
-	}
-	
-	void Source::setMinVolume(float volume)
-	{
-		this->minVolume = volume;
-	}
-
-	float Source::getMinVolume() const
-	{
-		return this->minVolume;
-	}
-
-	void Source::setMaxVolume(float volume)
-	{
-		this->maxVolume = volume;
-	}
-
-	float Source::getMaxVolume() const
-	{
-		return this->maxVolume;
-	}
-
-	void Source::setReferenceDistance(float distance)
-	{
-		this->referenceDistance = distance;
-	}
-
-	float Source::getReferenceDistance() const
-	{
-		return this->referenceDistance;
-	}
-
-	void Source::setRolloffFactor(float factor)
-	{
-		this->rolloffFactor = factor;
-	}
-
-	float Source::getRolloffFactor() const
-	{
-		return this->rolloffFactor;
-	}
-
-	void Source::setMaxDistance(float distance)
-	{
-		this->maxDistance = distance;
-	}
-
-	float Source::getMaxDistance() const
-	{
-		return this->maxDistance;
-	}
-
-} // null
-} // audio
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "Source.h"
+
+namespace love
+{
+namespace audio
+{
+namespace null
+{
+
+Source::Source()
+	: love::audio::Source(Source::TYPE_STATIC)
+{
+}
+
+Source::~Source()
+{
+}
+
+love::audio::Source *Source::copy()
+{
+	this->retain();
+	return this;
+}
+
+void Source::play()
+{
+}
+
+void Source::stop()
+{
+}
+
+void Source::pause()
+{
+}
+
+void Source::resume()
+{
+}
+
+void Source::rewind()
+{
+}
+
+bool Source::isStopped() const
+{
+	return true;
+}
+
+bool Source::isPaused() const
+{
+	return false;
+}
+
+bool Source::isFinished() const
+{
+	return true;
+}
+
+bool Source::update()
+{
+	return false;
+}
+
+void Source::setPitch(float pitch)
+{
+	this->pitch = pitch;
+}
+
+float Source::getPitch() const
+{
+	return pitch;
+}
+
+void Source::setVolume(float volume)
+{
+	this->volume = volume;
+}
+
+float Source::getVolume() const
+{
+	return volume;
+}
+
+void Source::seek(float, Source::Unit)
+{
+}
+
+float Source::tell(Source::Unit)
+{
+	return 0.0f;
+}
+
+void Source::setPosition(float *)
+{
+}
+
+void Source::getPosition(float *) const
+{
+}
+
+void Source::setVelocity(float *)
+{
+}
+
+void Source::getVelocity(float *) const
+{
+}
+
+void Source::setDirection(float *)
+{
+}
+
+void Source::getDirection(float *) const
+{
+}
+
+void Source::setLooping(bool looping)
+{
+	this->looping = looping;
+}
+
+bool Source::isLooping() const
+{
+	return looping;
+}
+
+bool Source::isStatic() const
+{
+	return (type == TYPE_STATIC);
+}
+
+void Source::setMinVolume(float volume)
+{
+	this->minVolume = volume;
+}
+
+float Source::getMinVolume() const
+{
+	return this->minVolume;
+}
+
+void Source::setMaxVolume(float volume)
+{
+	this->maxVolume = volume;
+}
+
+float Source::getMaxVolume() const
+{
+	return this->maxVolume;
+}
+
+void Source::setReferenceDistance(float distance)
+{
+	this->referenceDistance = distance;
+}
+
+float Source::getReferenceDistance() const
+{
+	return this->referenceDistance;
+}
+
+void Source::setRolloffFactor(float factor)
+{
+	this->rolloffFactor = factor;
+}
+
+float Source::getRolloffFactor() const
+{
+	return this->rolloffFactor;
+}
+
+void Source::setMaxDistance(float distance)
+{
+	this->maxDistance = distance;
+}
+
+float Source::getMaxDistance() const
+{
+	return this->maxDistance;
+}
+
+} // null
+} // audio
+} // love

+ 94 - 93
src/modules/audio/null/Source.h

@@ -1,93 +1,94 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_AUDIO_NULL_SOURCE_H
-#define LOVE_AUDIO_NULL_SOURCE_H
-
-// LOVE
-#include <common/Object.h>
-#include <audio/Source.h>
-
-namespace love
-{
-namespace audio
-{
-namespace null
-{
-	class Source : public love::audio::Source
-	{
-	private:
-
-		float pitch;
-		float volume;
-		bool looping;
-		float minVolume;
-		float maxVolume;
-		float referenceDistance;
-		float rolloffFactor;
-		float maxDistance;
-
-	public:
-		Source();
-		virtual ~Source();
-
-		virtual love::audio::Source * copy();
-		virtual void play();
-		virtual void stop();
-		virtual void pause();
-		virtual void resume();
-		virtual void rewind();
-		virtual bool isStopped() const;
-		virtual bool isPaused() const;
-		virtual bool isFinished() const;
-		virtual bool update();
-		virtual void setPitch(float pitch);
-		virtual float getPitch() const;
-		virtual void setVolume(float volume);
-		virtual float getVolume() const;
-		virtual void seek(float offset, Unit unit);
-		virtual float tell(Unit unit);
-		virtual void setPosition(float * v);
-		virtual void getPosition(float * v) const;
-		virtual void setVelocity(float * v);
-		virtual void getVelocity(float * v) const;
-		virtual void setDirection(float * v);
-		virtual void getDirection(float * v) const;
-		void setLooping(bool looping);
-		bool isLooping() const;
-		bool isStatic() const;
-		virtual void setMinVolume(float volume);
-		virtual float getMinVolume() const;
-		virtual void setMaxVolume(float volume);
-		virtual float getMaxVolume() const;
-		virtual void setReferenceDistance(float distance);
-		virtual float getReferenceDistance() const;
-		virtual void setRolloffFactor(float factor);
-		virtual float getRolloffFactor() const;
-		virtual void setMaxDistance(float distance);
-		virtual float getMaxDistance() const;
-
-	}; // Source
-
-} // null
-} // audio
-} // love
-
-#endif // LOVE_AUDIO_NULL_SOURCE_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_AUDIO_NULL_SOURCE_H
+#define LOVE_AUDIO_NULL_SOURCE_H
+
+// LOVE
+#include "common/Object.h"
+#include "audio/Source.h"
+
+namespace love
+{
+namespace audio
+{
+namespace null
+{
+
+class Source : public love::audio::Source
+{
+public:
+	Source();
+	virtual ~Source();
+
+	virtual love::audio::Source *copy();
+	virtual void play();
+	virtual void stop();
+	virtual void pause();
+	virtual void resume();
+	virtual void rewind();
+	virtual bool isStopped() const;
+	virtual bool isPaused() const;
+	virtual bool isFinished() const;
+	virtual bool update();
+	virtual void setPitch(float pitch);
+	virtual float getPitch() const;
+	virtual void setVolume(float volume);
+	virtual float getVolume() const;
+	virtual void seek(float offset, Unit unit);
+	virtual float tell(Unit unit);
+	virtual void setPosition(float *v);
+	virtual void getPosition(float *v) const;
+	virtual void setVelocity(float *v);
+	virtual void getVelocity(float *v) const;
+	virtual void setDirection(float *v);
+	virtual void getDirection(float *v) const;
+	void setLooping(bool looping);
+	bool isLooping() const;
+	bool isStatic() const;
+	virtual void setMinVolume(float volume);
+	virtual float getMinVolume() const;
+	virtual void setMaxVolume(float volume);
+	virtual float getMaxVolume() const;
+	virtual void setReferenceDistance(float distance);
+	virtual float getReferenceDistance() const;
+	virtual void setRolloffFactor(float factor);
+	virtual float getRolloffFactor() const;
+	virtual void setMaxDistance(float distance);
+	virtual float getMaxDistance() const;
+
+private:
+
+	float pitch;
+	float volume;
+	bool looping;
+	float minVolume;
+	float maxVolume;
+	float referenceDistance;
+	float rolloffFactor;
+	float maxDistance;
+
+}; // Source
+
+} // null
+} // audio
+} // love
+
+#endif // LOVE_AUDIO_NULL_SOURCE_H

+ 319 - 316
src/modules/audio/openal/Audio.cpp

@@ -1,316 +1,319 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "Audio.h"
-#include <common/delay.h>
-
-#include <sound/Decoder.h>
-
-namespace love
-{
-namespace audio
-{
-namespace openal
-{
-	Audio::PoolThread::PoolThread(Pool* pool)
-	: pool(pool), finish(false)
-	{
-	}
-
-	void Audio::PoolThread::main()
-	{
-		while (true)
-		{
-			{
-				thread::Lock lock(mutex);
-				if (finish)
-				{
-					return;
-				}
-			}
-
-			pool->update();
-			delay(5);
-		}
-	}
-
-	void Audio::PoolThread::setFinish()
-	{
-		thread::Lock lock(mutex);
-		finish = true;
-	}
-
-
-	Audio::Audio() : distanceModel(DISTANCE_INVERSE_CLAMPED)
-	{
-		// Passing zero for default device.
-		device = alcOpenDevice(0);
-
-		if (device == 0)
-			throw love::Exception("Could not open device.");
-
-		context = alcCreateContext(device, 0);
-
-		if (context == 0)
-			throw love::Exception("Could not create context.");
-
-		alcMakeContextCurrent(context);
-
-		if (alcGetError(device) != ALC_NO_ERROR)
-			throw love::Exception("Could not make context current.");
-
-		/*std::string captureName(alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER));
-		const ALCchar * devices = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER);
-		while (*devices)
-		{
-			std::string device(devices);
-			devices += device.size() + 1;
-			if (device.find("Mic") != std::string::npos || device.find("mic") != std::string::npos)
-			{
-				captureName = device;
-			}
-		}
-
-		capture = alcCaptureOpenDevice(captureName.c_str(), 8000, AL_FORMAT_MONO16, 262144); // about 32 seconds
-
-		if (!capture)
-		{
-			// We're not going to prevent LOVE from running without a microphone, but we should warn, at least
-			std::cerr << "Warning, couldn't open capture device! No audio input!" << std::endl;
-		}*/
-
-		// pool must be allocated after AL context.
-		pool = new Pool();
-
-		poolThread = new PoolThread(pool);
-		poolThread->start();
-	}
-
-	Audio::~Audio()
-	{
-		poolThread->setFinish();
-		poolThread->wait();
-
-		delete poolThread;
-		delete pool;
-
-		alcMakeContextCurrent(0);
-		alcDestroyContext(context);
-		//if (capture) alcCaptureCloseDevice(capture);
-		alcCloseDevice(device);
-	}
-
-
-	const char * Audio::getName() const
-	{
-		return "love.audio.openal";
-	}
-
-	love::audio::Source * Audio::newSource(love::sound::Decoder * decoder)
-	{
-		return new Source(pool, decoder);
-	}
-
-	love::audio::Source * Audio::newSource(love::sound::SoundData * soundData)
-	{
-		return new Source(pool, soundData);
-	}
-
-	int Audio::getNumSources() const
-	{
-		return pool->getNumSources();
-	}
-
-	int Audio::getMaxSources() const
-	{
-		return pool->getMaxSources();
-	}
-
-	void Audio::play(love::audio::Source * source)
-	{
-		source->play();
-	}
-
-	void Audio::stop(love::audio::Source * source)
-	{
-		source->stop();
-	}
-
-	void Audio::stop()
-	{
-		pool->stop();
-	}
-
-	void Audio::pause(love::audio::Source * source)
-	{
-		source->pause();
-	}
-
-	void Audio::pause()
-	{
-		pool->pause();
-	}
-
-	void Audio::resume(love::audio::Source * source)
-	{
-		source->resume();
-	}
-
-	void Audio::resume()
-	{
-		pool->resume();
-	}
-
-	void Audio::rewind(love::audio::Source * source)
-	{
-		source->rewind();
-	}
-
-	void Audio::rewind()
-	{
-		pool->rewind();
-	}
-
-	void Audio::setVolume(float volume)
-	{
-		alListenerf(AL_GAIN, volume);
-	}
-
-	float Audio::getVolume() const
-	{
-		ALfloat volume;
-		alGetListenerf(AL_GAIN, &volume);
-		return volume;
-	}
-
-	void Audio::getPosition(float * v) const
-	{
-		alGetListenerfv(AL_POSITION, v);
-	}
-
-	void Audio::setPosition(float * v)
-	{
-		alListenerfv(AL_POSITION, v);
-	}
-
-	void Audio::getOrientation(float * v) const
-	{
-		alGetListenerfv(AL_ORIENTATION, v);
-	}
-
-	void Audio::setOrientation(float * v)
-	{
-		alListenerfv(AL_ORIENTATION, v);
-	}
-
-	void Audio::getVelocity(float * v) const
-	{
-		alGetListenerfv(AL_VELOCITY, v);
-	}
-
-	void Audio::setVelocity(float * v)
-	{
-		alListenerfv(AL_VELOCITY, v);
-	}
-
-	void Audio::record()
-	{
-		if (!canRecord()) return;
-		alcCaptureStart(capture);
-	}
-
-	love::sound::SoundData * Audio::getRecordedData()
-	{
-		if (!canRecord())
-			return NULL;
-		int samplerate = 8000;
-		ALCint samples;
-		alcGetIntegerv(capture, ALC_CAPTURE_SAMPLES, 4, &samples);
-		void * data = malloc(samples * (2/sizeof(char)));
-		alcCaptureSamples(capture, data, samples);
-		love::sound::SoundData * sd = new love::sound::SoundData(data, samples, samplerate, 16, 1);
-		free(data);
-		return sd;
-	}
-
-	love::sound::SoundData * Audio::stopRecording(bool returnData)
-	{
-		if (!canRecord())
-			return NULL;
-		love::sound::SoundData * sd = NULL;
-		if (returnData)
-		{
-			sd = getRecordedData();
-		}
-		alcCaptureStop(capture);
-		return sd;
-	}
-
-	bool Audio::canRecord()
-	{
-		return (capture != NULL);
-	}
-	
-	Audio::DistanceModel Audio::getDistanceModel() const
-	{
-		return this->distanceModel;
-	}
-
-	void Audio::setDistanceModel(DistanceModel distanceModel)
-	{
-		this->distanceModel = distanceModel;
-		
-		switch (distanceModel)
-		{
-		case DISTANCE_NONE:
-			alDistanceModel(AL_NONE);
-			break;
-			
-		case DISTANCE_INVERSE:
-			alDistanceModel(AL_INVERSE_DISTANCE);
-			break;
-
-		case DISTANCE_INVERSE_CLAMPED:
-			alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
-			break;
-			
-		case DISTANCE_LINEAR:
-			alDistanceModel(AL_LINEAR_DISTANCE);
-			break;
-
-		case DISTANCE_LINEAR_CLAMPED:
-			alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);
-			break;
-			
-		case DISTANCE_EXPONENT:
-			alDistanceModel(AL_EXPONENT_DISTANCE);
-			break;
-
-		case DISTANCE_EXPONENT_CLAMPED:
-			alDistanceModel(AL_EXPONENT_DISTANCE_CLAMPED);
-			break;
-
-		default:
-			break;
-		}
-	}
-} // openal
-} // audio
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "Audio.h"
+#include "common/delay.h"
+
+#include "sound/Decoder.h"
+
+namespace love
+{
+namespace audio
+{
+namespace openal
+{
+
+Audio::PoolThread::PoolThread(Pool *pool)
+	: pool(pool)
+	, finish(false)
+{
+}
+
+void Audio::PoolThread::main()
+{
+	while (true)
+	{
+		{
+			thread::Lock lock(mutex);
+			if (finish)
+			{
+				return;
+			}
+		}
+
+		pool->update();
+		delay(5);
+	}
+}
+
+void Audio::PoolThread::setFinish()
+{
+	thread::Lock lock(mutex);
+	finish = true;
+}
+
+
+Audio::Audio() : distanceModel(DISTANCE_INVERSE_CLAMPED)
+{
+	// Passing zero for default device.
+	device = alcOpenDevice(0);
+
+	if (device == 0)
+		throw love::Exception("Could not open device.");
+
+	context = alcCreateContext(device, 0);
+
+	if (context == 0)
+		throw love::Exception("Could not create context.");
+
+	alcMakeContextCurrent(context);
+
+	if (alcGetError(device) != ALC_NO_ERROR)
+		throw love::Exception("Could not make context current.");
+
+	/*std::string captureName(alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER));
+	const ALCchar * devices = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER);
+	while (*devices)
+	{
+		std::string device(devices);
+		devices += device.size() + 1;
+		if (device.find("Mic") != std::string::npos || device.find("mic") != std::string::npos)
+		{
+			captureName = device;
+		}
+	}
+
+	capture = alcCaptureOpenDevice(captureName.c_str(), 8000, AL_FORMAT_MONO16, 262144); // about 32 seconds
+
+	if (!capture)
+	{
+		// We're not going to prevent LOVE from running without a microphone, but we should warn, at least
+		std::cerr << "Warning, couldn't open capture device! No audio input!" << std::endl;
+	}*/
+
+	// pool must be allocated after AL context.
+	pool = new Pool();
+
+	poolThread = new PoolThread(pool);
+	poolThread->start();
+}
+
+Audio::~Audio()
+{
+	poolThread->setFinish();
+	poolThread->wait();
+
+	delete poolThread;
+	delete pool;
+
+	alcMakeContextCurrent(0);
+	alcDestroyContext(context);
+	//if (capture) alcCaptureCloseDevice(capture);
+	alcCloseDevice(device);
+}
+
+
+const char *Audio::getName() const
+{
+	return "love.audio.openal";
+}
+
+love::audio::Source *Audio::newSource(love::sound::Decoder *decoder)
+{
+	return new Source(pool, decoder);
+}
+
+love::audio::Source *Audio::newSource(love::sound::SoundData *soundData)
+{
+	return new Source(pool, soundData);
+}
+
+int Audio::getNumSources() const
+{
+	return pool->getNumSources();
+}
+
+int Audio::getMaxSources() const
+{
+	return pool->getMaxSources();
+}
+
+void Audio::play(love::audio::Source *source)
+{
+	source->play();
+}
+
+void Audio::stop(love::audio::Source *source)
+{
+	source->stop();
+}
+
+void Audio::stop()
+{
+	pool->stop();
+}
+
+void Audio::pause(love::audio::Source *source)
+{
+	source->pause();
+}
+
+void Audio::pause()
+{
+	pool->pause();
+}
+
+void Audio::resume(love::audio::Source *source)
+{
+	source->resume();
+}
+
+void Audio::resume()
+{
+	pool->resume();
+}
+
+void Audio::rewind(love::audio::Source *source)
+{
+	source->rewind();
+}
+
+void Audio::rewind()
+{
+	pool->rewind();
+}
+
+void Audio::setVolume(float volume)
+{
+	alListenerf(AL_GAIN, volume);
+}
+
+float Audio::getVolume() const
+{
+	ALfloat volume;
+	alGetListenerf(AL_GAIN, &volume);
+	return volume;
+}
+
+void Audio::getPosition(float *v) const
+{
+	alGetListenerfv(AL_POSITION, v);
+}
+
+void Audio::setPosition(float *v)
+{
+	alListenerfv(AL_POSITION, v);
+}
+
+void Audio::getOrientation(float *v) const
+{
+	alGetListenerfv(AL_ORIENTATION, v);
+}
+
+void Audio::setOrientation(float *v)
+{
+	alListenerfv(AL_ORIENTATION, v);
+}
+
+void Audio::getVelocity(float *v) const
+{
+	alGetListenerfv(AL_VELOCITY, v);
+}
+
+void Audio::setVelocity(float *v)
+{
+	alListenerfv(AL_VELOCITY, v);
+}
+
+void Audio::record()
+{
+	if (!canRecord()) return;
+	alcCaptureStart(capture);
+}
+
+love::sound::SoundData *Audio::getRecordedData()
+{
+	if (!canRecord())
+		return NULL;
+	int samplerate = 8000;
+	ALCint samples;
+	alcGetIntegerv(capture, ALC_CAPTURE_SAMPLES, 4, &samples);
+	void *data = malloc(samples * (2/sizeof(char)));
+	alcCaptureSamples(capture, data, samples);
+	love::sound::SoundData *sd = new love::sound::SoundData(data, samples, samplerate, 16, 1);
+	free(data);
+	return sd;
+}
+
+love::sound::SoundData *Audio::stopRecording(bool returnData)
+{
+	if (!canRecord())
+		return NULL;
+	love::sound::SoundData *sd = NULL;
+	if (returnData)
+	{
+		sd = getRecordedData();
+	}
+	alcCaptureStop(capture);
+	return sd;
+}
+
+bool Audio::canRecord()
+{
+	return (capture != NULL);
+}
+
+Audio::DistanceModel Audio::getDistanceModel() const
+{
+	return this->distanceModel;
+}
+
+void Audio::setDistanceModel(DistanceModel distanceModel)
+{
+	this->distanceModel = distanceModel;
+
+	switch (distanceModel)
+	{
+	case DISTANCE_NONE:
+		alDistanceModel(AL_NONE);
+		break;
+
+	case DISTANCE_INVERSE:
+		alDistanceModel(AL_INVERSE_DISTANCE);
+		break;
+
+	case DISTANCE_INVERSE_CLAMPED:
+		alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
+		break;
+
+	case DISTANCE_LINEAR:
+		alDistanceModel(AL_LINEAR_DISTANCE);
+		break;
+
+	case DISTANCE_LINEAR_CLAMPED:
+		alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);
+		break;
+
+	case DISTANCE_EXPONENT:
+		alDistanceModel(AL_EXPONENT_DISTANCE);
+		break;
+
+	case DISTANCE_EXPONENT_CLAMPED:
+		alDistanceModel(AL_EXPONENT_DISTANCE_CLAMPED);
+		break;
+
+	default:
+		break;
+	}
+}
+
+} // openal
+} // audio
+} // love

+ 142 - 140
src/modules/audio/openal/Audio.h

@@ -1,140 +1,142 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_AUDIO_OPENAL_AUDIO_H
-#define LOVE_AUDIO_OPENAL_AUDIO_H
-
-// STD
-#include <queue>
-#include <map>
-#include <iostream>
-#include <cmath>
-
-// LOVE
-#include <audio/Audio.h>
-#include <common/config.h>
-#include <sound/SoundData.h>
-
-#include "Source.h"
-#include "Pool.h"
-#include <thread/threads.h>
-
-// OpenAL
-#ifdef LOVE_MACOSX
-#include <OpenAL/alc.h>
-#include <OpenAL/al.h>
-#else
-#include <AL/alc.h>
-#include <AL/al.h>
-#endif
-
-namespace love
-{
-namespace audio
-{
-namespace openal
-{
-	class Audio : public love::audio::Audio
-	{
-	private:
-
-		// The OpenAL device.
-		ALCdevice * device;
-
-		// The OpenAL capture device (microphone).
-		ALCdevice * capture;
-
-		// The OpenAL context.
-		ALCcontext * context;
-
-		// The Pool.
-		Pool * pool;
-
-
-		class PoolThread: public thread::ThreadBase {
-		protected:
-			Pool* pool;
-
-			// Set this to true when the thread should finish.
-			// Main thread will write to this value, and PoolThread
-			// will read from it.
-			volatile bool finish;
-
-			// finish lock
-			thread::Mutex mutex;
-
-			virtual void main();
-
-		public:
-			PoolThread(Pool* pool);
-			void setFinish();
-		};
-
-		PoolThread* poolThread;
-
-		DistanceModel distanceModel;
-
-	public:
-
-		Audio();
-		~Audio();
-
-		// Implements Module.
-		const char * getName() const;
-
-		// Implements Audio.
-		love::audio::Source * newSource(love::sound::Decoder * decoder);
-		love::audio::Source * newSource(love::sound::SoundData * soundData);
-		int getNumSources() const;
-		int getMaxSources() const;
-		void play(love::audio::Source * source);
-		void play();
-		void stop(love::audio::Source * source);
-		void stop();
-		void pause(love::audio::Source * source);
-		void pause();
-		void resume(love::audio::Source * source);
-		void resume();
-		void rewind(love::audio::Source * source);
-		void rewind();
-		void setVolume(float volume);
-		float getVolume() const;
-
-		void getPosition(float * v) const;
-		void setPosition(float * v);
-		void getOrientation(float * v) const;
-		void setOrientation(float * v);
-		void getVelocity(float * v) const;
-		void setVelocity(float * v);
-
-		void record();
-		love::sound::SoundData * getRecordedData();
-		love::sound::SoundData * stopRecording(bool returnData);
-		bool canRecord();
-		
-		DistanceModel getDistanceModel() const;
-		void setDistanceModel(DistanceModel distanceModel);
-	}; // Audio
-
-} // openal
-} // audio
-} // love
-
-#endif // LOVE_AUDIO_OPENAL_AUDIO_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_AUDIO_OPENAL_AUDIO_H
+#define LOVE_AUDIO_OPENAL_AUDIO_H
+
+// STD
+#include <queue>
+#include <map>
+#include <iostream>
+#include <cmath>
+
+// LOVE
+#include "audio/Audio.h"
+#include "common/config.h"
+#include "sound/SoundData.h"
+
+#include "Source.h"
+#include "Pool.h"
+#include "thread/threads.h"
+
+// OpenAL
+#ifdef LOVE_MACOSX
+#include <OpenAL/alc.h>
+#include <OpenAL/al.h>
+#else
+#include <AL/alc.h>
+#include <AL/al.h>
+#endif
+
+namespace love
+{
+namespace audio
+{
+namespace openal
+{
+
+class Audio : public love::audio::Audio
+{
+public:
+
+	Audio();
+	~Audio();
+
+	// Implements Module.
+	const char *getName() const;
+
+	// Implements Audio.
+	love::audio::Source *newSource(love::sound::Decoder *decoder);
+	love::audio::Source *newSource(love::sound::SoundData *soundData);
+	int getNumSources() const;
+	int getMaxSources() const;
+	void play(love::audio::Source *source);
+	void play();
+	void stop(love::audio::Source *source);
+	void stop();
+	void pause(love::audio::Source *source);
+	void pause();
+	void resume(love::audio::Source *source);
+	void resume();
+	void rewind(love::audio::Source *source);
+	void rewind();
+	void setVolume(float volume);
+	float getVolume() const;
+
+	void getPosition(float *v) const;
+	void setPosition(float *v);
+	void getOrientation(float *v) const;
+	void setOrientation(float *v);
+	void getVelocity(float *v) const;
+	void setVelocity(float *v);
+
+	void record();
+	love::sound::SoundData *getRecordedData();
+	love::sound::SoundData *stopRecording(bool returnData);
+	bool canRecord();
+
+	DistanceModel getDistanceModel() const;
+	void setDistanceModel(DistanceModel distanceModel);
+
+private:
+
+	// The OpenAL device.
+	ALCdevice *device;
+
+	// The OpenAL capture device (microphone).
+	ALCdevice *capture;
+
+	// The OpenAL context.
+	ALCcontext *context;
+
+	// The Pool.
+	Pool *pool;
+
+	class PoolThread: public thread::ThreadBase
+	{
+	protected:
+		Pool *pool;
+
+		// Set this to true when the thread should finish.
+		// Main thread will write to this value, and PoolThread
+		// will read from it.
+		volatile bool finish;
+
+		// finish lock
+		thread::Mutex mutex;
+
+		virtual void main();
+
+	public:
+		PoolThread(Pool *pool);
+		void setFinish();
+	};
+
+	PoolThread *poolThread;
+
+	DistanceModel distanceModel;
+
+}; // Audio
+
+} // openal
+} // audio
+} // love
+
+#endif // LOVE_AUDIO_OPENAL_AUDIO_H

+ 293 - 292
src/modules/audio/openal/Pool.cpp

@@ -1,292 +1,293 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "Pool.h"
-
-#include "Source.h"
-
-namespace love
-{
-namespace audio
-{
-namespace openal
-{
-	Pool::Pool()
-	{
-		// Generate sources.
-		alGenSources(NUM_SOURCES, sources);
-
-		// Create the mutex.
-		mutex = new thread::Mutex();
-
-		if (alGetError() != AL_NO_ERROR)
-			throw love::Exception("Could not generate sources.");
-
-		// Make all sources available initially.
-		for (int i = 0; i < NUM_SOURCES; i++)
-		{
-#ifdef AL_DIRECT_CHANNELS_SOFT
-			// Bypassing virtualization of speakers for multi-channel sources in OpenAL Soft.
-			alSourcei(sources[i], AL_DIRECT_CHANNELS_SOFT, AL_TRUE);
-#endif
-			available.push(sources[i]);
-		}
-	}
-
-	Pool::~Pool()
-	{
-		stop();
-
-		delete mutex;
-
-		// Free all sources.
-		alDeleteSources(NUM_SOURCES, sources);
-	}
-
-	bool Pool::isAvailable() const
-	{
-		bool has = false;
-		{
-			thread::Lock lock(mutex);
-			has = !available.empty();
-		}
-		return has;
-	}
-
-	bool Pool::isPlaying(Source * s)
-	{
-		bool p = false;
-		{
-			thread::Lock lock(mutex);
-			for (std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
-			{
-				if (i->first == s)
-					p = true;
-			}
-		}
-		return p;
-	}
-
-	void Pool::update()
-	{
-		thread::Lock lock(mutex);
-
-		std::map<Source *, ALuint>::iterator i = playing.begin();
-
-		while (i != playing.end())
-		{
-			if (!i->first->update())
-			{
-				i->first->stopAtomic();
-				i->first->rewindAtomic();
-				i->first->release();
-				available.push(i->second);
-				playing.erase(i++);
-			}
-			else
-				i++;
-		}
-	}
-
-	int Pool::getNumSources() const
-	{
-		return playing.size();
-	}
-
-	int Pool::getMaxSources() const
-	{
-		return NUM_SOURCES;
-	}
-
-	bool Pool::play(Source * source, ALuint & out)
-	{
-		bool ok;
-		out = 0;
-
-		thread::Lock lock(mutex);
-
-		bool alreadyPlaying = findSource(source, out);
-
-		if (!alreadyPlaying)
-		{
-			// Try to play.
-			if (!available.empty())
-			{
-				// Get the first available source.
-				out = available.front();
-
-				// Remove it.
-				available.pop();
-
-				// Insert into map of playing sources.
-				playing.insert(std::pair<Source *, ALuint>(source, out));
-
-				source->retain();
-
-				source->playAtomic();
-
-				ok = true;
-			}
-			else
-			{
-				ok = false;
-			}
-		}
-		else
-		{
-			ok = true;
-		}
-
-		return ok;
-	}
-
-	void Pool::stop()
-	{
-		thread::Lock lock(mutex);
-		for (std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
-		{
-			i->first->stopAtomic();
-			i->first->release();
-			available.push(i->second);
-		}
-
-		playing.clear();
-	}
-
-	void Pool::stop(Source * source)
-	{
-		thread::Lock lock(mutex);
-		removeSource(source);
-	}
-
-	void Pool::pause()
-	{
-		thread::Lock lock(mutex);
-		for (std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
-			i->first->pauseAtomic();
-	}
-
-	void Pool::pause(Source * source)
-	{
-		thread::Lock lock(mutex);
-		ALuint out;
-		if (findSource(source, out))
-			source->pauseAtomic();
-	}
-
-	void Pool::resume()
-	{
-		thread::Lock lock(mutex);
-		for (std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
-			i->first->resumeAtomic();
-	}
-
-	void Pool::resume(Source * source)
-	{
-		thread::Lock lock(mutex);
-		ALuint out;
-		if (findSource(source, out))
-			source->resumeAtomic();
-	}
-
-	void Pool::rewind()
-	{
-		thread::Lock lock(mutex);
-		for (std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
-			i->first->rewindAtomic();
-	}
-
-	// For those times we don't need it backed.
-	void Pool::softRewind(Source * source)
-	{
-		thread::Lock lock(mutex);
-		source->rewindAtomic();
-	}
-
-	void Pool::rewind(Source * source)
-	{
-		thread::Lock lock(mutex);
-		source->rewindAtomic();
-	}
-
-	void Pool::release(Source * source)
-	{
-		ALuint s = findi(source);
-
-		if (s != 0)
-		{
-			available.push(s);
-			playing.erase(source);
-		}
-	}
-
-	void Pool::seek(Source * source, float offset, void * unit)
-	{
-		thread::Lock lock(mutex);
-		return source->seekAtomic(offset, unit);
-	}
-
-	float Pool::tell(Source * source, void * unit)
-	{
-		thread::Lock lock(mutex);
-		return source->tellAtomic(unit);
-	}
-
-	ALuint Pool::findi(const Source * source) const
-	{
-		std::map<Source *, ALuint>::const_iterator i = playing.find((Source *)source);
-
-		if (i != playing.end())
-			return i->second;
-
-		return 0;
-	}
-
-	bool Pool::findSource(Source * source, ALuint & out)
-	{
-		std::map<Source *, ALuint>::const_iterator i = playing.find((Source *)source);
-
-		bool found = i != playing.end();
-
-		if (found)
-			out = i->second;
-
-		return found;
-	}
-
-	bool Pool::removeSource(Source * source)
-	{
-		std::map<Source *, ALuint>::iterator i = playing.find((Source *)source);
-
-		if (i != playing.end())
-		{
-			source->stopAtomic();
-			available.push(i->second);
-			playing.erase(i++);
-			source->release();
-			return true;
-		}
-
-		return false;
-	}
-
-} // openal
-} // audio
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "Pool.h"
+
+#include "Source.h"
+
+namespace love
+{
+namespace audio
+{
+namespace openal
+{
+
+Pool::Pool()
+{
+	// Generate sources.
+	alGenSources(NUM_SOURCES, sources);
+
+	// Create the mutex.
+	mutex = new thread::Mutex();
+
+	if (alGetError() != AL_NO_ERROR)
+		throw love::Exception("Could not generate sources.");
+
+	// Make all sources available initially.
+	for (int i = 0; i < NUM_SOURCES; i++)
+	{
+#ifdef AL_DIRECT_CHANNELS_SOFT
+		// Bypassing virtualization of speakers for multi-channel sources in OpenAL Soft.
+		alSourcei(sources[i], AL_DIRECT_CHANNELS_SOFT, AL_TRUE);
+#endif
+		available.push(sources[i]);
+	}
+}
+
+Pool::~Pool()
+{
+	stop();
+
+	delete mutex;
+
+	// Free all sources.
+	alDeleteSources(NUM_SOURCES, sources);
+}
+
+bool Pool::isAvailable() const
+{
+	bool has = false;
+	{
+		thread::Lock lock(mutex);
+		has = !available.empty();
+	}
+	return has;
+}
+
+bool Pool::isPlaying(Source *s)
+{
+	bool p = false;
+	{
+		thread::Lock lock(mutex);
+		for (std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
+		{
+			if (i->first == s)
+				p = true;
+		}
+	}
+	return p;
+}
+
+void Pool::update()
+{
+	thread::Lock lock(mutex);
+
+	std::map<Source *, ALuint>::iterator i = playing.begin();
+
+	while (i != playing.end())
+	{
+		if (!i->first->update())
+		{
+			i->first->stopAtomic();
+			i->first->rewindAtomic();
+			i->first->release();
+			available.push(i->second);
+			playing.erase(i++);
+		}
+		else
+			i++;
+	}
+}
+
+int Pool::getNumSources() const
+{
+	return playing.size();
+}
+
+int Pool::getMaxSources() const
+{
+	return NUM_SOURCES;
+}
+
+bool Pool::play(Source *source, ALuint &out)
+{
+	bool ok;
+	out = 0;
+
+	thread::Lock lock(mutex);
+
+	bool alreadyPlaying = findSource(source, out);
+
+	if (!alreadyPlaying)
+	{
+		// Try to play.
+		if (!available.empty())
+		{
+			// Get the first available source.
+			out = available.front();
+
+			// Remove it.
+			available.pop();
+
+			// Insert into map of playing sources.
+			playing.insert(std::pair<Source *, ALuint>(source, out));
+
+			source->retain();
+
+			source->playAtomic();
+
+			ok = true;
+		}
+		else
+		{
+			ok = false;
+		}
+	}
+	else
+	{
+		ok = true;
+	}
+
+	return ok;
+}
+
+void Pool::stop()
+{
+	thread::Lock lock(mutex);
+	for (std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
+	{
+		i->first->stopAtomic();
+		i->first->release();
+		available.push(i->second);
+	}
+
+	playing.clear();
+}
+
+void Pool::stop(Source *source)
+{
+	thread::Lock lock(mutex);
+	removeSource(source);
+}
+
+void Pool::pause()
+{
+	thread::Lock lock(mutex);
+	for (std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
+		i->first->pauseAtomic();
+}
+
+void Pool::pause(Source *source)
+{
+	thread::Lock lock(mutex);
+	ALuint out;
+	if (findSource(source, out))
+		source->pauseAtomic();
+}
+
+void Pool::resume()
+{
+	thread::Lock lock(mutex);
+	for (std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
+		i->first->resumeAtomic();
+}
+
+void Pool::resume(Source *source)
+{
+	thread::Lock lock(mutex);
+	ALuint out;
+	if (findSource(source, out))
+		source->resumeAtomic();
+}
+
+void Pool::rewind()
+{
+	thread::Lock lock(mutex);
+	for (std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
+		i->first->rewindAtomic();
+}
+
+// For those times we don't need it backed.
+void Pool::softRewind(Source *source)
+{
+	thread::Lock lock(mutex);
+	source->rewindAtomic();
+}
+
+void Pool::rewind(Source *source)
+{
+	thread::Lock lock(mutex);
+	source->rewindAtomic();
+}
+
+void Pool::release(Source *source)
+{
+	ALuint s = findi(source);
+
+	if (s != 0)
+	{
+		available.push(s);
+		playing.erase(source);
+	}
+}
+
+void Pool::seek(Source *source, float offset, void *unit)
+{
+	thread::Lock lock(mutex);
+	return source->seekAtomic(offset, unit);
+}
+
+float Pool::tell(Source *source, void *unit)
+{
+	thread::Lock lock(mutex);
+	return source->tellAtomic(unit);
+}
+
+ALuint Pool::findi(const Source *source) const
+{
+	std::map<Source *, ALuint>::const_iterator i = playing.find((Source *)source);
+
+	if (i != playing.end())
+		return i->second;
+
+	return 0;
+}
+
+bool Pool::findSource(Source *source, ALuint &out)
+{
+	std::map<Source *, ALuint>::const_iterator i = playing.find((Source *)source);
+
+	bool found = i != playing.end();
+
+	if (found)
+		out = i->second;
+
+	return found;
+}
+
+bool Pool::removeSource(Source *source)
+{
+	std::map<Source *, ALuint>::iterator i = playing.find((Source *)source);
+
+	if (i != playing.end())
+	{
+		source->stopAtomic();
+		available.push(i->second);
+		playing.erase(i++);
+		source->release();
+		return true;
+	}
+
+	return false;
+}
+
+} // openal
+} // audio
+} // love

+ 124 - 126
src/modules/audio/openal/Pool.h

@@ -1,126 +1,124 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_AUDIO_OPENAL_POOL_H
-#define LOVE_AUDIO_OPENAL_POOL_H
-
-// STD
-#include <queue>
-#include <map>
-#include <iostream>
-#include <cmath>
-
-// LOVE
-#include <common/config.h>
-#include <common/Exception.h>
-#include <thread/threads.h>
-
-// OpenAL
-#ifdef LOVE_MACOSX
-#include <OpenAL/alc.h>
-#include <OpenAL/al.h>
-#else
-#include <AL/alc.h>
-#include <AL/al.h>
-#include <AL/alext.h>
-#endif
-
-namespace love
-{
-namespace audio
-{
-namespace openal
-{
-
-	class Source;
-
-	class Pool
-	{
-	private:
-
-		// Number of OpenAL sources.
-		static const int NUM_SOURCES = 64;
-
-		// OpenAL sources
-		ALuint sources[NUM_SOURCES];
-
-		// A queue of available sources.
-		std::queue<ALuint> available;
-
-		// A map of playing sources.
-		std::map<Source *, ALuint> playing;
-
-		// Only one thread can access this object at the same time. This mutex will
-		// make sure of that.
-		thread::Mutex* mutex;
-
-	public:
-
-		Pool();
-		~Pool();
-
-		/**
-		* Checks whether an OpenAL source is available.
-		* @return True if at least one is available, false otherwise.
-		**/
-		bool isAvailable() const;
-
-		/**
-		* Checks whether a Source is currently in the playing list.
-		**/
-		bool isPlaying(Source * s);
-
-		void update();
-
-		int getNumSources() const;
-		int getMaxSources() const;
-
-		bool play(Source * source, ALuint & out);
-		void stop();
-		void stop(Source * source);
-		void pause();
-		void pause(Source * source);
-		void resume();
-		void resume(Source * source);
-		void rewind();
-		void rewind(Source * source);
-		void softRewind(Source * source);
-		void seek(Source * source, float offset, void * unit);
-		float tell(Source * source, void * unit);
-
-	private:
-
-		/**
-		* Makes the specified OpenAL source available for use.
-		* @param source The OpenAL source.
-		**/
-		void release(Source * source);
-
-		ALuint findi(const Source * source) const;
-
-		bool findSource(Source * source, ALuint & out);
-		bool removeSource(Source * source);
-	}; // Pool
-
-} // openal
-} // audio
-} // love
-
-#endif // LOVE_AUDIO_OPENAL_POOL_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_AUDIO_OPENAL_POOL_H
+#define LOVE_AUDIO_OPENAL_POOL_H
+
+// STD
+#include <queue>
+#include <map>
+#include <iostream>
+#include <cmath>
+
+// LOVE
+#include "common/config.h"
+#include "common/Exception.h"
+#include "thread/threads.h"
+
+// OpenAL
+#ifdef LOVE_MACOSX
+#include <OpenAL/alc.h>
+#include <OpenAL/al.h>
+#else
+#include <AL/alc.h>
+#include <AL/al.h>
+#include <AL/alext.h>
+#endif
+
+namespace love
+{
+namespace audio
+{
+namespace openal
+{
+
+class Source;
+
+class Pool
+{
+public:
+
+	Pool();
+	~Pool();
+
+	/**
+	 * Checks whether an OpenAL source is available.
+	 * @return True if at least one is available, false otherwise.
+	 **/
+	bool isAvailable() const;
+
+	/**
+	 * Checks whether a Source is currently in the playing list.
+	 **/
+	bool isPlaying(Source *s);
+
+	void update();
+
+	int getNumSources() const;
+	int getMaxSources() const;
+
+	bool play(Source *source, ALuint &out);
+	void stop();
+	void stop(Source *source);
+	void pause();
+	void pause(Source *source);
+	void resume();
+	void resume(Source *source);
+	void rewind();
+	void rewind(Source *source);
+	void softRewind(Source *source);
+	void seek(Source *source, float offset, void *unit);
+	float tell(Source *source, void *unit);
+
+private:
+
+	/**
+	 * Makes the specified OpenAL source available for use.
+	 * @param source The OpenAL source.
+	 **/
+	void release(Source *source);
+
+	ALuint findi(const Source *source) const;
+
+	bool findSource(Source *source, ALuint &out);
+	bool removeSource(Source *source);
+	// Number of OpenAL sources.
+	static const int NUM_SOURCES = 64;
+
+	// OpenAL sources
+	ALuint sources[NUM_SOURCES];
+
+	// A queue of available sources.
+	std::queue<ALuint> available;
+
+	// A map of playing sources.
+	std::map<Source *, ALuint> playing;
+
+	// Only one thread can access this object at the same time. This mutex will
+	// make sure of that.
+	thread::Mutex *mutex;
+
+}; // Pool
+
+} // openal
+} // audio
+} // love
+
+#endif // LOVE_AUDIO_OPENAL_POOL_H

+ 724 - 698
src/modules/audio/openal/Source.cpp

@@ -1,698 +1,724 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "Source.h"
-
-#include "Pool.h"
-
-// STD
-#include <iostream>
-#include <float.h>
-
-namespace love
-{
-namespace audio
-{
-namespace openal
-{
-
-	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), paused(false), minVolume(0.0f),
-		maxVolume(1.0f), referenceDistance(1.0f), rolloffFactor(1.0f), maxDistance(FLT_MAX),
-		offsetSamples(0), offsetSeconds(0), decoder(0), toLoop(0)
-	{
-		alGenBuffers(1, buffers);
-		ALenum fmt = getFormat(soundData->getChannels(), soundData->getBits());
-		alBufferData(buffers[0], fmt, soundData->getData(), soundData->getSize(), soundData->getSampleRate());
-
-		static float z[3] = {0, 0, 0};
-
-		setFloatv(position, z);
-		setFloatv(velocity, z);
-		setFloatv(direction, z);
-	}
-
-	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), paused(false), minVolume(0.0f),
-		maxVolume(1.0f), referenceDistance(1.0f), rolloffFactor(1.0f), maxDistance(FLT_MAX),
-		offsetSamples(0), offsetSeconds(0), decoder(decoder), toLoop(0)
-	{
-		decoder->retain();
-		alGenBuffers(MAX_BUFFERS, buffers);
-
-		static float z[3] = {0, 0, 0};
-
-		setFloatv(position, z);
-		setFloatv(velocity, z);
-		setFloatv(direction, z);
-	}
-
-	Source::~Source()
-	{
-		if (valid)
-			pool->stop(this);
-		alDeleteBuffers((type == TYPE_STATIC) ? 1 : MAX_BUFFERS, buffers);
-		if (decoder)
-			decoder->release();
-	}
-
-	love::audio::Source * Source::copy()
-	{
-		return 0;
-	}
-
-	void Source::play()
-	{
-		if (valid && paused)
-		{
-			pool->resume(this);
-			return;
-		}
-
-		valid = pool->play(this, source);
-
-		if (valid)
-			reset(source);
-	}
-
-	void Source::stop()
-	{
-		if (!isStopped())
-		{
-			pool->stop(this);
-			pool->softRewind(this);
-		}
-	}
-
-	void Source::pause()
-	{
-		pool->pause(this);
-	}
-
-	void Source::resume()
-	{
-		pool->resume(this);
-	}
-
-	void Source::rewind()
-	{
-		pool->rewind(this);
-	}
-
-	bool Source::isStopped() const
-	{
-		if (valid)
-		{
-			ALenum state;
-			alGetSourcei(source, AL_SOURCE_STATE, &state);
-			return (state == AL_STOPPED);
-		}
-
-		return true;
-	}
-
-	bool Source::isPaused() const
-	{
-		if (valid)
-		{
-			ALenum state;
-			alGetSourcei(source, AL_SOURCE_STATE, &state);
-			return (state == AL_PAUSED);
-		}
-
-		return false;
-	}
-
-	bool Source::isFinished() const
-	{
-		return type == TYPE_STATIC ? isStopped() : isStopped() && !isLooping() && decoder->isFinished();
-	}
-
-	bool Source::update()
-	{
-		if (!valid)
-			return false;
-		if (type == TYPE_STATIC)
-		{
-			// Looping mode could have changed.
-			alSourcei(source, AL_LOOPING, isLooping() ? AL_TRUE : AL_FALSE);
-			return !isStopped();
-		}
-		else if (type == TYPE_STREAM && (isLooping() || !isFinished()))
-		{
-			// Number of processed buffers.
-			ALint processed = 0;
-
-			alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
-
-			while (processed--)
-			{
-				ALuint buffer;
-
-				float curOffsetSamples, curOffsetSecs;
-
-				alGetSourcef(source, AL_SAMPLE_OFFSET, &curOffsetSamples);
-
-				ALint b;
-				alGetSourcei(source, AL_BUFFER, &b);
-				int freq;
-				alGetBufferi(b, AL_FREQUENCY, &freq);
-				curOffsetSecs = curOffsetSamples / freq;
-
-				// Get a free buffer.
-				alSourceUnqueueBuffers(source, 1, &buffer);
-
-				float newOffsetSamples, newOffsetSecs;
-
-				alGetSourcef(source, AL_SAMPLE_OFFSET, &newOffsetSamples);
-				newOffsetSecs = newOffsetSamples / freq;
-
-				offsetSamples += (curOffsetSamples - newOffsetSamples);
-				offsetSeconds += (curOffsetSecs - newOffsetSecs);
-
-				streamAtomic(buffer, decoder);
-				alSourceQueueBuffers(source, 1, &buffer);
-			}
-			return true;
-		}
-		return false;
-	}
-
-	void Source::setPitch(float pitch)
-	{
-		if (valid)
-			alSourcef(source, AL_PITCH, pitch);
-
-		this->pitch = pitch;
-	}
-
-	float Source::getPitch() const
-	{
-		if (valid)
-		{
-			ALfloat f;
-			alGetSourcef(source, AL_PITCH, &f);
-			return f;
-		}
-
-		// In case the Source isn't playing.
-		return pitch;
-	}
-
-	void Source::setVolume(float volume)
-	{
-		if (valid)
-		{
-			alSourcef(source, AL_GAIN, volume);
-		}
-
-		this->volume = volume;
-	}
-
-	float Source::getVolume() const
-	{
-		if (valid)
-		{
-			ALfloat f;
-			alGetSourcef(source, AL_GAIN, &f);
-			return f;
-		}
-
-		// In case the Source isn't playing.
-		return volume;
-	}
-
-	void Source::seekAtomic(float offset, void * unit)
-	{
-		if (valid)
-		{
-			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);
-					}
-					break;
-				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)
-			{
-				bool waspaused = paused;
-				// Because we still have old data
-				// from before the seek in the buffers
-				// let's empty them.
-				stopAtomic();
-				playAtomic();
-				if (waspaused)
-					pauseAtomic();
-			}
-		}
-	}
-
-	void Source::seek(float offset, Source::Unit unit)
-	{
-		return pool->seek(this, offset, &unit);
-	}
-
-	float Source::tellAtomic(void * unit) const
-	{
-		if (valid)
-		{
-			float offset;
-			switch (*((Source::Unit*) unit)) {
-				case Source::UNIT_SAMPLES:
-					alGetSourcef(source, AL_SAMPLE_OFFSET, &offset);
-					if (type == TYPE_STREAM) offset += offsetSamples;
-					break;
-				case Source::UNIT_SECONDS:
-				default:
-					alGetSourcef(source, AL_SAMPLE_OFFSET, &offset);
-					ALint buffer;
-					alGetSourcei(source, AL_BUFFER, &buffer);
-					int freq;
-					alGetBufferi(buffer, AL_FREQUENCY, &freq);
-					offset /= freq;
-					if (type == TYPE_STREAM) offset += offsetSeconds;
-					break;
-			}
-			return offset;
-		}
-		return 0.0f;
-	}
-
-	float Source::tell(Source::Unit unit)
-	{
-		return pool->tell(this, &unit);
-	}
-
-	void Source::setPosition(float * v)
-	{
-		if (valid)
-			alSourcefv(source, AL_POSITION, v);
-
-		setFloatv(position, v);
-	}
-
-	void Source::getPosition(float * v) const
-	{
-		if (valid)
-			alGetSourcefv(source, AL_POSITION, v);
-		else
-			setFloatv(v, position);
-	}
-
-	void Source::setVelocity(float * v)
-	{
-		if (valid)
-			alSourcefv(source, AL_VELOCITY, v);
-
-		setFloatv(velocity, v);
-	}
-
-	void Source::getVelocity(float * v) const
-	{
-		if (valid)
-			alGetSourcefv(source, AL_VELOCITY, v);
-		else
-			setFloatv(v, velocity);
-	}
-
-	void Source::setDirection(float * v)
-	{
-		if (valid)
-			alSourcefv(source, AL_DIRECTION, v);
-		else
-			setFloatv(direction, v);
-	}
-
-	void Source::getDirection(float * v) const
-	{
-		if (valid)
-			alGetSourcefv(source, AL_DIRECTION, v);
-		else
-			setFloatv(v, direction);
-	}
-
-	void Source::setLooping(bool looping)
-	{
-		if (valid && type == TYPE_STATIC)
-			alSourcei(source, AL_LOOPING, looping ? AL_TRUE : AL_FALSE);
-
-		this->looping = looping;
-	}
-
-	bool Source::isLooping() const
-	{
-		return looping;
-	}
-
-	void Source::playAtomic()
-	{
-		if (type == TYPE_STATIC)
-		{
-			alSourcei(source, AL_BUFFER, buffers[0]);
-		}
-		else if (type == TYPE_STREAM)
-		{
-			int usedBuffers = 0;
-
-			for (unsigned int i = 0; i < MAX_BUFFERS; i++)
-			{
-				streamAtomic(buffers[i], decoder);
-				++usedBuffers;
-				if (decoder->isFinished())
-					break;
-			}
-
-			if (usedBuffers > 0)
-				alSourceQueueBuffers(source, usedBuffers, buffers);
-		}
-
-		// Set these properties. These may have changed while we've
-		// been without an AL source.
-		alSourcef(source, AL_PITCH, pitch);
-		alSourcef(source, AL_GAIN, volume);
-		alSourcef(source, AL_MIN_GAIN, minVolume);
-		alSourcef(source, AL_MAX_GAIN, maxVolume);
-		alSourcef(source, AL_REFERENCE_DISTANCE, referenceDistance);
-		alSourcef(source, AL_ROLLOFF_FACTOR, rolloffFactor);
-		alSourcef(source, AL_MAX_DISTANCE, maxDistance);
-
-		alSourcePlay(source);
-
-		valid = true; //if it fails it will be set to false again
-		//but this prevents a horrible, horrible bug
-	}
-
-	void Source::stopAtomic()
-	{
-		if (valid)
-		{
-			if (type == TYPE_STATIC)
-			{
-				alSourceStop(source);
-			}
-			else if (type == TYPE_STREAM)
-			{
-				alSourceStop(source);
-				int queued = 0;
-				alGetSourcei(source, AL_BUFFERS_QUEUED, &queued);
-
-				while (queued--)
-				{
-					ALuint buffer;
-					alSourceUnqueueBuffers(source, 1, &buffer);
-				}
-			}
-			alSourcei(source, AL_BUFFER, AL_NONE);
-		}
-		toLoop = 0;
-		valid = false;
-	}
-
-	void Source::pauseAtomic()
-	{
-		if (valid)
-		{
-			alSourcePause(source);
-			paused = true;
-		}
-	}
-
-	void Source::resumeAtomic()
-	{
-		if (valid && paused)
-		{
-			alSourcePlay(source);
-			paused = false;
-		}
-	}
-
-	void Source::rewindAtomic()
-	{
-		if (valid && type == TYPE_STATIC)
-		{
-			alSourceRewind(source);
-			if (!paused)
-				alSourcePlay(source);
-		}
-		else if (valid && type == TYPE_STREAM)
-		{
-			bool waspaused = paused;
-			decoder->rewind();
-			// Because we still have old data
-			// from before the seek in the buffers
-			// let's empty them.
-			stopAtomic();
-			playAtomic();
-			if (waspaused)
-				pauseAtomic();
-			offsetSamples = 0;
-			offsetSeconds = 0;
-		}
-		else if (type == TYPE_STREAM)
-		{
-			decoder->rewind();
-			offsetSamples = 0;
-			offsetSeconds = 0;
-		}
-	}
-
-	void Source::reset(ALenum source)
-	{
-		alSourcefv(source, AL_POSITION, position);
-		alSourcefv(source, AL_VELOCITY, velocity);
-		alSourcefv(source, AL_DIRECTION, direction);
-		alSourcef(source, AL_PITCH, pitch);
-		alSourcef(source, AL_GAIN, volume);
-		alSourcef(source, AL_MIN_GAIN, minVolume);
-		alSourcef(source, AL_MAX_GAIN, maxVolume);
-		alSourcef(source, AL_REFERENCE_DISTANCE, referenceDistance);
-		alSourcef(source, AL_ROLLOFF_FACTOR, rolloffFactor);
-		alSourcef(source, AL_MAX_DISTANCE, maxDistance);
-	}
-
-	void Source::setFloatv(float * dst, const float * src) const
-	{
-		dst[0] = src[0];
-		dst[1] = src[1];
-		dst[2] = src[2];
-	}
-
-	ALenum Source::getFormat(int channels, int bits) const
-	{
-		if (channels == 1 && bits == 8)
-			return AL_FORMAT_MONO8;
-		else if (channels == 1 && bits == 16)
-			return AL_FORMAT_MONO16;
-		else if (channels == 2 && bits == 8)
-			return AL_FORMAT_STEREO8;
-		else if (channels == 2 && bits == 16)
-			return AL_FORMAT_STEREO16;
-		else
-			return 0;
-	}
-
-	int Source::streamAtomic(ALuint buffer, love::sound::Decoder * d)
-	{
-		// Get more sound data.
-		int decoded = d->decode();
-
-		int fmt = getFormat(d->getChannels(), d->getBits());
-
-		if (fmt != 0)
-			alBufferData(buffer, fmt, d->getBuffer(), decoded, d->getSampleRate());
-
-		if (decoder->isFinished() && isLooping())
-		{
-			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;
-	}
-
-	bool Source::isStatic() const
-	{
-		return (type == TYPE_STATIC);
-	}
-	
-	void Source::setMinVolume(float volume)
-	{
-		if (valid)
-		{
-			alSourcef(source, AL_MIN_GAIN, volume);
-		}
-
-		this->minVolume = volume;
-	}
-
-	float Source::getMinVolume() const
-	{
-		if (valid)
-		{
-			ALfloat f;
-			alGetSourcef(source, AL_MIN_GAIN, &f);
-			return f;
-		}
-
-		// In case the Source isn't playing.
-		return this->minVolume;
-	}
-
-	void Source::setMaxVolume(float volume)
-	{
-		if (valid)
-		{
-			alSourcef(source, AL_MAX_GAIN, volume);
-		}
-
-		this->maxVolume = volume;
-	}
-
-	float Source::getMaxVolume() const
-	{
-		if (valid)
-		{
-			ALfloat f;
-			alGetSourcef(source, AL_MAX_GAIN, &f);
-			return f;
-		}
-
-		// In case the Source isn't playing.
-		return this->maxVolume;
-	}
-
-	void Source::setReferenceDistance(float distance)
-	{
-		if (valid)
-		{
-			alSourcef(source, AL_REFERENCE_DISTANCE, distance);
-		}
-
-		this->referenceDistance = distance;
-	}
-
-	float Source::getReferenceDistance() const
-	{
-		if (valid)
-		{
-			ALfloat f;
-			alGetSourcef(source, AL_REFERENCE_DISTANCE, &f);
-			return f;
-		}
-
-		// In case the Source isn't playing.
-		return this->referenceDistance;
-	}
-
-	void Source::setRolloffFactor(float factor)
-	{
-		if (valid)
-		{
-			alSourcef(source, AL_ROLLOFF_FACTOR, factor);
-		}
-
-		this->rolloffFactor = factor;
-	}
-
-	float Source::getRolloffFactor() const
-	{
-		if (valid)
-		{
-			ALfloat f;
-			alGetSourcef(source, AL_ROLLOFF_FACTOR, &f);
-			return f;
-		}
-
-		// In case the Source isn't playing.
-		return this->rolloffFactor;
-	}
-
-	void Source::setMaxDistance(float distance)
-	{
-		if (valid)
-		{
-			alSourcef(source, AL_MAX_DISTANCE, distance);
-		}
-
-		this->maxDistance = distance;
-	}
-
-	float Source::getMaxDistance() const
-	{
-		if (valid)
-		{
-			ALfloat f;
-			alGetSourcef(source, AL_MAX_DISTANCE, &f);
-			return f;
-		}
-
-		// In case the Source isn't playing.
-		return this->maxDistance;
-	}
-
-} // openal
-} // audio
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "Source.h"
+
+#include "Pool.h"
+
+// STD
+#include <iostream>
+#include <float.h>
+
+namespace love
+{
+namespace audio
+{
+namespace openal
+{
+
+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)
+	, paused(false)
+	, minVolume(0.0f)
+	, maxVolume(1.0f)
+	, referenceDistance(1.0f)
+	, rolloffFactor(1.0f)
+	, maxDistance(FLT_MAX)
+	, offsetSamples(0)
+	, offsetSeconds(0)
+	, decoder(0)
+	, toLoop(0)
+{
+	alGenBuffers(1, buffers);
+	ALenum fmt = getFormat(soundData->getChannels(), soundData->getBits());
+	alBufferData(buffers[0], fmt, soundData->getData(), soundData->getSize(), soundData->getSampleRate());
+
+	static float z[3] = {0, 0, 0};
+
+	setFloatv(position, z);
+	setFloatv(velocity, z);
+	setFloatv(direction, z);
+}
+
+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)
+	, paused(false)
+	, minVolume(0.0f)
+	, maxVolume(1.0f)
+	, referenceDistance(1.0f)
+	, rolloffFactor(1.0f)
+	, maxDistance(FLT_MAX)
+	, offsetSamples(0)
+	, offsetSeconds(0)
+	, decoder(decoder)
+	, toLoop(0)
+{
+	decoder->retain();
+	alGenBuffers(MAX_BUFFERS, buffers);
+
+	static float z[3] = {0, 0, 0};
+
+	setFloatv(position, z);
+	setFloatv(velocity, z);
+	setFloatv(direction, z);
+}
+
+Source::~Source()
+{
+	if (valid)
+		pool->stop(this);
+	alDeleteBuffers((type == TYPE_STATIC) ? 1 : MAX_BUFFERS, buffers);
+	if (decoder)
+		decoder->release();
+}
+
+love::audio::Source *Source::copy()
+{
+	return 0;
+}
+
+void Source::play()
+{
+	if (valid && paused)
+	{
+		pool->resume(this);
+		return;
+	}
+
+	valid = pool->play(this, source);
+
+	if (valid)
+		reset(source);
+}
+
+void Source::stop()
+{
+	if (!isStopped())
+	{
+		pool->stop(this);
+		pool->softRewind(this);
+	}
+}
+
+void Source::pause()
+{
+	pool->pause(this);
+}
+
+void Source::resume()
+{
+	pool->resume(this);
+}
+
+void Source::rewind()
+{
+	pool->rewind(this);
+}
+
+bool Source::isStopped() const
+{
+	if (valid)
+	{
+		ALenum state;
+		alGetSourcei(source, AL_SOURCE_STATE, &state);
+		return (state == AL_STOPPED);
+	}
+
+	return true;
+}
+
+bool Source::isPaused() const
+{
+	if (valid)
+	{
+		ALenum state;
+		alGetSourcei(source, AL_SOURCE_STATE, &state);
+		return (state == AL_PAUSED);
+	}
+
+	return false;
+}
+
+bool Source::isFinished() const
+{
+	return type == TYPE_STATIC ? isStopped() : isStopped() && !isLooping() && decoder->isFinished();
+}
+
+bool Source::update()
+{
+	if (!valid)
+		return false;
+	if (type == TYPE_STATIC)
+	{
+		// Looping mode could have changed.
+		alSourcei(source, AL_LOOPING, isLooping() ? AL_TRUE : AL_FALSE);
+		return !isStopped();
+	}
+	else if (type == TYPE_STREAM && (isLooping() || !isFinished()))
+	{
+		// Number of processed buffers.
+		ALint processed = 0;
+
+		alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
+
+		while (processed--)
+		{
+			ALuint buffer;
+
+			float curOffsetSamples, curOffsetSecs;
+
+			alGetSourcef(source, AL_SAMPLE_OFFSET, &curOffsetSamples);
+
+			ALint b;
+			alGetSourcei(source, AL_BUFFER, &b);
+			int freq;
+			alGetBufferi(b, AL_FREQUENCY, &freq);
+			curOffsetSecs = curOffsetSamples / freq;
+
+			// Get a free buffer.
+			alSourceUnqueueBuffers(source, 1, &buffer);
+
+			float newOffsetSamples, newOffsetSecs;
+
+			alGetSourcef(source, AL_SAMPLE_OFFSET, &newOffsetSamples);
+			newOffsetSecs = newOffsetSamples / freq;
+
+			offsetSamples += (curOffsetSamples - newOffsetSamples);
+			offsetSeconds += (curOffsetSecs - newOffsetSecs);
+
+			streamAtomic(buffer, decoder);
+			alSourceQueueBuffers(source, 1, &buffer);
+		}
+		return true;
+	}
+	return false;
+}
+
+void Source::setPitch(float pitch)
+{
+	if (valid)
+		alSourcef(source, AL_PITCH, pitch);
+
+	this->pitch = pitch;
+}
+
+float Source::getPitch() const
+{
+	if (valid)
+	{
+		ALfloat f;
+		alGetSourcef(source, AL_PITCH, &f);
+		return f;
+	}
+
+	// In case the Source isn't playing.
+	return pitch;
+}
+
+void Source::setVolume(float volume)
+{
+	if (valid)
+	{
+		alSourcef(source, AL_GAIN, volume);
+	}
+
+	this->volume = volume;
+}
+
+float Source::getVolume() const
+{
+	if (valid)
+	{
+		ALfloat f;
+		alGetSourcef(source, AL_GAIN, &f);
+		return f;
+	}
+
+	// In case the Source isn't playing.
+	return volume;
+}
+
+void Source::seekAtomic(float offset, void *unit)
+{
+	if (valid)
+	{
+		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);
+			}
+			break;
+		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)
+		{
+			bool waspaused = paused;
+			// Because we still have old data
+			// from before the seek in the buffers
+			// let's empty them.
+			stopAtomic();
+			playAtomic();
+			if (waspaused)
+				pauseAtomic();
+		}
+	}
+}
+
+void Source::seek(float offset, Source::Unit unit)
+{
+	return pool->seek(this, offset, &unit);
+}
+
+float Source::tellAtomic(void *unit) const
+{
+	if (valid)
+	{
+		float offset;
+		switch (*((Source::Unit *) unit))
+		{
+		case Source::UNIT_SAMPLES:
+			alGetSourcef(source, AL_SAMPLE_OFFSET, &offset);
+			if (type == TYPE_STREAM) offset += offsetSamples;
+			break;
+		case Source::UNIT_SECONDS:
+		default:
+			alGetSourcef(source, AL_SAMPLE_OFFSET, &offset);
+			ALint buffer;
+			alGetSourcei(source, AL_BUFFER, &buffer);
+			int freq;
+			alGetBufferi(buffer, AL_FREQUENCY, &freq);
+			offset /= freq;
+			if (type == TYPE_STREAM) offset += offsetSeconds;
+			break;
+		}
+		return offset;
+	}
+	return 0.0f;
+}
+
+float Source::tell(Source::Unit unit)
+{
+	return pool->tell(this, &unit);
+}
+
+void Source::setPosition(float *v)
+{
+	if (valid)
+		alSourcefv(source, AL_POSITION, v);
+
+	setFloatv(position, v);
+}
+
+void Source::getPosition(float *v) const
+{
+	if (valid)
+		alGetSourcefv(source, AL_POSITION, v);
+	else
+		setFloatv(v, position);
+}
+
+void Source::setVelocity(float *v)
+{
+	if (valid)
+		alSourcefv(source, AL_VELOCITY, v);
+
+	setFloatv(velocity, v);
+}
+
+void Source::getVelocity(float *v) const
+{
+	if (valid)
+		alGetSourcefv(source, AL_VELOCITY, v);
+	else
+		setFloatv(v, velocity);
+}
+
+void Source::setDirection(float *v)
+{
+	if (valid)
+		alSourcefv(source, AL_DIRECTION, v);
+	else
+		setFloatv(direction, v);
+}
+
+void Source::getDirection(float *v) const
+{
+	if (valid)
+		alGetSourcefv(source, AL_DIRECTION, v);
+	else
+		setFloatv(v, direction);
+}
+
+void Source::setLooping(bool looping)
+{
+	if (valid && type == TYPE_STATIC)
+		alSourcei(source, AL_LOOPING, looping ? AL_TRUE : AL_FALSE);
+
+	this->looping = looping;
+}
+
+bool Source::isLooping() const
+{
+	return looping;
+}
+
+void Source::playAtomic()
+{
+	if (type == TYPE_STATIC)
+	{
+		alSourcei(source, AL_BUFFER, buffers[0]);
+	}
+	else if (type == TYPE_STREAM)
+	{
+		int usedBuffers = 0;
+
+		for (unsigned int i = 0; i < MAX_BUFFERS; i++)
+		{
+			streamAtomic(buffers[i], decoder);
+			++usedBuffers;
+			if (decoder->isFinished())
+				break;
+		}
+
+		if (usedBuffers > 0)
+			alSourceQueueBuffers(source, usedBuffers, buffers);
+	}
+
+	// Set these properties. These may have changed while we've
+	// been without an AL source.
+	alSourcef(source, AL_PITCH, pitch);
+	alSourcef(source, AL_GAIN, volume);
+	alSourcef(source, AL_MIN_GAIN, minVolume);
+	alSourcef(source, AL_MAX_GAIN, maxVolume);
+	alSourcef(source, AL_REFERENCE_DISTANCE, referenceDistance);
+	alSourcef(source, AL_ROLLOFF_FACTOR, rolloffFactor);
+	alSourcef(source, AL_MAX_DISTANCE, maxDistance);
+
+	alSourcePlay(source);
+
+	valid = true; //if it fails it will be set to false again
+	//but this prevents a horrible, horrible bug
+}
+
+void Source::stopAtomic()
+{
+	if (valid)
+	{
+		if (type == TYPE_STATIC)
+		{
+			alSourceStop(source);
+		}
+		else if (type == TYPE_STREAM)
+		{
+			alSourceStop(source);
+			int queued = 0;
+			alGetSourcei(source, AL_BUFFERS_QUEUED, &queued);
+
+			while (queued--)
+			{
+				ALuint buffer;
+				alSourceUnqueueBuffers(source, 1, &buffer);
+			}
+		}
+		alSourcei(source, AL_BUFFER, AL_NONE);
+	}
+	toLoop = 0;
+	valid = false;
+}
+
+void Source::pauseAtomic()
+{
+	if (valid)
+	{
+		alSourcePause(source);
+		paused = true;
+	}
+}
+
+void Source::resumeAtomic()
+{
+	if (valid && paused)
+	{
+		alSourcePlay(source);
+		paused = false;
+	}
+}
+
+void Source::rewindAtomic()
+{
+	if (valid && type == TYPE_STATIC)
+	{
+		alSourceRewind(source);
+		if (!paused)
+			alSourcePlay(source);
+	}
+	else if (valid && type == TYPE_STREAM)
+	{
+		bool waspaused = paused;
+		decoder->rewind();
+		// Because we still have old data
+		// from before the seek in the buffers
+		// let's empty them.
+		stopAtomic();
+		playAtomic();
+		if (waspaused)
+			pauseAtomic();
+		offsetSamples = 0;
+		offsetSeconds = 0;
+	}
+	else if (type == TYPE_STREAM)
+	{
+		decoder->rewind();
+		offsetSamples = 0;
+		offsetSeconds = 0;
+	}
+}
+
+void Source::reset(ALenum source)
+{
+	alSourcefv(source, AL_POSITION, position);
+	alSourcefv(source, AL_VELOCITY, velocity);
+	alSourcefv(source, AL_DIRECTION, direction);
+	alSourcef(source, AL_PITCH, pitch);
+	alSourcef(source, AL_GAIN, volume);
+	alSourcef(source, AL_MIN_GAIN, minVolume);
+	alSourcef(source, AL_MAX_GAIN, maxVolume);
+	alSourcef(source, AL_REFERENCE_DISTANCE, referenceDistance);
+	alSourcef(source, AL_ROLLOFF_FACTOR, rolloffFactor);
+	alSourcef(source, AL_MAX_DISTANCE, maxDistance);
+}
+
+void Source::setFloatv(float *dst, const float *src) const
+{
+	dst[0] = src[0];
+	dst[1] = src[1];
+	dst[2] = src[2];
+}
+
+ALenum Source::getFormat(int channels, int bits) const
+{
+	if (channels == 1 && bits == 8)
+		return AL_FORMAT_MONO8;
+	else if (channels == 1 && bits == 16)
+		return AL_FORMAT_MONO16;
+	else if (channels == 2 && bits == 8)
+		return AL_FORMAT_STEREO8;
+	else if (channels == 2 && bits == 16)
+		return AL_FORMAT_STEREO16;
+	else
+		return 0;
+}
+
+int Source::streamAtomic(ALuint buffer, love::sound::Decoder *d)
+{
+	// Get more sound data.
+	int decoded = d->decode();
+
+	int fmt = getFormat(d->getChannels(), d->getBits());
+
+	if (fmt != 0)
+		alBufferData(buffer, fmt, d->getBuffer(), decoded, d->getSampleRate());
+
+	if (decoder->isFinished() && isLooping())
+	{
+		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;
+}
+
+bool Source::isStatic() const
+{
+	return (type == TYPE_STATIC);
+}
+
+void Source::setMinVolume(float volume)
+{
+	if (valid)
+	{
+		alSourcef(source, AL_MIN_GAIN, volume);
+	}
+
+	this->minVolume = volume;
+}
+
+float Source::getMinVolume() const
+{
+	if (valid)
+	{
+		ALfloat f;
+		alGetSourcef(source, AL_MIN_GAIN, &f);
+		return f;
+	}
+
+	// In case the Source isn't playing.
+	return this->minVolume;
+}
+
+void Source::setMaxVolume(float volume)
+{
+	if (valid)
+	{
+		alSourcef(source, AL_MAX_GAIN, volume);
+	}
+
+	this->maxVolume = volume;
+}
+
+float Source::getMaxVolume() const
+{
+	if (valid)
+	{
+		ALfloat f;
+		alGetSourcef(source, AL_MAX_GAIN, &f);
+		return f;
+	}
+
+	// In case the Source isn't playing.
+	return this->maxVolume;
+}
+
+void Source::setReferenceDistance(float distance)
+{
+	if (valid)
+	{
+		alSourcef(source, AL_REFERENCE_DISTANCE, distance);
+	}
+
+	this->referenceDistance = distance;
+}
+
+float Source::getReferenceDistance() const
+{
+	if (valid)
+	{
+		ALfloat f;
+		alGetSourcef(source, AL_REFERENCE_DISTANCE, &f);
+		return f;
+	}
+
+	// In case the Source isn't playing.
+	return this->referenceDistance;
+}
+
+void Source::setRolloffFactor(float factor)
+{
+	if (valid)
+	{
+		alSourcef(source, AL_ROLLOFF_FACTOR, factor);
+	}
+
+	this->rolloffFactor = factor;
+}
+
+float Source::getRolloffFactor() const
+{
+	if (valid)
+	{
+		ALfloat f;
+		alGetSourcef(source, AL_ROLLOFF_FACTOR, &f);
+		return f;
+	}
+
+	// In case the Source isn't playing.
+	return this->rolloffFactor;
+}
+
+void Source::setMaxDistance(float distance)
+{
+	if (valid)
+	{
+		alSourcef(source, AL_MAX_DISTANCE, distance);
+	}
+
+	this->maxDistance = distance;
+}
+
+float Source::getMaxDistance() const
+{
+	if (valid)
+	{
+		ALfloat f;
+		alGetSourcef(source, AL_MAX_DISTANCE, &f);
+		return f;
+	}
+
+	// In case the Source isn't playing.
+	return this->maxDistance;
+}
+
+} // openal
+} // audio
+} // love

+ 150 - 151
src/modules/audio/openal/Source.h

@@ -1,151 +1,150 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_AUDIO_OPENAL_SOURCE_H
-#define LOVE_AUDIO_OPENAL_SOURCE_H
-
-// LOVE
-#include <common/config.h>
-#include <common/Object.h>
-#include <audio/Source.h>
-#include <sound/SoundData.h>
-#include <sound/Decoder.h>
-
-// OpenAL
-#ifdef LOVE_MACOSX
-#include <OpenAL/alc.h>
-#include <OpenAL/al.h>
-#else
-#include <AL/alc.h>
-#include <AL/al.h>
-#endif
-
-namespace love
-{
-namespace audio
-{
-namespace openal
-{
-	class Audio;
-	class Pool;
-
-	class Source : public love::audio::Source
-	{
-	private:
-
-		Pool * pool;
-		ALuint source;
-		bool valid;
-		static const unsigned int MAX_BUFFERS = 32;
-		ALuint buffers[MAX_BUFFERS];
-
-		float pitch;
-		float volume;
-		float position[3];
-		float velocity[3];
-		float direction[3];
-		bool looping;
-		bool paused;
-		float minVolume;
-		float maxVolume;
-		float referenceDistance;
-		float rolloffFactor;
-		float maxDistance;
-
-		float offsetSamples;
-		float offsetSeconds;
-
-		love::sound::Decoder * decoder;
-
-		unsigned int toLoop;
-
-	public:
-		Source(Pool * pool, love::sound::SoundData * soundData);
-		Source(Pool * pool, love::sound::Decoder * decoder);
-		virtual ~Source();
-
-		virtual love::audio::Source * copy();
-		virtual void play();
-		virtual void stop();
-		virtual void pause();
-		virtual void resume();
-		virtual void rewind();
-		virtual bool isStopped() const;
-		virtual bool isPaused() const;
-		virtual bool isFinished() const;
-		virtual bool update();
-		virtual void setPitch(float pitch);
-		virtual float getPitch() const;
-		virtual void setVolume(float volume);
-		virtual float getVolume() const;
-		virtual void seekAtomic(float offset, void * unit);
-		virtual void seek(float offset, Unit unit);
-		virtual float tellAtomic(void * unit) const;
-		virtual float tell(Unit unit);
-		virtual void setPosition(float * v);
-		virtual void getPosition(float * v) const;
-		virtual void setVelocity(float * v);
-		virtual void getVelocity(float * v) const;
-		virtual void setDirection(float * v);
-		virtual void getDirection(float * v) const;
-		void setLooping(bool looping);
-		bool isLooping() const;
-		bool isStatic() const;
-		virtual void setMinVolume(float volume);
-		virtual float getMinVolume() const;
-		virtual void setMaxVolume(float volume);
-		virtual float getMaxVolume() const;
-		virtual void setReferenceDistance(float distance);
-		virtual float getReferenceDistance() const;
-		virtual void setRolloffFactor(float factor);
-		virtual float getRolloffFactor() const;
-		virtual void setMaxDistance(float distance);
-		virtual float getMaxDistance() const;
-
-		void playAtomic();
-		void stopAtomic();
-		void pauseAtomic();
-		void resumeAtomic();
-		void rewindAtomic();
-
-	private:
-
-		void reset(ALenum source);
-
-		void setFloatv(float * dst, const float * src) const;
-
-		/**
-		* Gets the OpenAL format identifier based on number of
-		* channels and bits.
-		* @param channels Either 1 (mono) or 2 (stereo).
-		* @param bits Either 8-bit samples, or 16-bit samples.
-		* @return One of AL_FORMAT_*, or 0 if unsupported format.
-		**/
-		ALenum getFormat(int channels, int bits) const;
-
-		int streamAtomic(ALuint buffer, love::sound::Decoder * d);
-
-	}; // Source
-
-} // openal
-} // audio
-} // love
-
-#endif // LOVE_AUDIO_OPENAL_SOURCE_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_AUDIO_OPENAL_SOURCE_H
+#define LOVE_AUDIO_OPENAL_SOURCE_H
+
+// LOVE
+#include "common/config.h"
+#include "common/Object.h"
+#include "audio/Source.h"
+#include "sound/SoundData.h"
+#include "sound/Decoder.h"
+
+// OpenAL
+#ifdef LOVE_MACOSX
+#include <OpenAL/alc.h>
+#include <OpenAL/al.h>
+#else
+#include <AL/alc.h>
+#include <AL/al.h>
+#endif
+
+namespace love
+{
+namespace audio
+{
+namespace openal
+{
+
+class Audio;
+class Pool;
+
+class Source : public love::audio::Source
+{
+public:
+	Source(Pool *pool, love::sound::SoundData *soundData);
+	Source(Pool *pool, love::sound::Decoder *decoder);
+	virtual ~Source();
+
+	virtual love::audio::Source *copy();
+	virtual void play();
+	virtual void stop();
+	virtual void pause();
+	virtual void resume();
+	virtual void rewind();
+	virtual bool isStopped() const;
+	virtual bool isPaused() const;
+	virtual bool isFinished() const;
+	virtual bool update();
+	virtual void setPitch(float pitch);
+	virtual float getPitch() const;
+	virtual void setVolume(float volume);
+	virtual float getVolume() const;
+	virtual void seekAtomic(float offset, void *unit);
+	virtual void seek(float offset, Unit unit);
+	virtual float tellAtomic(void *unit) const;
+	virtual float tell(Unit unit);
+	virtual void setPosition(float *v);
+	virtual void getPosition(float *v) const;
+	virtual void setVelocity(float *v);
+	virtual void getVelocity(float *v) const;
+	virtual void setDirection(float *v);
+	virtual void getDirection(float *v) const;
+	void setLooping(bool looping);
+	bool isLooping() const;
+	bool isStatic() const;
+	virtual void setMinVolume(float volume);
+	virtual float getMinVolume() const;
+	virtual void setMaxVolume(float volume);
+	virtual float getMaxVolume() const;
+	virtual void setReferenceDistance(float distance);
+	virtual float getReferenceDistance() const;
+	virtual void setRolloffFactor(float factor);
+	virtual float getRolloffFactor() const;
+	virtual void setMaxDistance(float distance);
+	virtual float getMaxDistance() const;
+
+	void playAtomic();
+	void stopAtomic();
+	void pauseAtomic();
+	void resumeAtomic();
+	void rewindAtomic();
+
+private:
+
+	void reset(ALenum source);
+
+	void setFloatv(float *dst, const float *src) const;
+
+	/**
+	 * Gets the OpenAL format identifier based on number of
+	 * channels and bits.
+	 * @param channels Either 1 (mono) or 2 (stereo).
+	 * @param bits Either 8-bit samples, or 16-bit samples.
+	 * @return One of AL_FORMAT_*, or 0 if unsupported format.
+	 **/
+	ALenum getFormat(int channels, int bits) const;
+
+	int streamAtomic(ALuint buffer, love::sound::Decoder *d);
+
+	Pool *pool;
+	ALuint source;
+	bool valid;
+	static const unsigned int MAX_BUFFERS = 32;
+	ALuint buffers[MAX_BUFFERS];
+
+	float pitch;
+	float volume;
+	float position[3];
+	float velocity[3];
+	float direction[3];
+	bool looping;
+	bool paused;
+	float minVolume;
+	float maxVolume;
+	float referenceDistance;
+	float rolloffFactor;
+	float maxDistance;
+
+	float offsetSamples;
+	float offsetSeconds;
+
+	love::sound::Decoder *decoder;
+
+	unsigned int toLoop;
+
+}; // Source
+
+} // openal
+} // audio
+} // love
+
+#endif // LOVE_AUDIO_OPENAL_SOURCE_H

+ 343 - 339
src/modules/audio/wrap_Audio.cpp

@@ -1,339 +1,343 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-// LOVE
-#include "wrap_Audio.h"
-
-#include "openal/Audio.h"
-#include "null/Audio.h"
-
-#include <scripts/audio.lua.h>
-
-#include <common/runtime.h>
-
-namespace love
-{
-namespace audio
-{
-	static Audio * instance = 0;
-
-	int w_getNumSources(lua_State * L)
-	{
-		lua_pushinteger(L, instance->getNumSources());
-		return 1;
-	}
-
-	int w_newSource1(lua_State * L)
-	{
-		Source * t = 0;
-
-		if (luax_istype(L, 1, SOUND_SOUND_DATA_T))
-			t = instance->newSource(luax_totype<love::sound::SoundData>(L, 1, "SoundData", SOUND_SOUND_DATA_T));
-		else if (luax_istype(L, 1, SOUND_DECODER_T))
-			t = instance->newSource(luax_totype<love::sound::Decoder>(L, 1, "Decoder", SOUND_DECODER_T));
-
-		if (t)
-		{
-			luax_newtype(L, "Source", AUDIO_SOURCE_T, (void*)t);
-			return 1;
-		}
-		else
-			return luaL_error(L, "No matching overload");
-
-		return 0;
-	}
-
-	int w_play(lua_State * L)
-	{
-		Source * s = luax_checksource(L, 1);
-		instance->play(s);
-		return 0;
-	}
-
-	int w_stop(lua_State * L)
-	{
-		if (lua_gettop(L) == 0)
-		{
-			instance->stop();
-		}
-		else
-		{
-			Source * s = luax_checksource(L, 1);
-			s->stop();
-		}
-		return 0;
-	}
-
-	int w_pause(lua_State * L)
-	{
-		if (lua_gettop(L) == 0)
-		{
-			instance->pause();
-		}
-		else
-		{
-			Source * s = luax_checksource(L, 1);
-			s->pause();
-		}
-
-		return 0;
-	}
-
-	int w_resume(lua_State * L)
-	{
-		if (lua_gettop(L) == 0)
-		{
-			instance->resume();
-		}
-		else
-		{
-			Source * s = luax_checksource(L, 1);
-			s->resume();
-		}
-		return 0;
-	}
-
-	int w_rewind(lua_State * L)
-	{
-		if (lua_gettop(L) == 0)
-		{
-			instance->rewind();
-		}
-		else
-		{
-			Source * s = luax_checksource(L, 1);
-			s->rewind();
-		}
-		return 0;
-	}
-
-	int w_setVolume(lua_State * L)
-	{
-		float v = (float)luaL_checknumber(L, 1);
-		instance->setVolume(v);
-		return 0;
-	}
-
-	int w_getVolume(lua_State * L)
-	{
-		lua_pushnumber(L, instance->getVolume());
-		return 1;
-	}
-
-	int w_setPosition(lua_State * L)
-	{
-		float v[3];
-		v[0] = (float)luaL_checknumber(L, 1);
-		v[1] = (float)luaL_checknumber(L, 2);
-		v[2] = (float)luaL_optnumber(L, 3, 0);
-		instance->setPosition(v);
-		return 0;
-	}
-
-	int w_getPosition(lua_State * L)
-	{
-		float v[3];
-		instance->getPosition(v);
-		lua_pushnumber(L, v[0]);
-		lua_pushnumber(L, v[1]);
-		lua_pushnumber(L, v[2]);
-		return 3;
-	}
-
-	int w_setOrientation(lua_State * L)
-	{
-		float v[6];
-		v[0] = (float)luaL_checknumber(L, 1);
-		v[1] = (float)luaL_checknumber(L, 2);
-		v[2] = (float)luaL_checknumber(L, 3);
-		v[3] = (float)luaL_checknumber(L, 4);
-		v[4] = (float)luaL_checknumber(L, 5);
-		v[5] = (float)luaL_checknumber(L, 6);
-		instance->setOrientation(v);
-		return 0;
-	}
-
-	int w_getOrientation(lua_State * L)
-	{
-		float v[6];
-		instance->getOrientation(v);
-		lua_pushnumber(L, v[0]);
-		lua_pushnumber(L, v[1]);
-		lua_pushnumber(L, v[2]);
-		lua_pushnumber(L, v[3]);
-		lua_pushnumber(L, v[4]);
-		lua_pushnumber(L, v[5]);
-		return 6;
-	}
-
-	int w_setVelocity(lua_State * L)
-	{
-		float v[3];
-		v[0] = (float)luaL_checknumber(L, 1);
-		v[1] = (float)luaL_checknumber(L, 2);
-		v[2] = (float)luaL_optnumber(L, 3, 0);
-		instance->setVelocity(v);
-		return 0;
-	}
-
-	int w_getVelocity(lua_State * L)
-	{
-		float v[3];
-		instance->getVelocity(v);
-		lua_pushnumber(L, v[0]);
-		lua_pushnumber(L, v[1]);
-		lua_pushnumber(L, v[2]);
-		return 3;
-	}
-
-	int w_record(lua_State *)
-	{
-		instance->record();
-		return 0;
-	}
-
-	int w_getRecordedData(lua_State * L)
-	{
-		love::sound::SoundData * sd = instance->getRecordedData();
-		if (!sd)
-			lua_pushnil(L);
-		else
-			luax_newtype(L, "SoundData", SOUND_SOUND_DATA_T, (void*)sd);
-		return 1;
-	}
-
-	int w_stopRecording(lua_State * L)
-	{
-		if (luax_optboolean(L, 1, true))
-		{
-			love::sound::SoundData * sd = instance->stopRecording(true);
-			if (!sd) lua_pushnil(L);
-			else luax_newtype(L, "SoundData", SOUND_SOUND_DATA_T, (void*)sd);
-			return 1;
-		}
-		instance->stopRecording(false);
-		return 0;
-	}
-
-	int w_canRecord(lua_State * L) {
-		luax_pushboolean(L, instance->canRecord());
-		return 1;
-	}
-	
-	int w_setDistanceModel(lua_State * L)
-	{
-		const char *modelStr = luaL_checkstring(L, 1);
-		Audio::DistanceModel distanceModel;
-		if (!Audio::getConstant(modelStr, distanceModel))
-			return luaL_error(L, "Invalid distance model: %s", modelStr);
-		instance->setDistanceModel(distanceModel);
-		return 0;
-	}
-
-	int w_getDistanceModel(lua_State * L)
-	{
-		Audio::DistanceModel distanceModel = instance->getDistanceModel();
-		const char *modelStr;
-		if (!Audio::getConstant(distanceModel, modelStr))
-			return 0;
-		lua_pushstring(L, modelStr);
-		return 1;
-	}
-
-	// List of functions to wrap.
-	static const luaL_Reg functions[] = {
-		{ "getNumSources", w_getNumSources },
-		{ "newSource1", w_newSource1 },
-		{ "play", w_play },
-		{ "stop", w_stop },
-		{ "pause", w_pause },
-		{ "resume", w_resume },
-		{ "rewind", w_rewind },
-		{ "setVolume", w_setVolume },
-		{ "getVolume", w_getVolume },
-		{ "setPosition", w_setPosition },
-		{ "getPosition", w_getPosition },
-		{ "setOrientation", w_setOrientation },
-		{ "getOrientation", w_getOrientation },
-		{ "setVelocity", w_setVelocity },
-		{ "getVelocity", w_getVelocity },
-		/*{ "record", w_record },
-		{ "getRecordedData", w_getRecordedData },
-		{ "stopRecording", w_stopRecording },*/
-		{ "setDistanceModel", w_setDistanceModel },
-		{ "getDistanceModel", w_getDistanceModel },
-		{ 0, 0 }
-	};
-
-	static const lua_CFunction types[] = {
-		luaopen_source,
-		0
-	};
-
-	extern "C" int luaopen_love_audio(lua_State * L)
-	{
-		if (instance == 0)
-		{
-			// Try OpenAL first.
-			try
-			{
-				instance = new love::audio::openal::Audio();
-			}
-			catch (love::Exception & e)
-			{
-				std::cout << e.what() << std::endl;
-			}
-		}
-		else
-			instance->retain();
-
-		if (instance == 0)
-		{
-			// Fall back to nullaudio.
-			try
-			{
-				instance = new love::audio::null::Audio();
-			}
-			catch (love::Exception & e)
-			{
-				std::cout << e.what() << std::endl;
-			}
-		}
-
-		if (instance == 0)
-			return luaL_error(L, "Could not open any audio module.");
-
-		WrappedModule w;
-		w.module = instance;
-		w.name = "audio";
-		w.flags = MODULE_T;
-		w.functions = functions;
-		w.types = types;
-
-		int n = luax_register_module(L, w);
-
-		if (luaL_loadbuffer(L, (const char *)audio_lua, sizeof(audio_lua), "audio.lua") == 0)
-			lua_call(L, 0, 0);
-
-		return n;
-	}
-
-} // audio
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+// LOVE
+#include "wrap_Audio.h"
+
+#include "openal/Audio.h"
+#include "null/Audio.h"
+
+#include "scripts/audio.lua.h"
+
+#include "common/runtime.h"
+
+namespace love
+{
+namespace audio
+{
+
+static Audio *instance = 0;
+
+int w_getNumSources(lua_State *L)
+{
+	lua_pushinteger(L, instance->getNumSources());
+	return 1;
+}
+
+int w_newSource1(lua_State *L)
+{
+	Source *t = 0;
+
+	if (luax_istype(L, 1, SOUND_SOUND_DATA_T))
+		t = instance->newSource(luax_totype<love::sound::SoundData>(L, 1, "SoundData", SOUND_SOUND_DATA_T));
+	else if (luax_istype(L, 1, SOUND_DECODER_T))
+		t = instance->newSource(luax_totype<love::sound::Decoder>(L, 1, "Decoder", SOUND_DECODER_T));
+
+	if (t)
+	{
+		luax_newtype(L, "Source", AUDIO_SOURCE_T, (void *)t);
+		return 1;
+	}
+	else
+		return luaL_error(L, "No matching overload");
+
+	return 0;
+}
+
+int w_play(lua_State *L)
+{
+	Source *s = luax_checksource(L, 1);
+	instance->play(s);
+	return 0;
+}
+
+int w_stop(lua_State *L)
+{
+	if (lua_gettop(L) == 0)
+	{
+		instance->stop();
+	}
+	else
+	{
+		Source *s = luax_checksource(L, 1);
+		s->stop();
+	}
+	return 0;
+}
+
+int w_pause(lua_State *L)
+{
+	if (lua_gettop(L) == 0)
+	{
+		instance->pause();
+	}
+	else
+	{
+		Source *s = luax_checksource(L, 1);
+		s->pause();
+	}
+
+	return 0;
+}
+
+int w_resume(lua_State *L)
+{
+	if (lua_gettop(L) == 0)
+	{
+		instance->resume();
+	}
+	else
+	{
+		Source *s = luax_checksource(L, 1);
+		s->resume();
+	}
+	return 0;
+}
+
+int w_rewind(lua_State *L)
+{
+	if (lua_gettop(L) == 0)
+	{
+		instance->rewind();
+	}
+	else
+	{
+		Source *s = luax_checksource(L, 1);
+		s->rewind();
+	}
+	return 0;
+}
+
+int w_setVolume(lua_State *L)
+{
+	float v = (float)luaL_checknumber(L, 1);
+	instance->setVolume(v);
+	return 0;
+}
+
+int w_getVolume(lua_State *L)
+{
+	lua_pushnumber(L, instance->getVolume());
+	return 1;
+}
+
+int w_setPosition(lua_State *L)
+{
+	float v[3];
+	v[0] = (float)luaL_checknumber(L, 1);
+	v[1] = (float)luaL_checknumber(L, 2);
+	v[2] = (float)luaL_optnumber(L, 3, 0);
+	instance->setPosition(v);
+	return 0;
+}
+
+int w_getPosition(lua_State *L)
+{
+	float v[3];
+	instance->getPosition(v);
+	lua_pushnumber(L, v[0]);
+	lua_pushnumber(L, v[1]);
+	lua_pushnumber(L, v[2]);
+	return 3;
+}
+
+int w_setOrientation(lua_State *L)
+{
+	float v[6];
+	v[0] = (float)luaL_checknumber(L, 1);
+	v[1] = (float)luaL_checknumber(L, 2);
+	v[2] = (float)luaL_checknumber(L, 3);
+	v[3] = (float)luaL_checknumber(L, 4);
+	v[4] = (float)luaL_checknumber(L, 5);
+	v[5] = (float)luaL_checknumber(L, 6);
+	instance->setOrientation(v);
+	return 0;
+}
+
+int w_getOrientation(lua_State *L)
+{
+	float v[6];
+	instance->getOrientation(v);
+	lua_pushnumber(L, v[0]);
+	lua_pushnumber(L, v[1]);
+	lua_pushnumber(L, v[2]);
+	lua_pushnumber(L, v[3]);
+	lua_pushnumber(L, v[4]);
+	lua_pushnumber(L, v[5]);
+	return 6;
+}
+
+int w_setVelocity(lua_State *L)
+{
+	float v[3];
+	v[0] = (float)luaL_checknumber(L, 1);
+	v[1] = (float)luaL_checknumber(L, 2);
+	v[2] = (float)luaL_optnumber(L, 3, 0);
+	instance->setVelocity(v);
+	return 0;
+}
+
+int w_getVelocity(lua_State *L)
+{
+	float v[3];
+	instance->getVelocity(v);
+	lua_pushnumber(L, v[0]);
+	lua_pushnumber(L, v[1]);
+	lua_pushnumber(L, v[2]);
+	return 3;
+}
+
+int w_record(lua_State *)
+{
+	instance->record();
+	return 0;
+}
+
+int w_getRecordedData(lua_State *L)
+{
+	love::sound::SoundData *sd = instance->getRecordedData();
+	if (!sd)
+		lua_pushnil(L);
+	else
+		luax_newtype(L, "SoundData", SOUND_SOUND_DATA_T, (void *)sd);
+	return 1;
+}
+
+int w_stopRecording(lua_State *L)
+{
+	if (luax_optboolean(L, 1, true))
+	{
+		love::sound::SoundData *sd = instance->stopRecording(true);
+		if (!sd) lua_pushnil(L);
+		else luax_newtype(L, "SoundData", SOUND_SOUND_DATA_T, (void *)sd);
+		return 1;
+	}
+	instance->stopRecording(false);
+	return 0;
+}
+
+int w_canRecord(lua_State *L)
+{
+	luax_pushboolean(L, instance->canRecord());
+	return 1;
+}
+
+int w_setDistanceModel(lua_State *L)
+{
+	const char *modelStr = luaL_checkstring(L, 1);
+	Audio::DistanceModel distanceModel;
+	if (!Audio::getConstant(modelStr, distanceModel))
+		return luaL_error(L, "Invalid distance model: %s", modelStr);
+	instance->setDistanceModel(distanceModel);
+	return 0;
+}
+
+int w_getDistanceModel(lua_State *L)
+{
+	Audio::DistanceModel distanceModel = instance->getDistanceModel();
+	const char *modelStr;
+	if (!Audio::getConstant(distanceModel, modelStr))
+		return 0;
+	lua_pushstring(L, modelStr);
+	return 1;
+}
+
+// List of functions to wrap.
+static const luaL_Reg functions[] =
+{
+	{ "getNumSources", w_getNumSources },
+	{ "newSource1", w_newSource1 },
+	{ "play", w_play },
+	{ "stop", w_stop },
+	{ "pause", w_pause },
+	{ "resume", w_resume },
+	{ "rewind", w_rewind },
+	{ "setVolume", w_setVolume },
+	{ "getVolume", w_getVolume },
+	{ "setPosition", w_setPosition },
+	{ "getPosition", w_getPosition },
+	{ "setOrientation", w_setOrientation },
+	{ "getOrientation", w_getOrientation },
+	{ "setVelocity", w_setVelocity },
+	{ "getVelocity", w_getVelocity },
+	/*{ "record", w_record },
+	{ "getRecordedData", w_getRecordedData },
+	{ "stopRecording", w_stopRecording },*/
+	{ "setDistanceModel", w_setDistanceModel },
+	{ "getDistanceModel", w_getDistanceModel },
+	{ 0, 0 }
+};
+
+static const lua_CFunction types[] =
+{
+	luaopen_source,
+	0
+};
+
+extern "C" int luaopen_love_audio(lua_State *L)
+{
+	if (instance == 0)
+	{
+		// Try OpenAL first.
+		try
+		{
+			instance = new love::audio::openal::Audio();
+		}
+		catch(love::Exception &e)
+		{
+			std::cout << e.what() << std::endl;
+		}
+	}
+	else
+		instance->retain();
+
+	if (instance == 0)
+	{
+		// Fall back to nullaudio.
+		try
+		{
+			instance = new love::audio::null::Audio();
+		}
+		catch(love::Exception &e)
+		{
+			std::cout << e.what() << std::endl;
+		}
+	}
+
+	if (instance == 0)
+		return luaL_error(L, "Could not open any audio module.");
+
+	WrappedModule w;
+	w.module = instance;
+	w.name = "audio";
+	w.flags = MODULE_T;
+	w.functions = functions;
+	w.types = types;
+
+	int n = luax_register_module(L, w);
+
+	if (luaL_loadbuffer(L, (const char *)audio_lua, sizeof(audio_lua), "audio.lua") == 0)
+		lua_call(L, 0, 0);
+
+	return n;
+}
+
+} // audio
+} // love

+ 61 - 60
src/modules/audio/wrap_Audio.h

@@ -1,60 +1,61 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_AUDIO_WRAP_AUDIO_H
-#define LOVE_AUDIO_WRAP_AUDIO_H
-
-// LOVE
-#include <common/config.h>
-#include <common/runtime.h>
-#include "Audio.h"
-#include "wrap_Source.h"
-
-namespace love
-{
-namespace audio
-{
-	int w_getNumSources(lua_State * L);
-	int w_newSource1(lua_State * L);
-	int w_play(lua_State * L);
-	int w_stop(lua_State * L);
-	int w_pause(lua_State * L);
-	int w_resume(lua_State * L);
-	int w_rewind(lua_State * L);
-	int w_setVolume(lua_State * L);
-	int w_getVolume(lua_State * L);
-	int w_setPosition(lua_State * L);
-	int w_getPosition(lua_State * L);
-	int w_setOrientation(lua_State * L);
-	int w_getOrientation(lua_State * L);
-	int w_setVelocity(lua_State * L);
-	int w_getVelocity(lua_State * L);
-	int w_record(lua_State * L);
-	int w_getRecordedData(lua_State * L);
-	int w_stopRecording(lua_State * L);
-	int w_canRecord(lua_State * L);
-	int w_setDistanceModel(lua_State * L);
-	int w_getDistanceModel(lua_State * L);
-	extern "C" LOVE_EXPORT int luaopen_love_audio(lua_State * L);
-
-} // audio
-} // love
-
-#endif // LOVE_AUDIO_WRAP_AUDIO_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_AUDIO_WRAP_AUDIO_H
+#define LOVE_AUDIO_WRAP_AUDIO_H
+
+// LOVE
+#include "common/config.h"
+#include "common/runtime.h"
+#include "Audio.h"
+#include "wrap_Source.h"
+
+namespace love
+{
+namespace audio
+{
+
+int w_getNumSources(lua_State *L);
+int w_newSource1(lua_State *L);
+int w_play(lua_State *L);
+int w_stop(lua_State *L);
+int w_pause(lua_State *L);
+int w_resume(lua_State *L);
+int w_rewind(lua_State *L);
+int w_setVolume(lua_State *L);
+int w_getVolume(lua_State *L);
+int w_setPosition(lua_State *L);
+int w_getPosition(lua_State *L);
+int w_setOrientation(lua_State *L);
+int w_getOrientation(lua_State *L);
+int w_setVelocity(lua_State *L);
+int w_getVelocity(lua_State *L);
+int w_record(lua_State *L);
+int w_getRecordedData(lua_State *L);
+int w_stopRecording(lua_State *L);
+int w_canRecord(lua_State *L);
+int w_setDistanceModel(lua_State *L);
+int w_getDistanceModel(lua_State *L);
+extern "C" LOVE_EXPORT int luaopen_love_audio(lua_State *L);
+
+} // audio
+} // love
+
+#endif // LOVE_AUDIO_WRAP_AUDIO_H

+ 320 - 318
src/modules/audio/wrap_Source.cpp

@@ -1,318 +1,320 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "wrap_Source.h"
-
-namespace love
-{
-namespace audio
-{
-	Source * luax_checksource(lua_State * L, int idx)
-	{
-		return luax_checktype<Source>(L, idx, "Source", AUDIO_SOURCE_T);
-	}
-
-	int w_Source_play(lua_State * L)
-	{
-		Source * t = luax_checksource(L, 1);
-		t->play();
-		return 0;
-	}
-
-	int w_Source_stop(lua_State * L)
-	{
-		Source * t = luax_checksource(L, 1);
-		t->stop();
-		return 0;
-	}
-
-	int w_Source_pause(lua_State * L)
-	{
-		Source * t = luax_checksource(L, 1);
-		t->pause();
-		return 0;
-	}
-
-	int w_Source_resume(lua_State * L)
-	{
-		Source * t = luax_checksource(L, 1);
-		t->resume();
-		return 0;
-	}
-
-	int w_Source_rewind(lua_State * L)
-	{
-		Source * t = luax_checksource(L, 1);
-		t->rewind();
-		return 0;
-	}
-
-	int w_Source_setPitch(lua_State * L)
-	{
-		Source * t = luax_checksource(L, 1);
-		float p = (float)luaL_checknumber(L, 2);
-		t->setPitch(p);
-		return 0;
-	}
-
-	int w_Source_getPitch(lua_State * L)
-	{
-		Source * t = luax_checksource(L, 1);
-		lua_pushnumber(L, t->getPitch());
-		return 1;
-	}
-
-	int w_Source_setVolume(lua_State * L)
-	{
-		Source * t = luax_checksource(L, 1);
-		float p = (float)luaL_checknumber(L, 2);
-		t->setVolume(p);
-		return 0;
-	}
-
-	int w_Source_getVolume(lua_State * L)
-	{
-		Source * t = luax_checksource(L, 1);
-		lua_pushnumber(L, t->getVolume());
-		return 1;
-	}
-
-	int w_Source_seek(lua_State * L)
-	{
-		Source * t = luax_checksource(L, 1);
-		float offset = (float)luaL_checknumber(L, 2);
-		const char * unit = luaL_optstring(L, 3, "seconds");
-		Source::Unit u;
-		t->getConstant(unit, u);
-		t->seek(offset, u);
-		return 0;
-	}
-
-	int w_Source_tell(lua_State * L)
-	{
-		Source * t = luax_checksource(L, 1);
-		const char * unit = luaL_optstring(L, 2, "seconds");
-		Source::Unit u;
-		t->getConstant(unit, u);
-		lua_pushnumber(L, t->tell(u));
-		return 1;
-	}
-
-	int w_Source_setPosition(lua_State * L)
-	{
-		Source * t = luax_checksource(L, 1);
-		float v[3];
-		v[0] = (float)luaL_checknumber(L, 2);
-		v[1] = (float)luaL_checknumber(L, 3);
-		v[2] = (float)luaL_optnumber(L, 4, 0);
-		t->setPosition(v);
-		return 0;
-	}
-
-	int w_Source_getPosition(lua_State * L)
-	{
-		Source * t = luax_checksource(L, 1);
-		float v[3];
-		t->getPosition(v);
-		lua_pushnumber(L, v[0]);
-		lua_pushnumber(L, v[1]);
-		lua_pushnumber(L, v[2]);
-		return 3;
-	}
-
-	int w_Source_setVelocity(lua_State * L)
-	{
-		Source * t = luax_checksource(L, 1);
-		float v[3];
-		v[0] = (float)luaL_checknumber(L, 2);
-		v[1] = (float)luaL_checknumber(L, 3);
-		v[2] = (float)luaL_optnumber(L, 4, 0);
-		t->setVelocity(v);
-		return 0;
-	}
-
-	int w_Source_getVelocity(lua_State * L)
-	{
-		Source * t = luax_checksource(L, 1);
-		float v[3];
-		t->getVelocity(v);
-		lua_pushnumber(L, v[0]);
-		lua_pushnumber(L, v[1]);
-		lua_pushnumber(L, v[2]);
-		return 3;
-	}
-
-	int w_Source_setDirection(lua_State * L)
-	{
-		Source * t = luax_checksource(L, 1);
-		float v[3];
-		v[0] = (float)luaL_checknumber(L, 2);
-		v[1] = (float)luaL_checknumber(L, 3);
-		v[2] = (float)luaL_optnumber(L, 4, 0);
-		t->setDirection(v);
-		return 0;
-	}
-
-	int w_Source_getDirection(lua_State * L)
-	{
-		Source * t = luax_checksource(L, 1);
-		float v[3];
-		t->getDirection(v);
-		lua_pushnumber(L, v[0]);
-		lua_pushnumber(L, v[1]);
-		lua_pushnumber(L, v[2]);
-		return 3;
-	}
-
-	int w_Source_setLooping(lua_State * L)
-	{
-		Source * t = luax_checksource(L, 1);
-		t->setLooping(luax_toboolean(L, 2));
-		return 0;
-	}
-
-	int w_Source_isLooping(lua_State * L)
-	{
-		Source * t = luax_checksource(L, 1);
-		luax_pushboolean(L, t->isLooping());
-		return 1;
-	}
-
-	int w_Source_isStopped(lua_State * L)
-	{
-		Source * t = luax_checksource(L, 1);
-		luax_pushboolean(L, t->isStopped());
-		return 1;
-	}
-
-	int w_Source_isPaused(lua_State * L)
-	{
-		Source * t = luax_checksource(L, 1);
-		luax_pushboolean(L, t->isPaused());
-		return 1;
-	}
-
-	int w_Source_isStatic(lua_State * L)
-	{
-		Source * t = luax_checksource(L, 1);
-		luax_pushboolean(L, t->isStatic());
-		return 1;
-	}
-
-	int w_Source_setVolumeLimits(lua_State * L)
-	{
-		Source * t = luax_checksource(L, 1);
-		float vmin = (float)luaL_checknumber(L, 2);
-		float vmax = (float)luaL_checknumber(L, 3);
-		if (vmin < .0f || vmin > 1.f || vmax < .0f || vmax > 1.f)
-			return luaL_error(L, "Invalid volume limits: [%f:%f]. Must be in [0:1]", vmin, vmax);
-		t->setMinVolume(vmin);
-		t->setMaxVolume(vmin);
-		return 0;
-	}
-
-	int w_Source_getVolumeLimits(lua_State * L)
-	{
-		Source * t = luax_checksource(L, 1);
-		lua_pushnumber(L, t->getMinVolume());
-		lua_pushnumber(L, t->getMaxVolume());
-		return 2;
-	}
-
-	int w_Source_setDistance(lua_State * L)
-	{
-		Source * t = luax_checksource(L, 1);
-		float dref = (float)luaL_checknumber(L, 2);
-		float dmax = (float)luaL_checknumber(L, 3);
-		if (dref < .0f || dmax < .0f)
-			return luaL_error(L, "Invalid distances: %f, %f. Must be > 0", dref, dmax);
-		t->setReferenceDistance(dref);
-		t->setMaxDistance(dmax);
-		return 0;
-	}
-
-	int w_Source_getDistance(lua_State * L)
-	{
-		Source * t = luax_checksource(L, 1);
-		lua_pushnumber(L, t->getReferenceDistance());
-		lua_pushnumber(L, t->getMaxDistance());
-		return 2;
-	}
-
-	int w_Source_setRolloff(lua_State * L)
-	{
-		Source * t = luax_checksource(L, 1);
-		float rolloff = (float)luaL_checknumber(L, 2);
-		if (rolloff < .0f)
-			return luaL_error(L, "Invalid rolloff: %f. Must be > 0.", rolloff);
-		t->setRolloffFactor(rolloff);
-		return 0;
-	}
-
-	int w_Source_getRolloff(lua_State * L)
-	{
-		Source * t = luax_checksource(L, 1);
-		lua_pushnumber(L, t->getRolloffFactor());
-		return 1;
-	}
-
-	static const luaL_Reg functions[] = {
-		{ "play", w_Source_play },
-		{ "stop", w_Source_stop },
-		{ "pause", w_Source_pause },
-		{ "resume", w_Source_resume },
-		{ "rewind", w_Source_rewind },
-
-		{ "setPitch", w_Source_setPitch },
-		{ "getPitch", w_Source_getPitch },
-		{ "setVolume", w_Source_setVolume },
-		{ "getVolume", w_Source_getVolume },
-		{ "seek", w_Source_seek },
-		{ "tell", w_Source_tell },
-		{ "setPosition", w_Source_setPosition },
-		{ "getPosition", w_Source_getPosition },
-		{ "setVelocity", w_Source_setVelocity },
-		{ "getVelocity", w_Source_getVelocity },
-		{ "setDirection", w_Source_setDirection },
-		{ "getDirection", w_Source_getDirection },
-
-		{ "setLooping", w_Source_setLooping },
-		{ "isLooping", w_Source_isLooping },
-		{ "isStopped", w_Source_isStopped },
-		{ "isPaused", w_Source_isPaused },
-		{ "isStatic", w_Source_isStatic },
-
-		{ "setVolumeLimits", w_Source_setVolumeLimits },
-		{ "getVolumeLimits", w_Source_getVolumeLimits },
-		{ "setDistance", w_Source_setDistance },
-		{ "getDistance", w_Source_setDistance },
-		{ "setRolloff", w_Source_setRolloff},
-		{ "getRolloff", w_Source_getRolloff},
-
-		{ 0, 0 }
-	};
-
-	extern "C" int luaopen_source(lua_State * L)
-	{
-		return luax_register_type(L, "Source", functions);
-	}
-
-} // audio
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "wrap_Source.h"
+
+namespace love
+{
+namespace audio
+{
+
+Source *luax_checksource(lua_State *L, int idx)
+{
+	return luax_checktype<Source>(L, idx, "Source", AUDIO_SOURCE_T);
+}
+
+int w_Source_play(lua_State *L)
+{
+	Source *t = luax_checksource(L, 1);
+	t->play();
+	return 0;
+}
+
+int w_Source_stop(lua_State *L)
+{
+	Source *t = luax_checksource(L, 1);
+	t->stop();
+	return 0;
+}
+
+int w_Source_pause(lua_State *L)
+{
+	Source *t = luax_checksource(L, 1);
+	t->pause();
+	return 0;
+}
+
+int w_Source_resume(lua_State *L)
+{
+	Source *t = luax_checksource(L, 1);
+	t->resume();
+	return 0;
+}
+
+int w_Source_rewind(lua_State *L)
+{
+	Source *t = luax_checksource(L, 1);
+	t->rewind();
+	return 0;
+}
+
+int w_Source_setPitch(lua_State *L)
+{
+	Source *t = luax_checksource(L, 1);
+	float p = (float)luaL_checknumber(L, 2);
+	t->setPitch(p);
+	return 0;
+}
+
+int w_Source_getPitch(lua_State *L)
+{
+	Source *t = luax_checksource(L, 1);
+	lua_pushnumber(L, t->getPitch());
+	return 1;
+}
+
+int w_Source_setVolume(lua_State *L)
+{
+	Source *t = luax_checksource(L, 1);
+	float p = (float)luaL_checknumber(L, 2);
+	t->setVolume(p);
+	return 0;
+}
+
+int w_Source_getVolume(lua_State *L)
+{
+	Source *t = luax_checksource(L, 1);
+	lua_pushnumber(L, t->getVolume());
+	return 1;
+}
+
+int w_Source_seek(lua_State *L)
+{
+	Source *t = luax_checksource(L, 1);
+	float offset = (float)luaL_checknumber(L, 2);
+	const char *unit = luaL_optstring(L, 3, "seconds");
+	Source::Unit u;
+	t->getConstant(unit, u);
+	t->seek(offset, u);
+	return 0;
+}
+
+int w_Source_tell(lua_State *L)
+{
+	Source *t = luax_checksource(L, 1);
+	const char *unit = luaL_optstring(L, 2, "seconds");
+	Source::Unit u;
+	t->getConstant(unit, u);
+	lua_pushnumber(L, t->tell(u));
+	return 1;
+}
+
+int w_Source_setPosition(lua_State *L)
+{
+	Source *t = luax_checksource(L, 1);
+	float v[3];
+	v[0] = (float)luaL_checknumber(L, 2);
+	v[1] = (float)luaL_checknumber(L, 3);
+	v[2] = (float)luaL_optnumber(L, 4, 0);
+	t->setPosition(v);
+	return 0;
+}
+
+int w_Source_getPosition(lua_State *L)
+{
+	Source *t = luax_checksource(L, 1);
+	float v[3];
+	t->getPosition(v);
+	lua_pushnumber(L, v[0]);
+	lua_pushnumber(L, v[1]);
+	lua_pushnumber(L, v[2]);
+	return 3;
+}
+
+int w_Source_setVelocity(lua_State *L)
+{
+	Source *t = luax_checksource(L, 1);
+	float v[3];
+	v[0] = (float)luaL_checknumber(L, 2);
+	v[1] = (float)luaL_checknumber(L, 3);
+	v[2] = (float)luaL_optnumber(L, 4, 0);
+	t->setVelocity(v);
+	return 0;
+}
+
+int w_Source_getVelocity(lua_State *L)
+{
+	Source *t = luax_checksource(L, 1);
+	float v[3];
+	t->getVelocity(v);
+	lua_pushnumber(L, v[0]);
+	lua_pushnumber(L, v[1]);
+	lua_pushnumber(L, v[2]);
+	return 3;
+}
+
+int w_Source_setDirection(lua_State *L)
+{
+	Source *t = luax_checksource(L, 1);
+	float v[3];
+	v[0] = (float)luaL_checknumber(L, 2);
+	v[1] = (float)luaL_checknumber(L, 3);
+	v[2] = (float)luaL_optnumber(L, 4, 0);
+	t->setDirection(v);
+	return 0;
+}
+
+int w_Source_getDirection(lua_State *L)
+{
+	Source *t = luax_checksource(L, 1);
+	float v[3];
+	t->getDirection(v);
+	lua_pushnumber(L, v[0]);
+	lua_pushnumber(L, v[1]);
+	lua_pushnumber(L, v[2]);
+	return 3;
+}
+
+int w_Source_setLooping(lua_State *L)
+{
+	Source *t = luax_checksource(L, 1);
+	t->setLooping(luax_toboolean(L, 2));
+	return 0;
+}
+
+int w_Source_isLooping(lua_State *L)
+{
+	Source *t = luax_checksource(L, 1);
+	luax_pushboolean(L, t->isLooping());
+	return 1;
+}
+
+int w_Source_isStopped(lua_State *L)
+{
+	Source *t = luax_checksource(L, 1);
+	luax_pushboolean(L, t->isStopped());
+	return 1;
+}
+
+int w_Source_isPaused(lua_State *L)
+{
+	Source *t = luax_checksource(L, 1);
+	luax_pushboolean(L, t->isPaused());
+	return 1;
+}
+
+int w_Source_isStatic(lua_State *L)
+{
+	Source *t = luax_checksource(L, 1);
+	luax_pushboolean(L, t->isStatic());
+	return 1;
+}
+
+int w_Source_setVolumeLimits(lua_State *L)
+{
+	Source *t = luax_checksource(L, 1);
+	float vmin = (float)luaL_checknumber(L, 2);
+	float vmax = (float)luaL_checknumber(L, 3);
+	if (vmin < .0f || vmin > 1.f || vmax < .0f || vmax > 1.f)
+		return luaL_error(L, "Invalid volume limits: [%f:%f]. Must be in [0:1]", vmin, vmax);
+	t->setMinVolume(vmin);
+	t->setMaxVolume(vmin);
+	return 0;
+}
+
+int w_Source_getVolumeLimits(lua_State *L)
+{
+	Source *t = luax_checksource(L, 1);
+	lua_pushnumber(L, t->getMinVolume());
+	lua_pushnumber(L, t->getMaxVolume());
+	return 2;
+}
+
+int w_Source_setDistance(lua_State *L)
+{
+	Source *t = luax_checksource(L, 1);
+	float dref = (float)luaL_checknumber(L, 2);
+	float dmax = (float)luaL_checknumber(L, 3);
+	if (dref < .0f || dmax < .0f)
+		return luaL_error(L, "Invalid distances: %f, %f. Must be > 0", dref, dmax);
+	t->setReferenceDistance(dref);
+	t->setMaxDistance(dmax);
+	return 0;
+}
+
+int w_Source_getDistance(lua_State *L)
+{
+	Source *t = luax_checksource(L, 1);
+	lua_pushnumber(L, t->getReferenceDistance());
+	lua_pushnumber(L, t->getMaxDistance());
+	return 2;
+}
+
+int w_Source_setRolloff(lua_State *L)
+{
+	Source *t = luax_checksource(L, 1);
+	float rolloff = (float)luaL_checknumber(L, 2);
+	if (rolloff < .0f)
+		return luaL_error(L, "Invalid rolloff: %f. Must be > 0.", rolloff);
+	t->setRolloffFactor(rolloff);
+	return 0;
+}
+
+int w_Source_getRolloff(lua_State *L)
+{
+	Source *t = luax_checksource(L, 1);
+	lua_pushnumber(L, t->getRolloffFactor());
+	return 1;
+}
+
+static const luaL_Reg functions[] =
+{
+	{ "play", w_Source_play },
+	{ "stop", w_Source_stop },
+	{ "pause", w_Source_pause },
+	{ "resume", w_Source_resume },
+	{ "rewind", w_Source_rewind },
+
+	{ "setPitch", w_Source_setPitch },
+	{ "getPitch", w_Source_getPitch },
+	{ "setVolume", w_Source_setVolume },
+	{ "getVolume", w_Source_getVolume },
+	{ "seek", w_Source_seek },
+	{ "tell", w_Source_tell },
+	{ "setPosition", w_Source_setPosition },
+	{ "getPosition", w_Source_getPosition },
+	{ "setVelocity", w_Source_setVelocity },
+	{ "getVelocity", w_Source_getVelocity },
+	{ "setDirection", w_Source_setDirection },
+	{ "getDirection", w_Source_getDirection },
+
+	{ "setLooping", w_Source_setLooping },
+	{ "isLooping", w_Source_isLooping },
+	{ "isStopped", w_Source_isStopped },
+	{ "isPaused", w_Source_isPaused },
+	{ "isStatic", w_Source_isStatic },
+
+	{ "setVolumeLimits", w_Source_setVolumeLimits },
+	{ "getVolumeLimits", w_Source_getVolumeLimits },
+	{ "setDistance", w_Source_setDistance },
+	{ "getDistance", w_Source_setDistance },
+	{ "setRolloff", w_Source_setRolloff},
+	{ "getRolloff", w_Source_getRolloff},
+
+	{ 0, 0 }
+};
+
+extern "C" int luaopen_source(lua_State *L)
+{
+	return luax_register_type(L, "Source", functions);
+}
+
+} // audio
+} // love

+ 66 - 65
src/modules/audio/wrap_Source.h

@@ -1,65 +1,66 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_AUDIO_WRAP_SOURCE_H
-#define LOVE_AUDIO_WRAP_SOURCE_H
-
-#include <common/runtime.h>
-#include "Source.h"
-
-namespace love
-{
-namespace audio
-{
-	Source * luax_checksource(lua_State * L, int idx);
-	int w_Source_play(lua_State * L);
-	int w_Source_stop(lua_State * L);
-	int w_Source_pause(lua_State * L);
-	int w_Source_resume(lua_State * L);
-	int w_Source_rewind(lua_State * L);
-	int w_Source_setPitch(lua_State * L);
-	int w_Source_getPitch(lua_State * L);
-	int w_Source_setVolume(lua_State * L);
-	int w_Source_getVolume(lua_State * L);
-	int w_Source_seek(lua_State * L);
-	int w_Source_tell(lua_State * L);
-	int w_Source_setPosition(lua_State * L);
-	int w_Source_getPosition(lua_State * L);
-	int w_Source_setVelocity(lua_State * L);
-	int w_Source_getVelocity(lua_State * L);
-	int w_Source_setDirection(lua_State * L);
-	int w_Source_getDirection(lua_State * L);
-	int w_Source_setLooping(lua_State * L);
-	int w_Source_isLooping(lua_State * L);
-	int w_Source_isStopped(lua_State * L);
-	int w_Source_isPaused(lua_State * L);
-	int w_Source_isStatic(lua_State * L);
-	int w_Source_setVolumeLimits(lua_State * L);
-	int w_Source_getVolumeLimits(lua_State * L);
-	int w_Source_setDistance(lua_State * L);
-	int w_Source_getDistance(lua_State * L);
-	int w_Source_setRolloff(lua_State * L);
-	int w_Source_getRolloff(lua_State * L);
-	extern "C" int luaopen_source(lua_State * L);
-
-} // audio
-} // love
-
-#endif // LOVE_AUDIO_WRAP_SOURCE_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_AUDIO_WRAP_SOURCE_H
+#define LOVE_AUDIO_WRAP_SOURCE_H
+
+#include "common/runtime.h"
+#include "Source.h"
+
+namespace love
+{
+namespace audio
+{
+
+Source *luax_checksource(lua_State *L, int idx);
+int w_Source_play(lua_State *L);
+int w_Source_stop(lua_State *L);
+int w_Source_pause(lua_State *L);
+int w_Source_resume(lua_State *L);
+int w_Source_rewind(lua_State *L);
+int w_Source_setPitch(lua_State *L);
+int w_Source_getPitch(lua_State *L);
+int w_Source_setVolume(lua_State *L);
+int w_Source_getVolume(lua_State *L);
+int w_Source_seek(lua_State *L);
+int w_Source_tell(lua_State *L);
+int w_Source_setPosition(lua_State *L);
+int w_Source_getPosition(lua_State *L);
+int w_Source_setVelocity(lua_State *L);
+int w_Source_getVelocity(lua_State *L);
+int w_Source_setDirection(lua_State *L);
+int w_Source_getDirection(lua_State *L);
+int w_Source_setLooping(lua_State *L);
+int w_Source_isLooping(lua_State *L);
+int w_Source_isStopped(lua_State *L);
+int w_Source_isPaused(lua_State *L);
+int w_Source_isStatic(lua_State *L);
+int w_Source_setVolumeLimits(lua_State *L);
+int w_Source_getVolumeLimits(lua_State *L);
+int w_Source_setDistance(lua_State *L);
+int w_Source_getDistance(lua_State *L);
+int w_Source_setRolloff(lua_State *L);
+int w_Source_getRolloff(lua_State *L);
+extern "C" int luaopen_source(lua_State *L);
+
+} // audio
+} // love
+
+#endif // LOVE_AUDIO_WRAP_SOURCE_H

+ 297 - 295
src/modules/event/Event.cpp

@@ -1,295 +1,297 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "Event.h"
-
-using love::thread::Mutex;
-using love::thread::Lock;
-
-namespace love
-{
-namespace event
-{
-	Message::Message(std::string name, Variant *a, Variant *b, Variant *c, Variant *d)
-		: name(name), nargs(0)
-	{
-		args[0] = a;
-		args[1] = b;
-		args[2] = c;
-		args[3] = d;
-		for (int i = 0; i < 4; i++)
-		{
-			if (!args[i])
-				continue;
-			args[i]->retain();
-			nargs++;
-		}
-	}
-
-	Message::~Message()
-	{
-		for (int i = 0; i < nargs; i++)
-			args[i]->release();
-	}
-
-	int Message::toLua(lua_State *L)
-	{
-		luax_pushstring(L, name);
-		for (int i = 0; i < nargs; i++)
-			args[i]->toLua(L);
-		return nargs+1;
-	}
-
-	Message *Message::fromLua(lua_State *L, int n)
-	{
-		std::string name = luax_checkstring(L, n);
-		n++;
-		Message *m = new Message(name);
-		for (int i = 0; i < 4; i++)
-		{
-			if (lua_isnoneornil(L, n+i))
-				break;
-			m->args[i] = Variant::fromLua(L, n+i);
-			if (!m->args[i])
-			{
-				delete m;
-				luaL_error(L, "Argument %d can't be stored safely\nExpected boolean, number, string or userdata.", n+i);
-				return NULL;
-			}
-			m->nargs++;
-		}
-		return m;
-	}
-
-	Event::~Event()
-	{
-	}
-
-	void Event::push(Message *msg)
-	{
-		Lock lock(mutex);
-		msg->retain();
-		queue.push(msg);
-	}
-
-	bool Event::poll(Message *&msg)
-	{
-		Lock lock(mutex);
-		if (queue.empty())
-			return false;
-		msg = queue.front();
-		queue.pop();
-		return true;
-	}
-
-	void Event::clear()
-	{
-		Lock lock(mutex);
-		while (!queue.empty())
-		{
-			queue.back()->release();
-			queue.pop();
-		}
-	}
-
-	bool Event::getConstant(const char * in, love::mouse::Mouse::Button & out)
-	{
-		return buttons.find(in, out);
-	}
-
-	bool Event::getConstant(love::mouse::Mouse::Button in, const char *& out)
-	{
-		return buttons.find(in, out);
-	}
-
-	bool Event::getConstant(const char * in, love::keyboard::Keyboard::Key & out)
-	{
-		return keys.find(in, out);
-	}
-
-	bool Event::getConstant(love::keyboard::Keyboard::Key in, const char *& out)
-	{
-		return keys.find(in, out);
-	}
-
-	StringMap<love::mouse::Mouse::Button, love::mouse::Mouse::BUTTON_MAX_ENUM>::Entry Event::buttonEntries[] =
-	{
-		{"l", love::mouse::Mouse::BUTTON_LEFT},
-		{"m", love::mouse::Mouse::BUTTON_MIDDLE},
-		{"r", love::mouse::Mouse::BUTTON_RIGHT},
-		{"wu", love::mouse::Mouse::BUTTON_WHEELUP},
-		{"wd", love::mouse::Mouse::BUTTON_WHEELDOWN},
-		{"x1", love::mouse::Mouse::BUTTON_X1},
-		{"x2", love::mouse::Mouse::BUTTON_X2},
-	};
-
-	StringMap<love::mouse::Mouse::Button, love::mouse::Mouse::BUTTON_MAX_ENUM> Event::buttons(Event::buttonEntries, sizeof(Event::buttonEntries));
-
-	StringMap<love::keyboard::Keyboard::Key, love::keyboard::Keyboard::KEY_MAX_ENUM>::Entry Event::keyEntries[] =
-	{
-		{"backspace", love::keyboard::Keyboard::KEY_BACKSPACE},
-		{"tab", love::keyboard::Keyboard::KEY_TAB},
-		{"clear", love::keyboard::Keyboard::KEY_CLEAR},
-		{"return", love::keyboard::Keyboard::KEY_RETURN},
-		{"pause", love::keyboard::Keyboard::KEY_PAUSE},
-		{"escape", love::keyboard::Keyboard::KEY_ESCAPE},
-		{" ", love::keyboard::Keyboard::KEY_SPACE},
-		{"!", love::keyboard::Keyboard::KEY_EXCLAIM},
-		{"\"", love::keyboard::Keyboard::KEY_QUOTEDBL},
-		{"#", love::keyboard::Keyboard::KEY_HASH},
-		{"$", love::keyboard::Keyboard::KEY_DOLLAR},
-		{"&", love::keyboard::Keyboard::KEY_AMPERSAND},
-		{"'", love::keyboard::Keyboard::KEY_QUOTE},
-		{"(", love::keyboard::Keyboard::KEY_LEFTPAREN},
-		{")", love::keyboard::Keyboard::KEY_RIGHTPAREN},
-		{"*", love::keyboard::Keyboard::KEY_ASTERISK},
-		{"+", love::keyboard::Keyboard::KEY_PLUS},
-		{",", love::keyboard::Keyboard::KEY_COMMA},
-		{"-", love::keyboard::Keyboard::KEY_MINUS},
-		{".", love::keyboard::Keyboard::KEY_PERIOD},
-		{"/", love::keyboard::Keyboard::KEY_SLASH},
-		{"0", love::keyboard::Keyboard::KEY_0},
-		{"1", love::keyboard::Keyboard::KEY_1},
-		{"2", love::keyboard::Keyboard::KEY_2},
-		{"3", love::keyboard::Keyboard::KEY_3},
-		{"4", love::keyboard::Keyboard::KEY_4},
-		{"5", love::keyboard::Keyboard::KEY_5},
-		{"6", love::keyboard::Keyboard::KEY_6},
-		{"7", love::keyboard::Keyboard::KEY_7},
-		{"8", love::keyboard::Keyboard::KEY_8},
-		{"9", love::keyboard::Keyboard::KEY_9},
-		{":", love::keyboard::Keyboard::KEY_COLON},
-		{";", love::keyboard::Keyboard::KEY_SEMICOLON},
-		{"<", love::keyboard::Keyboard::KEY_LESS},
-		{"=", love::keyboard::Keyboard::KEY_EQUALS},
-		{">", love::keyboard::Keyboard::KEY_GREATER},
-		{"?", love::keyboard::Keyboard::KEY_QUESTION},
-		{"@", love::keyboard::Keyboard::KEY_AT},
-
-		{"[", love::keyboard::Keyboard::KEY_LEFTBRACKET},
-		{"\\", love::keyboard::Keyboard::KEY_BACKSLASH},
-		{"]", love::keyboard::Keyboard::KEY_RIGHTBRACKET},
-		{"^", love::keyboard::Keyboard::KEY_CARET},
-		{"_", love::keyboard::Keyboard::KEY_UNDERSCORE},
-		{"`", love::keyboard::Keyboard::KEY_BACKQUOTE},
-		{"a", love::keyboard::Keyboard::KEY_A},
-		{"b", love::keyboard::Keyboard::KEY_B},
-		{"c", love::keyboard::Keyboard::KEY_C},
-		{"d", love::keyboard::Keyboard::KEY_D},
-		{"e", love::keyboard::Keyboard::KEY_E},
-		{"f", love::keyboard::Keyboard::KEY_F},
-		{"g", love::keyboard::Keyboard::KEY_G},
-		{"h", love::keyboard::Keyboard::KEY_H},
-		{"i", love::keyboard::Keyboard::KEY_I},
-		{"j", love::keyboard::Keyboard::KEY_J},
-		{"k", love::keyboard::Keyboard::KEY_K},
-		{"l", love::keyboard::Keyboard::KEY_L},
-		{"m", love::keyboard::Keyboard::KEY_M},
-		{"n", love::keyboard::Keyboard::KEY_N},
-		{"o", love::keyboard::Keyboard::KEY_O},
-		{"p", love::keyboard::Keyboard::KEY_P},
-		{"q", love::keyboard::Keyboard::KEY_Q},
-		{"r", love::keyboard::Keyboard::KEY_R},
-		{"s", love::keyboard::Keyboard::KEY_S},
-		{"t", love::keyboard::Keyboard::KEY_T},
-		{"u", love::keyboard::Keyboard::KEY_U},
-		{"v", love::keyboard::Keyboard::KEY_V},
-		{"w", love::keyboard::Keyboard::KEY_W},
-		{"x", love::keyboard::Keyboard::KEY_X},
-		{"y", love::keyboard::Keyboard::KEY_Y},
-		{"z", love::keyboard::Keyboard::KEY_Z},
-		{"delete", love::keyboard::Keyboard::KEY_DELETE},
-
-		{"kp0", love::keyboard::Keyboard::KEY_KP0},
-		{"kp1", love::keyboard::Keyboard::KEY_KP1},
-		{"kp2", love::keyboard::Keyboard::KEY_KP2},
-		{"kp3", love::keyboard::Keyboard::KEY_KP3},
-		{"kp4", love::keyboard::Keyboard::KEY_KP4},
-		{"kp5", love::keyboard::Keyboard::KEY_KP5},
-		{"kp6", love::keyboard::Keyboard::KEY_KP6},
-		{"kp7", love::keyboard::Keyboard::KEY_KP7},
-		{"kp8", love::keyboard::Keyboard::KEY_KP8},
-		{"kp9", love::keyboard::Keyboard::KEY_KP9},
-		{"kp.", love::keyboard::Keyboard::KEY_KP_PERIOD},
-		{"kp/", love::keyboard::Keyboard::KEY_KP_DIVIDE},
-		{"kp*", love::keyboard::Keyboard::KEY_KP_MULTIPLY},
-		{"kp-", love::keyboard::Keyboard::KEY_KP_MINUS},
-		{"kp+", love::keyboard::Keyboard::KEY_KP_PLUS},
-		{"kpenter", love::keyboard::Keyboard::KEY_KP_ENTER},
-		{"kp=", love::keyboard::Keyboard::KEY_KP_EQUALS},
-
-		{"up", love::keyboard::Keyboard::KEY_UP},
-		{"down", love::keyboard::Keyboard::KEY_DOWN},
-		{"right", love::keyboard::Keyboard::KEY_RIGHT},
-		{"left", love::keyboard::Keyboard::KEY_LEFT},
-		{"insert", love::keyboard::Keyboard::KEY_INSERT},
-		{"home", love::keyboard::Keyboard::KEY_HOME},
-		{"end", love::keyboard::Keyboard::KEY_END},
-		{"pageup", love::keyboard::Keyboard::KEY_PAGEUP},
-		{"pagedown", love::keyboard::Keyboard::KEY_PAGEDOWN},
-
-		{"f1", love::keyboard::Keyboard::KEY_F1},
-		{"f2", love::keyboard::Keyboard::KEY_F2},
-		{"f3", love::keyboard::Keyboard::KEY_F3},
-		{"f4", love::keyboard::Keyboard::KEY_F4},
-		{"f5", love::keyboard::Keyboard::KEY_F5},
-		{"f6", love::keyboard::Keyboard::KEY_F6},
-		{"f7", love::keyboard::Keyboard::KEY_F7},
-		{"f8", love::keyboard::Keyboard::KEY_F8},
-		{"f9", love::keyboard::Keyboard::KEY_F9},
-		{"f10", love::keyboard::Keyboard::KEY_F10},
-		{"f11", love::keyboard::Keyboard::KEY_F11},
-		{"f12", love::keyboard::Keyboard::KEY_F12},
-		{"f13", love::keyboard::Keyboard::KEY_F13},
-		{"f14", love::keyboard::Keyboard::KEY_F14},
-		{"f15", love::keyboard::Keyboard::KEY_F15},
-
-		{"numlock", love::keyboard::Keyboard::KEY_NUMLOCK},
-		{"capslock", love::keyboard::Keyboard::KEY_CAPSLOCK},
-		{"scrollock", love::keyboard::Keyboard::KEY_SCROLLOCK},
-		{"rshift", love::keyboard::Keyboard::KEY_RSHIFT},
-		{"lshift", love::keyboard::Keyboard::KEY_LSHIFT},
-		{"rctrl", love::keyboard::Keyboard::KEY_RCTRL},
-		{"lctrl", love::keyboard::Keyboard::KEY_LCTRL},
-		{"ralt", love::keyboard::Keyboard::KEY_RALT},
-		{"lalt", love::keyboard::Keyboard::KEY_LALT},
-		{"rmeta", love::keyboard::Keyboard::KEY_RMETA},
-		{"lmeta", love::keyboard::Keyboard::KEY_LMETA},
-		{"lsuper", love::keyboard::Keyboard::KEY_LSUPER},
-		{"rsuper", love::keyboard::Keyboard::KEY_RSUPER},
-		{"mode", love::keyboard::Keyboard::KEY_MODE},
-		{"compose", love::keyboard::Keyboard::KEY_COMPOSE},
-
-		{"help", love::keyboard::Keyboard::KEY_HELP},
-		{"print", love::keyboard::Keyboard::KEY_PRINT},
-		{"sysreq", love::keyboard::Keyboard::KEY_SYSREQ},
-		{"break", love::keyboard::Keyboard::KEY_BREAK},
-		{"menu", love::keyboard::Keyboard::KEY_MENU},
-		{"power", love::keyboard::Keyboard::KEY_POWER},
-		{"euro", love::keyboard::Keyboard::KEY_EURO},
-		{"undo", love::keyboard::Keyboard::KEY_UNDO},
-
-		{"unknown", love::keyboard::Keyboard::KEY_UNKNOWN},
-	};
-
-	StringMap<love::keyboard::Keyboard::Key, love::keyboard::Keyboard::KEY_MAX_ENUM> Event::keys(Event::keyEntries, sizeof(Event::keyEntries));
-
-} // event
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "Event.h"
+
+using love::thread::Mutex;
+using love::thread::Lock;
+
+namespace love
+{
+namespace event
+{
+
+Message::Message(std::string name, Variant *a, Variant *b, Variant *c, Variant *d)
+	: name(name)
+	, nargs(0)
+{
+	args[0] = a;
+	args[1] = b;
+	args[2] = c;
+	args[3] = d;
+	for (int i = 0; i < 4; i++)
+	{
+		if (!args[i])
+			continue;
+		args[i]->retain();
+		nargs++;
+	}
+}
+
+Message::~Message()
+{
+	for (int i = 0; i < nargs; i++)
+		args[i]->release();
+}
+
+int Message::toLua(lua_State *L)
+{
+	luax_pushstring(L, name);
+	for (int i = 0; i < nargs; i++)
+		args[i]->toLua(L);
+	return nargs+1;
+}
+
+Message *Message::fromLua(lua_State *L, int n)
+{
+	std::string name = luax_checkstring(L, n);
+	n++;
+	Message *m = new Message(name);
+	for (int i = 0; i < 4; i++)
+	{
+		if (lua_isnoneornil(L, n+i))
+			break;
+		m->args[i] = Variant::fromLua(L, n+i);
+		if (!m->args[i])
+		{
+			delete m;
+			luaL_error(L, "Argument %d can't be stored safely\nExpected boolean, number, string or userdata.", n+i);
+			return NULL;
+		}
+		m->nargs++;
+	}
+	return m;
+}
+
+Event::~Event()
+{
+}
+
+void Event::push(Message *msg)
+{
+	Lock lock(mutex);
+	msg->retain();
+	queue.push(msg);
+}
+
+bool Event::poll(Message *&msg)
+{
+	Lock lock(mutex);
+	if (queue.empty())
+		return false;
+	msg = queue.front();
+	queue.pop();
+	return true;
+}
+
+void Event::clear()
+{
+	Lock lock(mutex);
+	while (!queue.empty())
+	{
+		queue.back()->release();
+		queue.pop();
+	}
+}
+
+bool Event::getConstant(const char *in, love::mouse::Mouse::Button &out)
+{
+	return buttons.find(in, out);
+}
+
+bool Event::getConstant(love::mouse::Mouse::Button in, const char  *&out)
+{
+	return buttons.find(in, out);
+}
+
+bool Event::getConstant(const char *in, love::keyboard::Keyboard::Key &out)
+{
+	return keys.find(in, out);
+}
+
+bool Event::getConstant(love::keyboard::Keyboard::Key in, const char  *&out)
+{
+	return keys.find(in, out);
+}
+
+StringMap<love::mouse::Mouse::Button, love::mouse::Mouse::BUTTON_MAX_ENUM>::Entry Event::buttonEntries[] =
+{
+	{"l", love::mouse::Mouse::BUTTON_LEFT},
+	{"m", love::mouse::Mouse::BUTTON_MIDDLE},
+	{"r", love::mouse::Mouse::BUTTON_RIGHT},
+	{"wu", love::mouse::Mouse::BUTTON_WHEELUP},
+	{"wd", love::mouse::Mouse::BUTTON_WHEELDOWN},
+	{"x1", love::mouse::Mouse::BUTTON_X1},
+	{"x2", love::mouse::Mouse::BUTTON_X2},
+};
+
+StringMap<love::mouse::Mouse::Button, love::mouse::Mouse::BUTTON_MAX_ENUM> Event::buttons(Event::buttonEntries, sizeof(Event::buttonEntries));
+
+StringMap<love::keyboard::Keyboard::Key, love::keyboard::Keyboard::KEY_MAX_ENUM>::Entry Event::keyEntries[] =
+{
+	{"backspace", love::keyboard::Keyboard::KEY_BACKSPACE},
+	{"tab", love::keyboard::Keyboard::KEY_TAB},
+	{"clear", love::keyboard::Keyboard::KEY_CLEAR},
+	{"return", love::keyboard::Keyboard::KEY_RETURN},
+	{"pause", love::keyboard::Keyboard::KEY_PAUSE},
+	{"escape", love::keyboard::Keyboard::KEY_ESCAPE},
+	{" ", love::keyboard::Keyboard::KEY_SPACE},
+	{"!", love::keyboard::Keyboard::KEY_EXCLAIM},
+	{"\"", love::keyboard::Keyboard::KEY_QUOTEDBL},
+	{"#", love::keyboard::Keyboard::KEY_HASH},
+	{"$", love::keyboard::Keyboard::KEY_DOLLAR},
+	{"&", love::keyboard::Keyboard::KEY_AMPERSAND},
+	{"'", love::keyboard::Keyboard::KEY_QUOTE},
+	{"(", love::keyboard::Keyboard::KEY_LEFTPAREN},
+	{")", love::keyboard::Keyboard::KEY_RIGHTPAREN},
+	{"*", love::keyboard::Keyboard::KEY_ASTERISK},
+	{"+", love::keyboard::Keyboard::KEY_PLUS},
+	{",", love::keyboard::Keyboard::KEY_COMMA},
+	{"-", love::keyboard::Keyboard::KEY_MINUS},
+	{".", love::keyboard::Keyboard::KEY_PERIOD},
+	{"/", love::keyboard::Keyboard::KEY_SLASH},
+	{"0", love::keyboard::Keyboard::KEY_0},
+	{"1", love::keyboard::Keyboard::KEY_1},
+	{"2", love::keyboard::Keyboard::KEY_2},
+	{"3", love::keyboard::Keyboard::KEY_3},
+	{"4", love::keyboard::Keyboard::KEY_4},
+	{"5", love::keyboard::Keyboard::KEY_5},
+	{"6", love::keyboard::Keyboard::KEY_6},
+	{"7", love::keyboard::Keyboard::KEY_7},
+	{"8", love::keyboard::Keyboard::KEY_8},
+	{"9", love::keyboard::Keyboard::KEY_9},
+	{":", love::keyboard::Keyboard::KEY_COLON},
+	{";", love::keyboard::Keyboard::KEY_SEMICOLON},
+	{"<", love::keyboard::Keyboard::KEY_LESS},
+	{"=", love::keyboard::Keyboard::KEY_EQUALS},
+	{">", love::keyboard::Keyboard::KEY_GREATER},
+	{"?", love::keyboard::Keyboard::KEY_QUESTION},
+	{"@", love::keyboard::Keyboard::KEY_AT},
+
+	{"[", love::keyboard::Keyboard::KEY_LEFTBRACKET},
+	{"\\", love::keyboard::Keyboard::KEY_BACKSLASH},
+	{"]", love::keyboard::Keyboard::KEY_RIGHTBRACKET},
+	{"^", love::keyboard::Keyboard::KEY_CARET},
+	{"_", love::keyboard::Keyboard::KEY_UNDERSCORE},
+	{"`", love::keyboard::Keyboard::KEY_BACKQUOTE},
+	{"a", love::keyboard::Keyboard::KEY_A},
+	{"b", love::keyboard::Keyboard::KEY_B},
+	{"c", love::keyboard::Keyboard::KEY_C},
+	{"d", love::keyboard::Keyboard::KEY_D},
+	{"e", love::keyboard::Keyboard::KEY_E},
+	{"f", love::keyboard::Keyboard::KEY_F},
+	{"g", love::keyboard::Keyboard::KEY_G},
+	{"h", love::keyboard::Keyboard::KEY_H},
+	{"i", love::keyboard::Keyboard::KEY_I},
+	{"j", love::keyboard::Keyboard::KEY_J},
+	{"k", love::keyboard::Keyboard::KEY_K},
+	{"l", love::keyboard::Keyboard::KEY_L},
+	{"m", love::keyboard::Keyboard::KEY_M},
+	{"n", love::keyboard::Keyboard::KEY_N},
+	{"o", love::keyboard::Keyboard::KEY_O},
+	{"p", love::keyboard::Keyboard::KEY_P},
+	{"q", love::keyboard::Keyboard::KEY_Q},
+	{"r", love::keyboard::Keyboard::KEY_R},
+	{"s", love::keyboard::Keyboard::KEY_S},
+	{"t", love::keyboard::Keyboard::KEY_T},
+	{"u", love::keyboard::Keyboard::KEY_U},
+	{"v", love::keyboard::Keyboard::KEY_V},
+	{"w", love::keyboard::Keyboard::KEY_W},
+	{"x", love::keyboard::Keyboard::KEY_X},
+	{"y", love::keyboard::Keyboard::KEY_Y},
+	{"z", love::keyboard::Keyboard::KEY_Z},
+	{"delete", love::keyboard::Keyboard::KEY_DELETE},
+
+	{"kp0", love::keyboard::Keyboard::KEY_KP0},
+	{"kp1", love::keyboard::Keyboard::KEY_KP1},
+	{"kp2", love::keyboard::Keyboard::KEY_KP2},
+	{"kp3", love::keyboard::Keyboard::KEY_KP3},
+	{"kp4", love::keyboard::Keyboard::KEY_KP4},
+	{"kp5", love::keyboard::Keyboard::KEY_KP5},
+	{"kp6", love::keyboard::Keyboard::KEY_KP6},
+	{"kp7", love::keyboard::Keyboard::KEY_KP7},
+	{"kp8", love::keyboard::Keyboard::KEY_KP8},
+	{"kp9", love::keyboard::Keyboard::KEY_KP9},
+	{"kp.", love::keyboard::Keyboard::KEY_KP_PERIOD},
+	{"kp/", love::keyboard::Keyboard::KEY_KP_DIVIDE},
+	{"kp*", love::keyboard::Keyboard::KEY_KP_MULTIPLY},
+	{"kp-", love::keyboard::Keyboard::KEY_KP_MINUS},
+	{"kp+", love::keyboard::Keyboard::KEY_KP_PLUS},
+	{"kpenter", love::keyboard::Keyboard::KEY_KP_ENTER},
+	{"kp=", love::keyboard::Keyboard::KEY_KP_EQUALS},
+
+	{"up", love::keyboard::Keyboard::KEY_UP},
+	{"down", love::keyboard::Keyboard::KEY_DOWN},
+	{"right", love::keyboard::Keyboard::KEY_RIGHT},
+	{"left", love::keyboard::Keyboard::KEY_LEFT},
+	{"insert", love::keyboard::Keyboard::KEY_INSERT},
+	{"home", love::keyboard::Keyboard::KEY_HOME},
+	{"end", love::keyboard::Keyboard::KEY_END},
+	{"pageup", love::keyboard::Keyboard::KEY_PAGEUP},
+	{"pagedown", love::keyboard::Keyboard::KEY_PAGEDOWN},
+
+	{"f1", love::keyboard::Keyboard::KEY_F1},
+	{"f2", love::keyboard::Keyboard::KEY_F2},
+	{"f3", love::keyboard::Keyboard::KEY_F3},
+	{"f4", love::keyboard::Keyboard::KEY_F4},
+	{"f5", love::keyboard::Keyboard::KEY_F5},
+	{"f6", love::keyboard::Keyboard::KEY_F6},
+	{"f7", love::keyboard::Keyboard::KEY_F7},
+	{"f8", love::keyboard::Keyboard::KEY_F8},
+	{"f9", love::keyboard::Keyboard::KEY_F9},
+	{"f10", love::keyboard::Keyboard::KEY_F10},
+	{"f11", love::keyboard::Keyboard::KEY_F11},
+	{"f12", love::keyboard::Keyboard::KEY_F12},
+	{"f13", love::keyboard::Keyboard::KEY_F13},
+	{"f14", love::keyboard::Keyboard::KEY_F14},
+	{"f15", love::keyboard::Keyboard::KEY_F15},
+
+	{"numlock", love::keyboard::Keyboard::KEY_NUMLOCK},
+	{"capslock", love::keyboard::Keyboard::KEY_CAPSLOCK},
+	{"scrollock", love::keyboard::Keyboard::KEY_SCROLLOCK},
+	{"rshift", love::keyboard::Keyboard::KEY_RSHIFT},
+	{"lshift", love::keyboard::Keyboard::KEY_LSHIFT},
+	{"rctrl", love::keyboard::Keyboard::KEY_RCTRL},
+	{"lctrl", love::keyboard::Keyboard::KEY_LCTRL},
+	{"ralt", love::keyboard::Keyboard::KEY_RALT},
+	{"lalt", love::keyboard::Keyboard::KEY_LALT},
+	{"rmeta", love::keyboard::Keyboard::KEY_RMETA},
+	{"lmeta", love::keyboard::Keyboard::KEY_LMETA},
+	{"lsuper", love::keyboard::Keyboard::KEY_LSUPER},
+	{"rsuper", love::keyboard::Keyboard::KEY_RSUPER},
+	{"mode", love::keyboard::Keyboard::KEY_MODE},
+	{"compose", love::keyboard::Keyboard::KEY_COMPOSE},
+
+	{"help", love::keyboard::Keyboard::KEY_HELP},
+	{"print", love::keyboard::Keyboard::KEY_PRINT},
+	{"sysreq", love::keyboard::Keyboard::KEY_SYSREQ},
+	{"break", love::keyboard::Keyboard::KEY_BREAK},
+	{"menu", love::keyboard::Keyboard::KEY_MENU},
+	{"power", love::keyboard::Keyboard::KEY_POWER},
+	{"euro", love::keyboard::Keyboard::KEY_EURO},
+	{"undo", love::keyboard::Keyboard::KEY_UNDO},
+
+	{"unknown", love::keyboard::Keyboard::KEY_UNKNOWN},
+};
+
+StringMap<love::keyboard::Keyboard::Key, love::keyboard::Keyboard::KEY_MAX_ENUM> Event::keys(Event::keyEntries, sizeof(Event::keyEntries));
+
+} // event
+} // love

+ 83 - 83
src/modules/event/Event.h

@@ -1,83 +1,83 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_EVENT_EVENT_H
-#define LOVE_EVENT_EVENT_H
-
-// LOVE
-#include <common/Module.h>
-#include <common/StringMap.h>
-#include <common/Variant.h>
-#include <keyboard/Keyboard.h>
-#include <mouse/Mouse.h>
-#include <thread/threads.h>
-
-// STL
-#include <queue>
-
-namespace love
-{
-namespace event
-{
-	class Message : public Object
-	{
-	private:
-		std::string name;
-		Variant *args[4];
-		int nargs;
-
-	public:
-		Message(std::string name, Variant *a = NULL, Variant *b = NULL, Variant *c = NULL, Variant *d = NULL);
-		~Message();
-
-		int toLua(lua_State *L);
-		static Message *fromLua(lua_State *L, int n);
-	};
-
-	class Event : public Module
-	{
-	public:
-		virtual ~Event();
-
-		void push(Message *msg);
-		bool poll(Message *&msg);
-		virtual void clear();
-
-		virtual void pump() = 0;
-
-		static bool getConstant(const char * in, love::mouse::Mouse::Button & out);
-		static bool getConstant(love::mouse::Mouse::Button in, const char *& out);
-		static bool getConstant(const char * in, love::keyboard::Keyboard::Key & out);
-		static bool getConstant(love::keyboard::Keyboard::Key in, const char *& out);
-
-	protected:
-		thread::Mutex mutex;
-		std::queue<Message*> queue;
-		static StringMap<love::mouse::Mouse::Button, love::mouse::Mouse::BUTTON_MAX_ENUM>::Entry buttonEntries[];
-		static StringMap<love::mouse::Mouse::Button, love::mouse::Mouse::BUTTON_MAX_ENUM> buttons;
-		static StringMap<love::keyboard::Keyboard::Key, love::keyboard::Keyboard::KEY_MAX_ENUM>::Entry keyEntries[];
-		static StringMap<love::keyboard::Keyboard::Key, love::keyboard::Keyboard::KEY_MAX_ENUM> keys;
-
-	}; // Event
-
-} // event
-} // love
-
-#endif // LOVE_EVENT_EVENT_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_EVENT_EVENT_H
+#define LOVE_EVENT_EVENT_H
+
+// LOVE
+#include "common/Module.h"
+#include "common/StringMap.h"
+#include "common/Variant.h"
+#include "keyboard/Keyboard.h"
+#include "mouse/Mouse.h"
+#include "thread/threads.h"
+
+// STL
+#include <queue>
+
+namespace love
+{
+namespace event
+{
+class Message : public Object
+{
+private:
+	std::string name;
+	Variant *args[4];
+	int nargs;
+
+public:
+	Message(std::string name, Variant *a = NULL, Variant *b = NULL, Variant *c = NULL, Variant *d = NULL);
+	~Message();
+
+	int toLua(lua_State *L);
+	static Message *fromLua(lua_State *L, int n);
+};
+
+class Event : public Module
+{
+public:
+	virtual ~Event();
+
+	void push(Message *msg);
+	bool poll(Message *&msg);
+	virtual void clear();
+
+	virtual void pump() = 0;
+
+	static bool getConstant(const char *in, love::mouse::Mouse::Button &out);
+	static bool getConstant(love::mouse::Mouse::Button in, const char  *&out);
+	static bool getConstant(const char *in, love::keyboard::Keyboard::Key &out);
+	static bool getConstant(love::keyboard::Keyboard::Key in, const char  *&out);
+
+protected:
+	thread::Mutex mutex;
+	std::queue<Message *> queue;
+	static StringMap<love::mouse::Mouse::Button, love::mouse::Mouse::BUTTON_MAX_ENUM>::Entry buttonEntries[];
+	static StringMap<love::mouse::Mouse::Button, love::mouse::Mouse::BUTTON_MAX_ENUM> buttons;
+	static StringMap<love::keyboard::Keyboard::Key, love::keyboard::Keyboard::KEY_MAX_ENUM>::Entry keyEntries[];
+	static StringMap<love::keyboard::Keyboard::Key, love::keyboard::Keyboard::KEY_MAX_ENUM> keys;
+
+}; // Event
+
+} // event
+} // love
+
+#endif // LOVE_EVENT_EVENT_H

+ 314 - 313
src/modules/event/sdl/Event.cpp

@@ -1,313 +1,314 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "Event.h"
-
-#include <keyboard/Keyboard.h>
-#include <mouse/Mouse.h>
-
-namespace love
-{
-namespace event
-{
-namespace sdl
-{
-	const char * Event::getName() const
-	{
-		return "love.event.sdl";
-	}
-
-	Event::Event()
-	{
-		SDL_EnableUNICODE(1);
-	}
-
-	void Event::pump()
-	{
-		SDL_PumpEvents();
-
-		static SDL_Event e;
-		SDL_EnableUNICODE(1);
-
-		Message *msg;
-
-		while (SDL_PollEvent(&e))
-		{
-			msg = convert(e);
-			if (msg)
-			{
-				push(msg);
-				msg->release();
-			}
-		}
-	}
-
-	Message *Event::wait()
-	{
-		static SDL_Event e;
-		bool ok = (SDL_WaitEvent(&e) == 1);
-		if (!ok)
-			return NULL;
-		return convert(e);
-	}
-
-	void Event::clear()
-	{
-		static SDL_Event e;
-
-		while (SDL_PollEvent(&e))
-		{
-			// Do nothing with 'e' ...
-		}
-
-		love::event::Event::clear();
-	}
-
-	Message *Event::convert(SDL_Event & e)
-	{
-		Message *msg = NULL;
-		love::keyboard::Keyboard::Key key;
-		love::mouse::Mouse::Button button;
-		Variant *arg1, *arg2, *arg3;
-		const char *txt;
-		switch(e.type)
-		{
-		case SDL_KEYDOWN:
-			if (keys.find(e.key.keysym.sym, key) && love::event::Event::keys.find(key, txt))
-			{
-				arg1 = new Variant(txt, strlen(txt));
-				arg2 = new Variant((double) e.key.keysym.unicode);
-				msg = new Message("keypressed", arg1, arg2);
-				arg1->release();
-				arg2->release();
-			}
-			break;
-		case SDL_KEYUP:
-			if (keys.find(e.key.keysym.sym, key) && love::event::Event::keys.find(key, txt))
-			{
-				arg1 = new Variant(txt, strlen(txt));
-				msg = new Message("keyreleased", arg1);
-				arg1->release();
-			}
-			break;
-		case SDL_MOUSEBUTTONDOWN:
-		case SDL_MOUSEBUTTONUP:
-			if (buttons.find(e.button.button, button) && love::event::Event::buttons.find(button, txt))
-			{
-				arg1 = new Variant((double) e.button.x);
-				arg2 = new Variant((double) e.button.y);
-				arg3 = new Variant(txt, strlen(txt));
-				msg = new Message((e.type == SDL_MOUSEBUTTONDOWN) ?
-						"mousepressed" : "mousereleased",
-						arg1, arg2, arg3);
-				arg1->release();
-				arg2->release();
-				arg3->release();
-			}
-			break;
-		case SDL_JOYBUTTONDOWN:
-		case SDL_JOYBUTTONUP:
-			arg1 = new Variant((double) (e.jbutton.which+1));
-			arg2 = new Variant((double) (e.jbutton.button+1));
-			msg = new Message((e.type == SDL_JOYBUTTONDOWN) ?
-					"joystickpressed" : "joystickreleased",
-					arg1, arg2);
-			arg1->release();
-			arg2->release();
-			break;
-		case SDL_ACTIVEEVENT:
-			arg1 = new Variant(e.active.gain != 0);
-			if (e.active.state & SDL_APPINPUTFOCUS)
-				msg = new Message("focus", arg1);
-			arg1->release();
-			break;
-		case SDL_QUIT:
-			msg = new Message("quit");
-			break;
-		}
-
-		return msg;
-	}
-
-	EnumMap<love::keyboard::Keyboard::Key, SDLKey, love::keyboard::Keyboard::KEY_MAX_ENUM>::Entry Event::keyEntries[] =
-	{
-		{ love::keyboard::Keyboard::KEY_BACKSPACE, SDLK_BACKSPACE},
-		{ love::keyboard::Keyboard::KEY_TAB, SDLK_TAB},
-		{ love::keyboard::Keyboard::KEY_CLEAR, SDLK_CLEAR},
-		{ love::keyboard::Keyboard::KEY_RETURN, SDLK_RETURN},
-		{ love::keyboard::Keyboard::KEY_PAUSE, SDLK_PAUSE},
-		{ love::keyboard::Keyboard::KEY_ESCAPE, SDLK_ESCAPE },
-		{ love::keyboard::Keyboard::KEY_SPACE, SDLK_SPACE },
-		{ love::keyboard::Keyboard::KEY_EXCLAIM, SDLK_EXCLAIM },
-		{ love::keyboard::Keyboard::KEY_QUOTEDBL, SDLK_QUOTEDBL },
-		{ love::keyboard::Keyboard::KEY_HASH, SDLK_HASH },
-		{ love::keyboard::Keyboard::KEY_DOLLAR, SDLK_DOLLAR },
-		{ love::keyboard::Keyboard::KEY_AMPERSAND, SDLK_AMPERSAND },
-		{ love::keyboard::Keyboard::KEY_QUOTE, SDLK_QUOTE },
-		{ love::keyboard::Keyboard::KEY_LEFTPAREN, SDLK_LEFTPAREN },
-		{ love::keyboard::Keyboard::KEY_RIGHTPAREN, SDLK_RIGHTPAREN },
-		{ love::keyboard::Keyboard::KEY_ASTERISK, SDLK_ASTERISK },
-		{ love::keyboard::Keyboard::KEY_PLUS, SDLK_PLUS },
-		{ love::keyboard::Keyboard::KEY_COMMA, SDLK_COMMA },
-		{ love::keyboard::Keyboard::KEY_MINUS, SDLK_MINUS },
-		{ love::keyboard::Keyboard::KEY_PERIOD, SDLK_PERIOD },
-		{ love::keyboard::Keyboard::KEY_SLASH, SDLK_SLASH },
-		{ love::keyboard::Keyboard::KEY_0, SDLK_0 },
-		{ love::keyboard::Keyboard::KEY_1, SDLK_1 },
-		{ love::keyboard::Keyboard::KEY_2, SDLK_2 },
-		{ love::keyboard::Keyboard::KEY_3, SDLK_3 },
-		{ love::keyboard::Keyboard::KEY_4, SDLK_4 },
-		{ love::keyboard::Keyboard::KEY_5, SDLK_5 },
-		{ love::keyboard::Keyboard::KEY_6, SDLK_6 },
-		{ love::keyboard::Keyboard::KEY_7, SDLK_7 },
-		{ love::keyboard::Keyboard::KEY_8, SDLK_8 },
-		{ love::keyboard::Keyboard::KEY_9, SDLK_9 },
-		{ love::keyboard::Keyboard::KEY_COLON, SDLK_COLON },
-		{ love::keyboard::Keyboard::KEY_SEMICOLON, SDLK_SEMICOLON },
-		{ love::keyboard::Keyboard::KEY_LESS, SDLK_LESS },
-		{ love::keyboard::Keyboard::KEY_EQUALS, SDLK_EQUALS },
-		{ love::keyboard::Keyboard::KEY_GREATER, SDLK_GREATER },
-		{ love::keyboard::Keyboard::KEY_QUESTION, SDLK_QUESTION },
-		{ love::keyboard::Keyboard::KEY_AT, SDLK_AT },
-
-		{ love::keyboard::Keyboard::KEY_LEFTBRACKET, SDLK_LEFTBRACKET },
-		{ love::keyboard::Keyboard::KEY_BACKSLASH, SDLK_BACKSLASH },
-		{ love::keyboard::Keyboard::KEY_RIGHTBRACKET, SDLK_RIGHTBRACKET },
-		{ love::keyboard::Keyboard::KEY_CARET, SDLK_CARET },
-		{ love::keyboard::Keyboard::KEY_UNDERSCORE, SDLK_UNDERSCORE },
-		{ love::keyboard::Keyboard::KEY_BACKQUOTE, SDLK_BACKQUOTE },
-		{ love::keyboard::Keyboard::KEY_A, SDLK_a },
-		{ love::keyboard::Keyboard::KEY_B, SDLK_b },
-		{ love::keyboard::Keyboard::KEY_C, SDLK_c },
-		{ love::keyboard::Keyboard::KEY_D, SDLK_d },
-		{ love::keyboard::Keyboard::KEY_E, SDLK_e },
-		{ love::keyboard::Keyboard::KEY_F, SDLK_f },
-		{ love::keyboard::Keyboard::KEY_G, SDLK_g },
-		{ love::keyboard::Keyboard::KEY_H, SDLK_h },
-		{ love::keyboard::Keyboard::KEY_I, SDLK_i },
-		{ love::keyboard::Keyboard::KEY_J, SDLK_j },
-		{ love::keyboard::Keyboard::KEY_K, SDLK_k },
-		{ love::keyboard::Keyboard::KEY_L, SDLK_l },
-		{ love::keyboard::Keyboard::KEY_M, SDLK_m },
-		{ love::keyboard::Keyboard::KEY_N, SDLK_n },
-		{ love::keyboard::Keyboard::KEY_O, SDLK_o },
-		{ love::keyboard::Keyboard::KEY_P, SDLK_p },
-		{ love::keyboard::Keyboard::KEY_Q, SDLK_q },
-		{ love::keyboard::Keyboard::KEY_R, SDLK_r },
-		{ love::keyboard::Keyboard::KEY_S, SDLK_s },
-		{ love::keyboard::Keyboard::KEY_T, SDLK_t },
-		{ love::keyboard::Keyboard::KEY_U, SDLK_u },
-		{ love::keyboard::Keyboard::KEY_V, SDLK_v },
-		{ love::keyboard::Keyboard::KEY_W, SDLK_w },
-		{ love::keyboard::Keyboard::KEY_X, SDLK_x },
-		{ love::keyboard::Keyboard::KEY_Y, SDLK_y },
-		{ love::keyboard::Keyboard::KEY_Z, SDLK_z },
-		{ love::keyboard::Keyboard::KEY_DELETE, SDLK_DELETE },
-
-		{ love::keyboard::Keyboard::KEY_KP0, SDLK_KP0 },
-		{ love::keyboard::Keyboard::KEY_KP1, SDLK_KP1 },
-		{ love::keyboard::Keyboard::KEY_KP2, SDLK_KP2 },
-		{ love::keyboard::Keyboard::KEY_KP3, SDLK_KP3 },
-		{ love::keyboard::Keyboard::KEY_KP4, SDLK_KP4 },
-		{ love::keyboard::Keyboard::KEY_KP5, SDLK_KP5 },
-		{ love::keyboard::Keyboard::KEY_KP6, SDLK_KP6 },
-		{ love::keyboard::Keyboard::KEY_KP7, SDLK_KP7 },
-		{ love::keyboard::Keyboard::KEY_KP8, SDLK_KP8 },
-		{ love::keyboard::Keyboard::KEY_KP9, SDLK_KP9 },
-		{ love::keyboard::Keyboard::KEY_KP_PERIOD, SDLK_KP_PERIOD },
-		{ love::keyboard::Keyboard::KEY_KP_DIVIDE, SDLK_KP_DIVIDE },
-		{ love::keyboard::Keyboard::KEY_KP_MULTIPLY, SDLK_KP_MULTIPLY},
-		{ love::keyboard::Keyboard::KEY_KP_MINUS, SDLK_KP_MINUS },
-		{ love::keyboard::Keyboard::KEY_KP_PLUS, SDLK_KP_PLUS },
-		{ love::keyboard::Keyboard::KEY_KP_ENTER, SDLK_KP_ENTER },
-		{ love::keyboard::Keyboard::KEY_KP_EQUALS, SDLK_KP_EQUALS },
-
-		{ love::keyboard::Keyboard::KEY_UP, SDLK_UP },
-		{ love::keyboard::Keyboard::KEY_DOWN, SDLK_DOWN },
-		{ love::keyboard::Keyboard::KEY_RIGHT, SDLK_RIGHT },
-		{ love::keyboard::Keyboard::KEY_LEFT, SDLK_LEFT },
-		{ love::keyboard::Keyboard::KEY_INSERT, SDLK_INSERT },
-		{ love::keyboard::Keyboard::KEY_HOME, SDLK_HOME },
-		{ love::keyboard::Keyboard::KEY_END, SDLK_END },
-		{ love::keyboard::Keyboard::KEY_PAGEUP, SDLK_PAGEUP },
-		{ love::keyboard::Keyboard::KEY_PAGEDOWN, SDLK_PAGEDOWN },
-
-		{ love::keyboard::Keyboard::KEY_F1, SDLK_F1 },
-		{ love::keyboard::Keyboard::KEY_F2, SDLK_F2 },
-		{ love::keyboard::Keyboard::KEY_F3, SDLK_F3 },
-		{ love::keyboard::Keyboard::KEY_F4, SDLK_F4 },
-		{ love::keyboard::Keyboard::KEY_F5, SDLK_F5 },
-		{ love::keyboard::Keyboard::KEY_F6, SDLK_F6 },
-		{ love::keyboard::Keyboard::KEY_F7, SDLK_F7 },
-		{ love::keyboard::Keyboard::KEY_F8, SDLK_F8 },
-		{ love::keyboard::Keyboard::KEY_F9, SDLK_F9 },
-		{ love::keyboard::Keyboard::KEY_F10, SDLK_F10 },
-		{ love::keyboard::Keyboard::KEY_F11, SDLK_F11 },
-		{ love::keyboard::Keyboard::KEY_F12, SDLK_F12 },
-		{ love::keyboard::Keyboard::KEY_F13, SDLK_F13 },
-		{ love::keyboard::Keyboard::KEY_F14, SDLK_F14 },
-		{ love::keyboard::Keyboard::KEY_F15, SDLK_F15 },
-
-		{ love::keyboard::Keyboard::KEY_NUMLOCK, SDLK_NUMLOCK },
-		{ love::keyboard::Keyboard::KEY_CAPSLOCK, SDLK_CAPSLOCK },
-		{ love::keyboard::Keyboard::KEY_SCROLLOCK, SDLK_SCROLLOCK },
-		{ love::keyboard::Keyboard::KEY_RSHIFT, SDLK_RSHIFT },
-		{ love::keyboard::Keyboard::KEY_LSHIFT, SDLK_LSHIFT },
-		{ love::keyboard::Keyboard::KEY_RCTRL, SDLK_RCTRL },
-		{ love::keyboard::Keyboard::KEY_LCTRL, SDLK_LCTRL },
-		{ love::keyboard::Keyboard::KEY_RALT, SDLK_RALT },
-		{ love::keyboard::Keyboard::KEY_LALT, SDLK_LALT },
-		{ love::keyboard::Keyboard::KEY_RMETA, SDLK_RMETA },
-		{ love::keyboard::Keyboard::KEY_LMETA, SDLK_LMETA },
-		{ love::keyboard::Keyboard::KEY_LSUPER, SDLK_LSUPER },
-		{ love::keyboard::Keyboard::KEY_RSUPER, SDLK_RSUPER },
-		{ love::keyboard::Keyboard::KEY_MODE, SDLK_MODE },
-		{ love::keyboard::Keyboard::KEY_COMPOSE, SDLK_COMPOSE },
-
-		{ love::keyboard::Keyboard::KEY_HELP, SDLK_HELP },
-		{ love::keyboard::Keyboard::KEY_PRINT, SDLK_PRINT },
-		{ love::keyboard::Keyboard::KEY_SYSREQ, SDLK_SYSREQ },
-		{ love::keyboard::Keyboard::KEY_BREAK, SDLK_BREAK },
-		{ love::keyboard::Keyboard::KEY_MENU, SDLK_MENU },
-		{ love::keyboard::Keyboard::KEY_POWER, SDLK_POWER },
-		{ love::keyboard::Keyboard::KEY_EURO, SDLK_EURO },
-		{ love::keyboard::Keyboard::KEY_UNDO, SDLK_UNDO },
-
-		{ love::keyboard::Keyboard::KEY_UNKNOWN, SDLK_UNKNOWN },
-	};
-
-	EnumMap<love::keyboard::Keyboard::Key, SDLKey, love::keyboard::Keyboard::KEY_MAX_ENUM> Event::keys(Event::keyEntries, sizeof(Event::keyEntries));
-
-	EnumMap<love::mouse::Mouse::Button, Uint8, love::mouse::Mouse::BUTTON_MAX_ENUM>::Entry Event::buttonEntries[] =
-	{
-		{ love::mouse::Mouse::BUTTON_LEFT, SDL_BUTTON_LEFT},
-		{ love::mouse::Mouse::BUTTON_MIDDLE, SDL_BUTTON_MIDDLE},
-		{ love::mouse::Mouse::BUTTON_RIGHT, SDL_BUTTON_RIGHT},
-		{ love::mouse::Mouse::BUTTON_WHEELUP, SDL_BUTTON_WHEELUP},
-		{ love::mouse::Mouse::BUTTON_WHEELDOWN, SDL_BUTTON_WHEELDOWN},
-		{ love::mouse::Mouse::BUTTON_X1, SDL_BUTTON_X1},
-		{ love::mouse::Mouse::BUTTON_X2, SDL_BUTTON_X2},
-	};
-
-	EnumMap<love::mouse::Mouse::Button, Uint8, love::mouse::Mouse::BUTTON_MAX_ENUM> Event::buttons(Event::buttonEntries, sizeof(Event::buttonEntries));
-
-} // sdl
-} // event
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "Event.h"
+
+#include "keyboard/Keyboard.h"
+#include "mouse/Mouse.h"
+
+namespace love
+{
+namespace event
+{
+namespace sdl
+{
+
+const char *Event::getName() const
+{
+	return "love.event.sdl";
+}
+
+Event::Event()
+{
+	SDL_EnableUNICODE(1);
+}
+
+void Event::pump()
+{
+	SDL_PumpEvents();
+
+	static SDL_Event e;
+	SDL_EnableUNICODE(1);
+
+	Message *msg;
+
+	while (SDL_PollEvent(&e))
+	{
+		msg = convert(e);
+		if (msg)
+		{
+			push(msg);
+			msg->release();
+		}
+	}
+}
+
+Message *Event::wait()
+{
+	static SDL_Event e;
+	bool ok = (SDL_WaitEvent(&e) == 1);
+	if (!ok)
+		return NULL;
+	return convert(e);
+}
+
+void Event::clear()
+{
+	static SDL_Event e;
+
+	while (SDL_PollEvent(&e))
+	{
+		// Do nothing with 'e' ...
+	}
+
+	love::event::Event::clear();
+}
+
+Message *Event::convert(SDL_Event &e)
+{
+	Message *msg = NULL;
+	love::keyboard::Keyboard::Key key;
+	love::mouse::Mouse::Button button;
+	Variant *arg1, *arg2, *arg3;
+	const char *txt;
+	switch (e.type)
+	{
+	case SDL_KEYDOWN:
+		if (keys.find(e.key.keysym.sym, key) && love::event::Event::keys.find(key, txt))
+		{
+			arg1 = new Variant(txt, strlen(txt));
+			arg2 = new Variant((double) e.key.keysym.unicode);
+			msg = new Message("keypressed", arg1, arg2);
+			arg1->release();
+			arg2->release();
+		}
+		break;
+	case SDL_KEYUP:
+		if (keys.find(e.key.keysym.sym, key) && love::event::Event::keys.find(key, txt))
+		{
+			arg1 = new Variant(txt, strlen(txt));
+			msg = new Message("keyreleased", arg1);
+			arg1->release();
+		}
+		break;
+	case SDL_MOUSEBUTTONDOWN:
+	case SDL_MOUSEBUTTONUP:
+		if (buttons.find(e.button.button, button) && love::event::Event::buttons.find(button, txt))
+		{
+			arg1 = new Variant((double) e.button.x);
+			arg2 = new Variant((double) e.button.y);
+			arg3 = new Variant(txt, strlen(txt));
+			msg = new Message((e.type == SDL_MOUSEBUTTONDOWN) ?
+							  "mousepressed" : "mousereleased",
+							  arg1, arg2, arg3);
+			arg1->release();
+			arg2->release();
+			arg3->release();
+		}
+		break;
+	case SDL_JOYBUTTONDOWN:
+	case SDL_JOYBUTTONUP:
+		arg1 = new Variant((double)(e.jbutton.which+1));
+		arg2 = new Variant((double)(e.jbutton.button+1));
+		msg = new Message((e.type == SDL_JOYBUTTONDOWN) ?
+						  "joystickpressed" : "joystickreleased",
+						  arg1, arg2);
+		arg1->release();
+		arg2->release();
+		break;
+	case SDL_ACTIVEEVENT:
+		arg1 = new Variant(e.active.gain != 0);
+		if (e.active.state & SDL_APPINPUTFOCUS)
+			msg = new Message("focus", arg1);
+		arg1->release();
+		break;
+	case SDL_QUIT:
+		msg = new Message("quit");
+		break;
+	}
+
+	return msg;
+}
+
+EnumMap<love::keyboard::Keyboard::Key, SDLKey, love::keyboard::Keyboard::KEY_MAX_ENUM>::Entry Event::keyEntries[] =
+{
+	{ love::keyboard::Keyboard::KEY_BACKSPACE, SDLK_BACKSPACE},
+	{ love::keyboard::Keyboard::KEY_TAB, SDLK_TAB},
+	{ love::keyboard::Keyboard::KEY_CLEAR, SDLK_CLEAR},
+	{ love::keyboard::Keyboard::KEY_RETURN, SDLK_RETURN},
+	{ love::keyboard::Keyboard::KEY_PAUSE, SDLK_PAUSE},
+	{ love::keyboard::Keyboard::KEY_ESCAPE, SDLK_ESCAPE },
+	{ love::keyboard::Keyboard::KEY_SPACE, SDLK_SPACE },
+	{ love::keyboard::Keyboard::KEY_EXCLAIM, SDLK_EXCLAIM },
+	{ love::keyboard::Keyboard::KEY_QUOTEDBL, SDLK_QUOTEDBL },
+	{ love::keyboard::Keyboard::KEY_HASH, SDLK_HASH },
+	{ love::keyboard::Keyboard::KEY_DOLLAR, SDLK_DOLLAR },
+	{ love::keyboard::Keyboard::KEY_AMPERSAND, SDLK_AMPERSAND },
+	{ love::keyboard::Keyboard::KEY_QUOTE, SDLK_QUOTE },
+	{ love::keyboard::Keyboard::KEY_LEFTPAREN, SDLK_LEFTPAREN },
+	{ love::keyboard::Keyboard::KEY_RIGHTPAREN, SDLK_RIGHTPAREN },
+	{ love::keyboard::Keyboard::KEY_ASTERISK, SDLK_ASTERISK },
+	{ love::keyboard::Keyboard::KEY_PLUS, SDLK_PLUS },
+	{ love::keyboard::Keyboard::KEY_COMMA, SDLK_COMMA },
+	{ love::keyboard::Keyboard::KEY_MINUS, SDLK_MINUS },
+	{ love::keyboard::Keyboard::KEY_PERIOD, SDLK_PERIOD },
+	{ love::keyboard::Keyboard::KEY_SLASH, SDLK_SLASH },
+	{ love::keyboard::Keyboard::KEY_0, SDLK_0 },
+	{ love::keyboard::Keyboard::KEY_1, SDLK_1 },
+	{ love::keyboard::Keyboard::KEY_2, SDLK_2 },
+	{ love::keyboard::Keyboard::KEY_3, SDLK_3 },
+	{ love::keyboard::Keyboard::KEY_4, SDLK_4 },
+	{ love::keyboard::Keyboard::KEY_5, SDLK_5 },
+	{ love::keyboard::Keyboard::KEY_6, SDLK_6 },
+	{ love::keyboard::Keyboard::KEY_7, SDLK_7 },
+	{ love::keyboard::Keyboard::KEY_8, SDLK_8 },
+	{ love::keyboard::Keyboard::KEY_9, SDLK_9 },
+	{ love::keyboard::Keyboard::KEY_COLON, SDLK_COLON },
+	{ love::keyboard::Keyboard::KEY_SEMICOLON, SDLK_SEMICOLON },
+	{ love::keyboard::Keyboard::KEY_LESS, SDLK_LESS },
+	{ love::keyboard::Keyboard::KEY_EQUALS, SDLK_EQUALS },
+	{ love::keyboard::Keyboard::KEY_GREATER, SDLK_GREATER },
+	{ love::keyboard::Keyboard::KEY_QUESTION, SDLK_QUESTION },
+	{ love::keyboard::Keyboard::KEY_AT, SDLK_AT },
+
+	{ love::keyboard::Keyboard::KEY_LEFTBRACKET, SDLK_LEFTBRACKET },
+	{ love::keyboard::Keyboard::KEY_BACKSLASH, SDLK_BACKSLASH },
+	{ love::keyboard::Keyboard::KEY_RIGHTBRACKET, SDLK_RIGHTBRACKET },
+	{ love::keyboard::Keyboard::KEY_CARET, SDLK_CARET },
+	{ love::keyboard::Keyboard::KEY_UNDERSCORE, SDLK_UNDERSCORE },
+	{ love::keyboard::Keyboard::KEY_BACKQUOTE, SDLK_BACKQUOTE },
+	{ love::keyboard::Keyboard::KEY_A, SDLK_a },
+	{ love::keyboard::Keyboard::KEY_B, SDLK_b },
+	{ love::keyboard::Keyboard::KEY_C, SDLK_c },
+	{ love::keyboard::Keyboard::KEY_D, SDLK_d },
+	{ love::keyboard::Keyboard::KEY_E, SDLK_e },
+	{ love::keyboard::Keyboard::KEY_F, SDLK_f },
+	{ love::keyboard::Keyboard::KEY_G, SDLK_g },
+	{ love::keyboard::Keyboard::KEY_H, SDLK_h },
+	{ love::keyboard::Keyboard::KEY_I, SDLK_i },
+	{ love::keyboard::Keyboard::KEY_J, SDLK_j },
+	{ love::keyboard::Keyboard::KEY_K, SDLK_k },
+	{ love::keyboard::Keyboard::KEY_L, SDLK_l },
+	{ love::keyboard::Keyboard::KEY_M, SDLK_m },
+	{ love::keyboard::Keyboard::KEY_N, SDLK_n },
+	{ love::keyboard::Keyboard::KEY_O, SDLK_o },
+	{ love::keyboard::Keyboard::KEY_P, SDLK_p },
+	{ love::keyboard::Keyboard::KEY_Q, SDLK_q },
+	{ love::keyboard::Keyboard::KEY_R, SDLK_r },
+	{ love::keyboard::Keyboard::KEY_S, SDLK_s },
+	{ love::keyboard::Keyboard::KEY_T, SDLK_t },
+	{ love::keyboard::Keyboard::KEY_U, SDLK_u },
+	{ love::keyboard::Keyboard::KEY_V, SDLK_v },
+	{ love::keyboard::Keyboard::KEY_W, SDLK_w },
+	{ love::keyboard::Keyboard::KEY_X, SDLK_x },
+	{ love::keyboard::Keyboard::KEY_Y, SDLK_y },
+	{ love::keyboard::Keyboard::KEY_Z, SDLK_z },
+	{ love::keyboard::Keyboard::KEY_DELETE, SDLK_DELETE },
+
+	{ love::keyboard::Keyboard::KEY_KP0, SDLK_KP0 },
+	{ love::keyboard::Keyboard::KEY_KP1, SDLK_KP1 },
+	{ love::keyboard::Keyboard::KEY_KP2, SDLK_KP2 },
+	{ love::keyboard::Keyboard::KEY_KP3, SDLK_KP3 },
+	{ love::keyboard::Keyboard::KEY_KP4, SDLK_KP4 },
+	{ love::keyboard::Keyboard::KEY_KP5, SDLK_KP5 },
+	{ love::keyboard::Keyboard::KEY_KP6, SDLK_KP6 },
+	{ love::keyboard::Keyboard::KEY_KP7, SDLK_KP7 },
+	{ love::keyboard::Keyboard::KEY_KP8, SDLK_KP8 },
+	{ love::keyboard::Keyboard::KEY_KP9, SDLK_KP9 },
+	{ love::keyboard::Keyboard::KEY_KP_PERIOD, SDLK_KP_PERIOD },
+	{ love::keyboard::Keyboard::KEY_KP_DIVIDE, SDLK_KP_DIVIDE },
+	{ love::keyboard::Keyboard::KEY_KP_MULTIPLY, SDLK_KP_MULTIPLY},
+	{ love::keyboard::Keyboard::KEY_KP_MINUS, SDLK_KP_MINUS },
+	{ love::keyboard::Keyboard::KEY_KP_PLUS, SDLK_KP_PLUS },
+	{ love::keyboard::Keyboard::KEY_KP_ENTER, SDLK_KP_ENTER },
+	{ love::keyboard::Keyboard::KEY_KP_EQUALS, SDLK_KP_EQUALS },
+
+	{ love::keyboard::Keyboard::KEY_UP, SDLK_UP },
+	{ love::keyboard::Keyboard::KEY_DOWN, SDLK_DOWN },
+	{ love::keyboard::Keyboard::KEY_RIGHT, SDLK_RIGHT },
+	{ love::keyboard::Keyboard::KEY_LEFT, SDLK_LEFT },
+	{ love::keyboard::Keyboard::KEY_INSERT, SDLK_INSERT },
+	{ love::keyboard::Keyboard::KEY_HOME, SDLK_HOME },
+	{ love::keyboard::Keyboard::KEY_END, SDLK_END },
+	{ love::keyboard::Keyboard::KEY_PAGEUP, SDLK_PAGEUP },
+	{ love::keyboard::Keyboard::KEY_PAGEDOWN, SDLK_PAGEDOWN },
+
+	{ love::keyboard::Keyboard::KEY_F1, SDLK_F1 },
+	{ love::keyboard::Keyboard::KEY_F2, SDLK_F2 },
+	{ love::keyboard::Keyboard::KEY_F3, SDLK_F3 },
+	{ love::keyboard::Keyboard::KEY_F4, SDLK_F4 },
+	{ love::keyboard::Keyboard::KEY_F5, SDLK_F5 },
+	{ love::keyboard::Keyboard::KEY_F6, SDLK_F6 },
+	{ love::keyboard::Keyboard::KEY_F7, SDLK_F7 },
+	{ love::keyboard::Keyboard::KEY_F8, SDLK_F8 },
+	{ love::keyboard::Keyboard::KEY_F9, SDLK_F9 },
+	{ love::keyboard::Keyboard::KEY_F10, SDLK_F10 },
+	{ love::keyboard::Keyboard::KEY_F11, SDLK_F11 },
+	{ love::keyboard::Keyboard::KEY_F12, SDLK_F12 },
+	{ love::keyboard::Keyboard::KEY_F13, SDLK_F13 },
+	{ love::keyboard::Keyboard::KEY_F14, SDLK_F14 },
+	{ love::keyboard::Keyboard::KEY_F15, SDLK_F15 },
+
+	{ love::keyboard::Keyboard::KEY_NUMLOCK, SDLK_NUMLOCK },
+	{ love::keyboard::Keyboard::KEY_CAPSLOCK, SDLK_CAPSLOCK },
+	{ love::keyboard::Keyboard::KEY_SCROLLOCK, SDLK_SCROLLOCK },
+	{ love::keyboard::Keyboard::KEY_RSHIFT, SDLK_RSHIFT },
+	{ love::keyboard::Keyboard::KEY_LSHIFT, SDLK_LSHIFT },
+	{ love::keyboard::Keyboard::KEY_RCTRL, SDLK_RCTRL },
+	{ love::keyboard::Keyboard::KEY_LCTRL, SDLK_LCTRL },
+	{ love::keyboard::Keyboard::KEY_RALT, SDLK_RALT },
+	{ love::keyboard::Keyboard::KEY_LALT, SDLK_LALT },
+	{ love::keyboard::Keyboard::KEY_RMETA, SDLK_RMETA },
+	{ love::keyboard::Keyboard::KEY_LMETA, SDLK_LMETA },
+	{ love::keyboard::Keyboard::KEY_LSUPER, SDLK_LSUPER },
+	{ love::keyboard::Keyboard::KEY_RSUPER, SDLK_RSUPER },
+	{ love::keyboard::Keyboard::KEY_MODE, SDLK_MODE },
+	{ love::keyboard::Keyboard::KEY_COMPOSE, SDLK_COMPOSE },
+
+	{ love::keyboard::Keyboard::KEY_HELP, SDLK_HELP },
+	{ love::keyboard::Keyboard::KEY_PRINT, SDLK_PRINT },
+	{ love::keyboard::Keyboard::KEY_SYSREQ, SDLK_SYSREQ },
+	{ love::keyboard::Keyboard::KEY_BREAK, SDLK_BREAK },
+	{ love::keyboard::Keyboard::KEY_MENU, SDLK_MENU },
+	{ love::keyboard::Keyboard::KEY_POWER, SDLK_POWER },
+	{ love::keyboard::Keyboard::KEY_EURO, SDLK_EURO },
+	{ love::keyboard::Keyboard::KEY_UNDO, SDLK_UNDO },
+
+	{ love::keyboard::Keyboard::KEY_UNKNOWN, SDLK_UNKNOWN },
+};
+
+EnumMap<love::keyboard::Keyboard::Key, SDLKey, love::keyboard::Keyboard::KEY_MAX_ENUM> Event::keys(Event::keyEntries, sizeof(Event::keyEntries));
+
+EnumMap<love::mouse::Mouse::Button, Uint8, love::mouse::Mouse::BUTTON_MAX_ENUM>::Entry Event::buttonEntries[] =
+{
+	{ love::mouse::Mouse::BUTTON_LEFT, SDL_BUTTON_LEFT},
+	{ love::mouse::Mouse::BUTTON_MIDDLE, SDL_BUTTON_MIDDLE},
+	{ love::mouse::Mouse::BUTTON_RIGHT, SDL_BUTTON_RIGHT},
+	{ love::mouse::Mouse::BUTTON_WHEELUP, SDL_BUTTON_WHEELUP},
+	{ love::mouse::Mouse::BUTTON_WHEELDOWN, SDL_BUTTON_WHEELDOWN},
+	{ love::mouse::Mouse::BUTTON_X1, SDL_BUTTON_X1},
+	{ love::mouse::Mouse::BUTTON_X2, SDL_BUTTON_X2},
+};
+
+EnumMap<love::mouse::Mouse::Button, Uint8, love::mouse::Mouse::BUTTON_MAX_ENUM> Event::buttons(Event::buttonEntries, sizeof(Event::buttonEntries));
+
+} // sdl
+} // event
+} // love

+ 82 - 81
src/modules/event/sdl/Event.h

@@ -1,81 +1,82 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_EVENT_SDL_EVENT_H
-#define LOVE_EVENT_SDL_EVENT_H
-
-// LOVE
-#include <event/Event.h>
-#include <common/runtime.h>
-#include <common/EnumMap.h>
-
-// SDL
-#include <SDL.h>
-
-namespace love
-{
-namespace event
-{
-namespace sdl
-{
-	class Event : public love::event::Event
-	{
-	public:
-
-		// Implements Module.
-		const char * getName() const;
-
-		Event();
-
-		/**
-		* Pumps the event queue. This function gathers all the pending input information
-		* from devices and places it on the event queue. Normally not needed if you poll
-		* for events.
-		**/
-		void pump();
-
-		/**
-		* Waits for the next event (indefinitely). Useful for creating games where
-		* the screen and game state only needs updating when the user interacts with
-		* the window.
-		**/
-		Message *wait();
-
-		/**
-		 * Clears the event queue.
-		 */
-		void clear();
-
-	private:
-
-		Message *convert(SDL_Event & e);
-
-		static EnumMap<love::keyboard::Keyboard::Key, SDLKey, love::keyboard::Keyboard::KEY_MAX_ENUM>::Entry keyEntries[];
-		static EnumMap<love::keyboard::Keyboard::Key, SDLKey, love::keyboard::Keyboard::KEY_MAX_ENUM> keys;
-		static EnumMap<love::mouse::Mouse::Button, Uint8, love::mouse::Mouse::BUTTON_MAX_ENUM>::Entry buttonEntries[];
-		static EnumMap<love::mouse::Mouse::Button, Uint8, love::mouse::Mouse::BUTTON_MAX_ENUM> buttons;
-
-	}; // System
-
-} // sdl
-} // event
-} // love
-
-#endif // LOVE_EVENT_SDL_EVENT_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_EVENT_SDL_EVENT_H
+#define LOVE_EVENT_SDL_EVENT_H
+
+// LOVE
+#include "event/Event.h"
+#include "common/runtime.h"
+#include "common/EnumMap.h"
+
+// SDL
+#include <SDL.h>
+
+namespace love
+{
+namespace event
+{
+namespace sdl
+{
+
+class Event : public love::event::Event
+{
+public:
+
+	// Implements Module.
+	const char *getName() const;
+
+	Event();
+
+	/**
+	 * Pumps the event queue. This function gathers all the pending input information
+	 * from devices and places it on the event queue. Normally not needed if you poll
+	 * for events.
+	 **/
+	void pump();
+
+	/**
+	 * Waits for the next event (indefinitely). Useful for creating games where
+	 * the screen and game state only needs updating when the user interacts with
+	 * the window.
+	 **/
+	Message *wait();
+
+	/**
+	 * Clears the event queue.
+	 */
+	void clear();
+
+private:
+
+	Message *convert(SDL_Event &e);
+
+	static EnumMap<love::keyboard::Keyboard::Key, SDLKey, love::keyboard::Keyboard::KEY_MAX_ENUM>::Entry keyEntries[];
+	static EnumMap<love::keyboard::Keyboard::Key, SDLKey, love::keyboard::Keyboard::KEY_MAX_ENUM> keys;
+	static EnumMap<love::mouse::Mouse::Button, Uint8, love::mouse::Mouse::BUTTON_MAX_ENUM>::Entry buttonEntries[];
+	static EnumMap<love::mouse::Mouse::Button, Uint8, love::mouse::Mouse::BUTTON_MAX_ENUM> buttons;
+
+}; // System
+
+} // sdl
+} // event
+} // love
+
+#endif // LOVE_EVENT_SDL_EVENT_H

+ 150 - 148
src/modules/event/sdl/wrap_Event.cpp

@@ -1,148 +1,150 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "wrap_Event.h"
-
-// LOVE
-#include <common/runtime.h>
-
-// sdlevent
-#include "Event.h"
-
-namespace love
-{
-namespace event
-{
-namespace sdl
-{
-	static Event * instance = 0;
-
-	static int poll_i(lua_State * L)
-	{
-		Message *m;
-
-		while (instance->poll(m))
-		{
-			int args = m->toLua(L);
-			m->release();
-			return args;
-		}
-
-		// No pending events.
-		return 0;
-	}
-
-	int w_pump(lua_State *)
-	{
-		instance->pump();
-		return 0;
-	}
-
-	int w_poll(lua_State * L)
-	{
-		lua_pushcclosure(L, &poll_i, 0);
-		return 1;
-	}
-
-	int w_wait(lua_State * L)
-	{
-		static Message *m;
-
-		if ((m = instance->wait()))
-		{
-			int args = m->toLua(L);
-			m->release();
-			return args;
-		}
-
-		return 0;
-	}
-
-	int w_push(lua_State * L)
-	{
-		static Message *m;
-
-		bool success = (m = Message::fromLua(L, 1)) != NULL;
-		luax_pushboolean(L, success);
-
-		if (!success)
-			return 1;
-
-		instance->push(m);
-		m->release();
-
-		return 1;
-	}
-
-	int w_clear(lua_State *)
-	{
-		instance->clear();
-		return 0;
-	}
-
-	int w_quit(lua_State * L)
-	{
-		Message *m = new Message("quit");
-		instance->push(m);
-		m->release();
-		luax_pushboolean(L, true);
-		return 1;
-	}
-
-	// List of functions to wrap.
-	static const luaL_Reg functions[] = {
-		{ "pump", w_pump },
-		{ "poll", w_poll },
-		{ "wait", w_wait },
-		{ "push", w_push },
-		{ "clear", w_clear },
-		{ "quit", w_quit },
-		{ 0, 0 }
-	};
-
-	extern "C" int luaopen_love_event(lua_State * L)
-	{
-		if (instance == 0)
-		{
-			try
-			{
-				instance = new Event();
-			}
-			catch (Exception & e)
-			{
-				return luaL_error(L, e.what());
-			}
-		}
-		else
-			instance->retain();
-
-		WrappedModule w;
-		w.module = instance;
-		w.name = "event";
-		w.flags = MODULE_T;
-		w.functions = functions;
-		w.types = 0;
-
-		return luax_register_module(L, w);
-	}
-
-} // sdl
-} // event
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "wrap_Event.h"
+
+// LOVE
+#include "common/runtime.h"
+
+// sdlevent
+#include "Event.h"
+
+namespace love
+{
+namespace event
+{
+namespace sdl
+{
+
+static Event *instance = 0;
+
+static int poll_i(lua_State *L)
+{
+	Message *m;
+
+	while (instance->poll(m))
+	{
+		int args = m->toLua(L);
+		m->release();
+		return args;
+	}
+
+	// No pending events.
+	return 0;
+}
+
+int w_pump(lua_State *)
+{
+	instance->pump();
+	return 0;
+}
+
+int w_poll(lua_State *L)
+{
+	lua_pushcclosure(L, &poll_i, 0);
+	return 1;
+}
+
+int w_wait(lua_State *L)
+{
+	static Message *m;
+
+	if ((m = instance->wait()))
+	{
+		int args = m->toLua(L);
+		m->release();
+		return args;
+	}
+
+	return 0;
+}
+
+int w_push(lua_State *L)
+{
+	static Message *m;
+
+	bool success = (m = Message::fromLua(L, 1)) != NULL;
+	luax_pushboolean(L, success);
+
+	if (!success)
+		return 1;
+
+	instance->push(m);
+	m->release();
+
+	return 1;
+}
+
+int w_clear(lua_State *)
+{
+	instance->clear();
+	return 0;
+}
+
+int w_quit(lua_State *L)
+{
+	Message *m = new Message("quit");
+	instance->push(m);
+	m->release();
+	luax_pushboolean(L, true);
+	return 1;
+}
+
+// List of functions to wrap.
+static const luaL_Reg functions[] =
+{
+	{ "pump", w_pump },
+	{ "poll", w_poll },
+	{ "wait", w_wait },
+	{ "push", w_push },
+	{ "clear", w_clear },
+	{ "quit", w_quit },
+	{ 0, 0 }
+};
+
+extern "C" int luaopen_love_event(lua_State *L)
+{
+	if (instance == 0)
+	{
+		try
+		{
+			instance = new Event();
+		}
+		catch(Exception &e)
+		{
+			return luaL_error(L, e.what());
+		}
+	}
+	else
+		instance->retain();
+
+	WrappedModule w;
+	w.module = instance;
+	w.name = "event";
+	w.flags = MODULE_T;
+	w.functions = functions;
+	w.types = 0;
+
+	return luax_register_module(L, w);
+}
+
+} // sdl
+} // event
+} // love

+ 48 - 47
src/modules/event/sdl/wrap_Event.h

@@ -1,47 +1,48 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_EVENT_SDL_WRAP_EVENT_H
-#define LOVE_EVENT_SDL_WRAP_EVENT_H
-
-// LOVE
-#include <common/config.h>
-#include "Event.h"
-
-namespace love
-{
-namespace event
-{
-namespace sdl
-{
-	int w_pump(lua_State * L);
-	int w_poll(lua_State * L);
-	int w_wait(lua_State * L);
-	int w_push(lua_State * L);
-	int w_clear(lua_State * L);
-	int w_quit(lua_State * L);
-
-	extern "C" LOVE_EXPORT int luaopen_love_event(lua_State * L);
-
-} // sdl
-} // event
-} // love
-
-#endif // LOVE_EVENT_SDL_WRAP_EVENT_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_EVENT_SDL_WRAP_EVENT_H
+#define LOVE_EVENT_SDL_WRAP_EVENT_H
+
+// LOVE
+#include "common/config.h"
+#include "Event.h"
+
+namespace love
+{
+namespace event
+{
+namespace sdl
+{
+
+int w_pump(lua_State *L);
+int w_poll(lua_State *L);
+int w_wait(lua_State *L);
+int w_push(lua_State *L);
+int w_clear(lua_State *L);
+int w_quit(lua_State *L);
+
+extern "C" LOVE_EXPORT int luaopen_love_event(lua_State *L);
+
+} // sdl
+} // event
+} // love
+
+#endif // LOVE_EVENT_SDL_WRAP_EVENT_H

+ 53 - 52
src/modules/filesystem/File.cpp

@@ -1,52 +1,53 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "File.h"
-
-namespace love
-{
-namespace filesystem
-{
-	File::~File()
-	{
-	}
-
-	bool File::getConstant(const char * in, Mode & out)
-	{
-		return modes.find(in, out);
-	}
-
-	bool File::getConstant(Mode in, const char *& out)
-	{
-		return modes.find(in, out);
-	}
-
-	StringMap<File::Mode, File::MODE_MAX_ENUM>::Entry File::modeEntries[] =
-	{
-		{"c", File::CLOSED},
-		{"r", File::READ},
-		{"w", File::WRITE},
-		{"a", File::APPEND},
-	};
-
-	StringMap<File::Mode, File::MODE_MAX_ENUM> File::modes(File::modeEntries, sizeof(File::modeEntries));
-
-} // filesystem
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "File.h"
+
+namespace love
+{
+namespace filesystem
+{
+
+File::~File()
+{
+}
+
+bool File::getConstant(const char *in, Mode &out)
+{
+	return modes.find(in, out);
+}
+
+bool File::getConstant(Mode in, const char  *&out)
+{
+	return modes.find(in, out);
+}
+
+StringMap<File::Mode, File::MODE_MAX_ENUM>::Entry File::modeEntries[] =
+{
+	{"c", File::CLOSED},
+	{"r", File::READ},
+	{"w", File::WRITE},
+	{"a", File::APPEND},
+};
+
+StringMap<File::Mode, File::MODE_MAX_ENUM> File::modes(File::modeEntries, sizeof(File::modeEntries));
+
+} // filesystem
+} // love

+ 178 - 177
src/modules/filesystem/File.h

@@ -1,177 +1,178 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_FILESYSTEM_FILE_H
-#define LOVE_FILESYSTEM_FILE_H
-
-// STD
-#include <string>
-
-// LOVE
-#include <common/Data.h>
-#include <common/Object.h>
-#include <common/StringMap.h>
-#include <common/int.h>
-
-namespace love
-{
-namespace filesystem
-{
-	/**
-	* A File interface, providing generic means of reading from and
-	* writing to files.
-	**/
-	class File : public Object
-	{
-	public:
-
-		/**
-		* File open mode.
-		**/
-		enum Mode
-		{
-			CLOSED,
-			READ,
-			WRITE,
-			APPEND,
-			MODE_MAX_ENUM
-		};
-
-		/**
-		* Used to indicate ALL data in a file.
-		**/
-		static const int64 ALL = -1;
-
-		/**
-		* Destructor.
-		**/
-		virtual ~File();
-
-		/**
-		* Opens the file in a certain mode.
-		*
-		* @param mode READ, WRITE, APPEND.
-		* @return True if successful, false otherwise.
-		**/
-		virtual bool open(Mode mode) = 0;
-
-		/**
-		* Closes the file.
-		*
-		* @return True if successful, false otherwise.
-		**/
-		virtual bool close() = 0;
-
-		/**
-		* Gets the size of the file.
-		*
-		* @return The size of the file.
-		**/
-		virtual int64 getSize() = 0;
-
-		/**
-		* Reads data from the file and allocates a Data object.
-		*
-		* @param size The number of bytes to attempt reading, or -1 for EOF.
-		* @return A newly allocated Data object.
-		**/
-		virtual Data * read(int64 size = ALL) = 0;
-
-		/**
-		* Reads data into the destination buffer.
-		*
-		* @param dst The destination buffer.
-		* @param size The number of bytes to attempt reading.
-		* @return The number of bytes actually read.
-		**/
-		virtual int64 read(void * dst, int64 size) = 0;
-
-		/**
-		* Writes data into the File.
-		*
-		* @param data The source buffer.
-		* @param size The size of the buffer.
-		* @return True of success, false otherwise.
-		**/
-		virtual bool write(const void * data, int64 size) = 0;
-
-		/**
-		* Writes a Data object into the File.
-		*
-		* @param data The data object to write into the file.
-		* @param size The number of bytes to attempt writing, or -1 for everything.
-		* @return True of success, false otherwise.
-		**/
-		virtual bool write(const Data * data, int64 size = ALL) = 0;
-
-		/**
-		* Checks whether we are currently at end-of-file.
-		*
-		* @return True if EOF, false otherwise.
-		**/
-		virtual bool eof() = 0;
-
-		/**
-		* Gets the current position in the File.
-		*
-		* @return The current byte position in the File.
-		**/
-		virtual int64 tell() = 0;
-
-		/**
-		* Seeks to a certain position in the File.
-		*
-		* @param pos The byte position in the file.
-		* @return True on success, false otherwise.
-		**/
-		virtual bool seek(uint64 pos) = 0;
-
-		/**
-		* Gets the current mode of the File.
-		* @return The current mode of the File; CLOSED, READ, WRITE or APPEND.
-		**/
-		virtual Mode getMode() = 0;
-
-		/**
-		* Gets the filename for this File, or empty string if none.
-		* @return The filename for this File.
-		**/
-		virtual std::string getFilename() const = 0;
-
-		/**
-		* Gets the file extension for this File, or empty string if none.
-		* @return The file extension for this File (without the dot).
-		**/
-		virtual std::string getExtension() const = 0;
-
-		static bool getConstant(const char * in, Mode & out);
-		static bool getConstant(Mode in, const char *& out);
-
-	private:
-
-		static StringMap<Mode, MODE_MAX_ENUM>::Entry modeEntries[];
-		static StringMap<Mode, MODE_MAX_ENUM> modes;
-
-	}; // File
-
-} // filesystem
-} // love
-
-#endif // LOVE_FILESYSTEM_FILE_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_FILESYSTEM_FILE_H
+#define LOVE_FILESYSTEM_FILE_H
+
+// STD
+#include <string>
+
+// LOVE
+#include "common/Data.h"
+#include "common/Object.h"
+#include "common/StringMap.h"
+#include "common/int.h"
+
+namespace love
+{
+namespace filesystem
+{
+
+/**
+ * A File interface, providing generic means of reading from and
+ * writing to files.
+ **/
+class File : public Object
+{
+public:
+
+	/**
+	 * File open mode.
+	 **/
+	enum Mode
+	{
+		CLOSED,
+		READ,
+		WRITE,
+		APPEND,
+		MODE_MAX_ENUM
+	};
+
+	/**
+	 * Used to indicate ALL data in a file.
+	 **/
+	static const int64 ALL = -1;
+
+	/**
+	 * Destructor.
+	 **/
+	virtual ~File();
+
+	/**
+	 * Opens the file in a certain mode.
+	 *
+	 * @param mode READ, WRITE, APPEND.
+	 * @return True if successful, false otherwise.
+	 **/
+	virtual bool open(Mode mode) = 0;
+
+	/**
+	 * Closes the file.
+	 *
+	 * @return True if successful, false otherwise.
+	 **/
+	virtual bool close() = 0;
+
+	/**
+	 * Gets the size of the file.
+	 *
+	 * @return The size of the file.
+	 **/
+	virtual int64 getSize() = 0;
+
+	/**
+	 * Reads data from the file and allocates a Data object.
+	 *
+	 * @param size The number of bytes to attempt reading, or -1 for EOF.
+	 * @return A newly allocated Data object.
+	 **/
+	virtual Data *read(int64 size = ALL) = 0;
+
+	/**
+	 * Reads data into the destination buffer.
+	 *
+	 * @param dst The destination buffer.
+	 * @param size The number of bytes to attempt reading.
+	 * @return The number of bytes actually read.
+	 **/
+	virtual int64 read(void *dst, int64 size) = 0;
+
+	/**
+	 * Writes data into the File.
+	 *
+	 * @param data The source buffer.
+	 * @param size The size of the buffer.
+	 * @return True of success, false otherwise.
+	 **/
+	virtual bool write(const void *data, int64 size) = 0;
+
+	/**
+	 * Writes a Data object into the File.
+	 *
+	 * @param data The data object to write into the file.
+	 * @param size The number of bytes to attempt writing, or -1 for everything.
+	 * @return True of success, false otherwise.
+	 **/
+	virtual bool write(const Data *data, int64 size = ALL) = 0;
+
+	/**
+	 * Checks whether we are currently at end-of-file.
+	 *
+	 * @return True if EOF, false otherwise.
+	 **/
+	virtual bool eof() = 0;
+
+	/**
+	 * Gets the current position in the File.
+	 *
+	 * @return The current byte position in the File.
+	 **/
+	virtual int64 tell() = 0;
+
+	/**
+	 * Seeks to a certain position in the File.
+	 *
+	 * @param pos The byte position in the file.
+	 * @return True on success, false otherwise.
+	 **/
+	virtual bool seek(uint64 pos) = 0;
+
+	/**
+	 * Gets the current mode of the File.
+	 * @return The current mode of the File; CLOSED, READ, WRITE or APPEND.
+	 **/
+	virtual Mode getMode() = 0;
+
+	/**
+	 * Gets the filename for this File, or empty string if none.
+	 * @return The filename for this File.
+	 **/
+	virtual std::string getFilename() const = 0;
+
+	/**
+	 * Gets the file extension for this File, or empty string if none.
+	 * @return The file extension for this File (without the dot).
+	 **/
+	virtual std::string getExtension() const = 0;
+
+	static bool getConstant(const char *in, Mode &out);
+	static bool getConstant(Mode in, const char  *&out);
+
+private:
+
+	static StringMap<Mode, MODE_MAX_ENUM>::Entry modeEntries[];
+	static StringMap<Mode, MODE_MAX_ENUM> modes;
+
+}; // File
+
+} // filesystem
+} // love
+
+#endif // LOVE_FILESYSTEM_FILE_H

+ 91 - 88
src/modules/filesystem/FileData.cpp

@@ -1,88 +1,91 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "FileData.h"
-
-// STD
-#include <iostream>
-#include <climits>
-
-namespace love
-{
-namespace filesystem
-{
-	FileData::FileData(uint64 size, const std::string & filename)
-		: data(new char[(size_t) size]), size(size), filename(filename)
-	{
-		if (filename.rfind('.') != std::string::npos)
-			extension = filename.substr(filename.rfind('.')+1);
-	}
-
-	FileData::~FileData()
-	{
-		delete [] data;
-	}
-
-	void * FileData::getData() const
-	{
-		return (void*)data;
-	}
-
-	// TODO: Enable this
-	/*uint64 FileData::getSize() const
-	{
-		return size;
-	}*/
-
-	int FileData::getSize() const
-	{
-		return size > INT_MAX ? INT_MAX : (int) size;
-	}
-
-	const std::string & FileData::getFilename() const
-	{
-		return filename;
-	}
-
-	const std::string & FileData::getExtension() const
-	{
-		return extension;
-	}
-
-	bool FileData::getConstant(const char * in, Decoder & out)
-	{
-		return decoders.find(in, out);
-	}
-
-	bool FileData::getConstant(Decoder in, const char *& out)
-	{
-		return decoders.find(in, out);
-	}
-
-	StringMap<FileData::Decoder, FileData::DECODE_MAX_ENUM>::Entry FileData::decoderEntries[] =
-	{
-		{"file", FileData::FILE},
-		{"base64", FileData::BASE64},
-	};
-
-	StringMap<FileData::Decoder, FileData::DECODE_MAX_ENUM> FileData::decoders(FileData::decoderEntries, sizeof(FileData::decoderEntries));
-
-} // filesystem
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "FileData.h"
+
+// STD
+#include <iostream>
+#include <climits>
+
+namespace love
+{
+namespace filesystem
+{
+
+FileData::FileData(uint64 size, const std::string &filename)
+	: data(new char[(size_t) size])
+	, size(size)
+	, filename(filename)
+{
+	if (filename.rfind('.') != std::string::npos)
+		extension = filename.substr(filename.rfind('.')+1);
+}
+
+FileData::~FileData()
+{
+	delete [] data;
+}
+
+void *FileData::getData() const
+{
+	return (void *)data;
+}
+
+// TODO: Enable this
+/*uint64 FileData::getSize() const
+{
+	return size;
+}*/
+
+int FileData::getSize() const
+{
+	return size > INT_MAX ? INT_MAX : (int) size;
+}
+
+const std::string &FileData::getFilename() const
+{
+	return filename;
+}
+
+const std::string &FileData::getExtension() const
+{
+	return extension;
+}
+
+bool FileData::getConstant(const char *in, Decoder &out)
+{
+	return decoders.find(in, out);
+}
+
+bool FileData::getConstant(Decoder in, const char  *&out)
+{
+	return decoders.find(in, out);
+}
+
+StringMap<FileData::Decoder, FileData::DECODE_MAX_ENUM>::Entry FileData::decoderEntries[] =
+{
+	{"file", FileData::FILE},
+	{"base64", FileData::BASE64},
+};
+
+StringMap<FileData::Decoder, FileData::DECODE_MAX_ENUM> FileData::decoders(FileData::decoderEntries, sizeof(FileData::decoderEntries));
+
+} // filesystem
+} // love

+ 84 - 85
src/modules/filesystem/FileData.h

@@ -1,85 +1,84 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_FILESYSTEM_FILE_DATA_H
-#define LOVE_FILESYSTEM_FILE_DATA_H
-
-// LOVE
-#include <string>
-#include <common/Data.h>
-#include <common/StringMap.h>
-#include <common/int.h>
-
-namespace love
-{
-namespace filesystem
-{
-	class FileData : public Data
-	{
-	private:
-
-		// The actual data.
-		char * data;
-
-		// Size of the data.
-		uint64 size;
-
-		// The filename used for error purposes.
-		std::string filename;
-
-		// The extension (without dot). Used to identify file type.
-		std::string extension;
-
-	public:
-
-		enum Decoder
-		{
-			FILE,
-			BASE64,
-			DECODE_MAX_ENUM
-		}; // Decoder
-
-		FileData(uint64 size, const std::string & filename);
-
-		virtual ~FileData();
-
-		// Implements Data.
-		void * getData() const;
-		//TODO: Enable this
-		//uint64 getSize() const;
-		int getSize() const;
-
-		const std::string & getFilename() const;
-		const std::string & getExtension() const;
-
-		static bool getConstant(const char * in, Decoder & out);
-		static bool getConstant(Decoder in, const char *& out);
-
-	private:
-
-		static StringMap<Decoder, DECODE_MAX_ENUM>::Entry decoderEntries[];
-		static StringMap<Decoder, DECODE_MAX_ENUM> decoders;
-
-	}; // FileData
-
-} // filesystem
-} // love
-
-#endif // LOVE_FILESYSTEM_FILE_DATA_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_FILESYSTEM_FILE_DATA_H
+#define LOVE_FILESYSTEM_FILE_DATA_H
+
+// LOVE
+#include <string>
+#include "common/Data.h"
+#include "common/StringMap.h"
+#include "common/int.h"
+
+namespace love
+{
+namespace filesystem
+{
+
+class FileData : public Data
+{
+public:
+
+	enum Decoder
+	{
+		FILE,
+		BASE64,
+		DECODE_MAX_ENUM
+	}; // Decoder
+
+	FileData(uint64 size, const std::string &filename);
+
+	virtual ~FileData();
+
+	// Implements Data.
+	void *getData() const;
+	//TODO: Enable this
+	//uint64 getSize() const;
+	int getSize() const;
+
+	const std::string &getFilename() const;
+	const std::string &getExtension() const;
+
+	static bool getConstant(const char *in, Decoder &out);
+	static bool getConstant(Decoder in, const char  *&out);
+
+private:
+
+	// The actual data.
+	char *data;
+
+	// Size of the data.
+	uint64 size;
+
+	// The filename used for error purposes.
+	std::string filename;
+
+	// The extension (without dot). Used to identify file type.
+	std::string extension;
+
+	static StringMap<Decoder, DECODE_MAX_ENUM>::Entry decoderEntries[];
+	static StringMap<Decoder, DECODE_MAX_ENUM> decoders;
+
+}; // FileData
+
+} // filesystem
+} // love
+
+#endif // LOVE_FILESYSTEM_FILE_DATA_H

+ 243 - 240
src/modules/filesystem/physfs/File.cpp

@@ -1,240 +1,243 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "File.h"
-
-// STD
-#include <cstring>
-
-// LOVE
-#include "Filesystem.h"
-#include <filesystem/FileData.h>
-
-namespace love
-{
-namespace filesystem
-{
-namespace physfs
-{
-	extern bool hack_setupWriteDirectory();
-
-	File::File(std::string filename)
-		: filename(filename), file(0), mode(filesystem::File::CLOSED)
-	{
-	}
-
-	File::~File()
-	{
-		if (mode != CLOSED)
-			close();
-	}
-
-	bool File::open(Mode mode)
-	{
-		if (mode == CLOSED)
-			return true;
-
-		// File must exist if read mode.
-		if ((mode == READ) && !PHYSFS_exists(filename.c_str()))
-			throw love::Exception("Could not open file %s. Does not exist.", filename.c_str());
-
-		// Check whether the write directory is set.
-		if ((mode == APPEND || mode == WRITE) && (PHYSFS_getWriteDir() == 0) && !hack_setupWriteDirectory())
-			throw love::Exception("Could not set write directory.");
-
-		// File already open?
-		if (file != 0)
-			return false;
-
-		this->mode = mode;
-
-		switch(mode)
-		{
-		case READ:
-			file = PHYSFS_openRead(filename.c_str());
-			break;
-		case APPEND:
-			file = PHYSFS_openAppend(filename.c_str());
-			break;
-		case WRITE:
-			file = PHYSFS_openWrite(filename.c_str());
-			break;
-		default:
-			break;
-		}
-
-		return (file != 0);
-	}
-
-	bool File::close()
-	{
-		if (!PHYSFS_close(file))
-			return false;
-		mode = CLOSED;
-		file = 0;
-		return true;
-	}
-
-	int64 File::getSize()
-	{
-		// If the file is closed, open it to
-		// check the size.
-		if (file == 0)
-		{
-			open(READ);
-			int64 size = (int64)PHYSFS_fileLength(file);
-			close();
-			return size;
-		}
-
-		return (int64)PHYSFS_fileLength(file);
-	}
-
-
-	Data * File::read(int64 size)
-	{
-		bool isOpen = (file != 0);
-
-		if (!isOpen && !open(READ))
-			throw love::Exception("Could not read file %s.", filename.c_str());
-
-		int64 max = (int64)PHYSFS_fileLength(file);
-		size = (size == ALL) ? max : size;
-		size = (size > max) ? max : size;
-
-		FileData * fileData = new FileData(size, getFilename());
-
-		read(fileData->getData(), size);
-
-		if (!isOpen)
-			close();
-
-		return fileData;
-	}
-
-	int64 File::read(void * dst, int64 size)
-	{
-		bool isOpen = (file != 0);
-
-		if (!isOpen)
-			open(READ);
-
-		int64 max = (int64)PHYSFS_fileLength(file);
-		size = (size == ALL) ? max : size;
-		size = (size > max) ? max : size;
-		// Sadly, we'll have to clamp to 32 bits here
-		size = (size > LOVE_UINT32_MAX) ? LOVE_UINT32_MAX : size;
-
-		int64 read = (int64)PHYSFS_read(file, dst, 1, (int) size);
-
-		if (!isOpen)
-			close();
-
-		return read;
-	}
-
-	bool File::write(const void * data, int64 size)
-	{
-		if (file == 0)
-			throw love::Exception("Could not write to file. File not open.");
-
-		// Another clamp, for the time being.
-		size = (size > LOVE_UINT32_MAX) ? LOVE_UINT32_MAX : size;
-
-		// Try to write.
-		int64 written = static_cast<int64>(PHYSFS_write(file, data, 1, (int) size));
-
-		// Check that correct amount of data was written.
-		if (written != size)
-			return false;
-
-		return true;
-	}
-
-	bool File::write(const Data * data, int64 size)
-	{
-		return write(data->getData(), (size == ALL) ? data->getSize() : size);
-	}
-
-#ifdef LOVE_WINDOWS
-	// MSVC doesn't like the 'this' keyword
-	// well, we'll use 'that'.
-	// It zigs, we zag.
-	inline bool test_eof(File * that, PHYSFS_File *)
-	{
-		int64 pos = that->tell();
-		int64 size = that->getSize();
-		return pos == -1 || size == -1 || pos >= size;
-	}
-#else
-	inline bool test_eof(File *, PHYSFS_File * file)
-	{
-		return PHYSFS_eof(file);
-	}
-#endif
-
-	bool File::eof()
-	{
-		if (file == 0 || test_eof(this, file))
-			return true;
-		return false;
-	}
-
-	int64 File::tell()
-	{
-		if (file == 0)
-			return -1;
-
-		return (int64)PHYSFS_tell(file);
-	}
-
-	bool File::seek(uint64 pos)
-	{
-		if (file == 0)
-			return false;
-
-		if (!PHYSFS_seek(file, (PHYSFS_uint64)pos))
-			return false;
-		return true;
-	}
-
-	std::string File::getFilename() const
-	{
-		return filename;
-	}
-
-	std::string File::getExtension() const
-	{
-		std::string::size_type idx = filename.rfind('.');
-
-		if (idx != std::string::npos)
-			return filename.substr(idx+1);
-		else
-			return std::string();
-	}
-
-	filesystem::File::Mode File::getMode()
-	{
-		return mode;
-	}
-
-} // physfs
-} // filesystem
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "File.h"
+
+// STD
+#include <cstring>
+
+// LOVE
+#include "Filesystem.h"
+#include "filesystem/FileData.h"
+
+namespace love
+{
+namespace filesystem
+{
+namespace physfs
+{
+
+extern bool hack_setupWriteDirectory();
+
+File::File(std::string filename)
+	: filename(filename)
+	, file(0)
+	, mode(filesystem::File::CLOSED)
+{
+}
+
+File::~File()
+{
+	if (mode != CLOSED)
+		close();
+}
+
+bool File::open(Mode mode)
+{
+	if (mode == CLOSED)
+		return true;
+
+	// File must exist if read mode.
+	if ((mode == READ) && !PHYSFS_exists(filename.c_str()))
+		throw love::Exception("Could not open file %s. Does not exist.", filename.c_str());
+
+	// Check whether the write directory is set.
+	if ((mode == APPEND || mode == WRITE) && (PHYSFS_getWriteDir() == 0) && !hack_setupWriteDirectory())
+		throw love::Exception("Could not set write directory.");
+
+	// File already open?
+	if (file != 0)
+		return false;
+
+	this->mode = mode;
+
+	switch (mode)
+	{
+	case READ:
+		file = PHYSFS_openRead(filename.c_str());
+		break;
+	case APPEND:
+		file = PHYSFS_openAppend(filename.c_str());
+		break;
+	case WRITE:
+		file = PHYSFS_openWrite(filename.c_str());
+		break;
+	default:
+		break;
+	}
+
+	return (file != 0);
+}
+
+bool File::close()
+{
+	if (!PHYSFS_close(file))
+		return false;
+	mode = CLOSED;
+	file = 0;
+	return true;
+}
+
+int64 File::getSize()
+{
+	// If the file is closed, open it to
+	// check the size.
+	if (file == 0)
+	{
+		open(READ);
+		int64 size = (int64)PHYSFS_fileLength(file);
+		close();
+		return size;
+	}
+
+	return (int64)PHYSFS_fileLength(file);
+}
+
+
+Data *File::read(int64 size)
+{
+	bool isOpen = (file != 0);
+
+	if (!isOpen && !open(READ))
+		throw love::Exception("Could not read file %s.", filename.c_str());
+
+	int64 max = (int64)PHYSFS_fileLength(file);
+	size = (size == ALL) ? max : size;
+	size = (size > max) ? max : size;
+
+	FileData *fileData = new FileData(size, getFilename());
+
+	read(fileData->getData(), size);
+
+	if (!isOpen)
+		close();
+
+	return fileData;
+}
+
+int64 File::read(void *dst, int64 size)
+{
+	bool isOpen = (file != 0);
+
+	if (!isOpen)
+		open(READ);
+
+	int64 max = (int64)PHYSFS_fileLength(file);
+	size = (size == ALL) ? max : size;
+	size = (size > max) ? max : size;
+	// Sadly, we'll have to clamp to 32 bits here
+	size = (size > LOVE_UINT32_MAX) ? LOVE_UINT32_MAX : size;
+
+	int64 read = (int64)PHYSFS_read(file, dst, 1, (int) size);
+
+	if (!isOpen)
+		close();
+
+	return read;
+}
+
+bool File::write(const void *data, int64 size)
+{
+	if (file == 0)
+		throw love::Exception("Could not write to file. File not open.");
+
+	// Another clamp, for the time being.
+	size = (size > LOVE_UINT32_MAX) ? LOVE_UINT32_MAX : size;
+
+	// Try to write.
+	int64 written = static_cast<int64>(PHYSFS_write(file, data, 1, (int) size));
+
+	// Check that correct amount of data was written.
+	if (written != size)
+		return false;
+
+	return true;
+}
+
+bool File::write(const Data *data, int64 size)
+{
+	return write(data->getData(), (size == ALL) ? data->getSize() : size);
+}
+
+#ifdef LOVE_WINDOWS
+// MSVC doesn't like the 'this' keyword
+// well, we'll use 'that'.
+// It zigs, we zag.
+inline bool test_eof(File *that, PHYSFS_File *)
+{
+	int64 pos = that->tell();
+	int64 size = that->getSize();
+	return pos == -1 || size == -1 || pos >= size;
+}
+#else
+inline bool test_eof(File *, PHYSFS_File *file)
+{
+	return PHYSFS_eof(file);
+}
+#endif
+
+bool File::eof()
+{
+	if (file == 0 || test_eof(this, file))
+		return true;
+	return false;
+}
+
+int64 File::tell()
+{
+	if (file == 0)
+		return -1;
+
+	return (int64)PHYSFS_tell(file);
+}
+
+bool File::seek(uint64 pos)
+{
+	if (file == 0)
+		return false;
+
+	if (!PHYSFS_seek(file, (PHYSFS_uint64)pos))
+		return false;
+	return true;
+}
+
+std::string File::getFilename() const
+{
+	return filename;
+}
+
+std::string File::getExtension() const
+{
+	std::string::size_type idx = filename.rfind('.');
+
+	if (idx != std::string::npos)
+		return filename.substr(idx+1);
+	else
+		return std::string();
+}
+
+filesystem::File::Mode File::getMode()
+{
+	return mode;
+}
+
+} // physfs
+} // filesystem
+} // love

+ 89 - 88
src/modules/filesystem/physfs/File.h

@@ -1,88 +1,89 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_FILESYSTEM_PHYSFS_FILE_H
-#define LOVE_FILESYSTEM_PHYSFS_FILE_H
-
-// LOVE
-#include <filesystem/File.h>
-
-// PhysFS
-#ifdef LOVE_MACOSX // wacky Mac behavior means different #include syntax!
-#include <physfs/physfs.h>
-#else
-#include <physfs.h>
-#endif
-
-// STD
-#include <string>
-
-namespace love
-{
-namespace filesystem
-{
-namespace physfs
-{
-	class File : public love::filesystem::File
-	{
-	private:
-
-		// filename
-		std::string filename;
-
-		// PHYSFS File handle.
-		PHYSFS_file * file;
-
-		// The current mode of the file.
-		Mode mode;
-
-	public:
-
-		/**
-		* Constructs an File with the given source and filename.
-		* @param source The source from which to load the file. (Archive or directory)
-		* @param filename The relative filepath of the file to load from the source.
-		**/
-		File(std::string filename);
-
-		virtual ~File();
-
-		// Implements love::filesystem::File.
-		bool open(Mode mode);
-		bool close();
-		int64 getSize();
-		Data * read(int64 size = ALL);
-		int64 read(void * dst, int64 size);
-		bool write(const void * data, int64 size);
-		bool write(const Data * data, int64 size = ALL);
-		bool eof();
-		int64 tell();
-		bool seek(uint64 pos);
-		Mode getMode();
-		std::string getFilename() const;
-		std::string getExtension() const;
-
-	}; // File
-
-} // physfs
-} // filesystem
-} // love
-
-#endif // LOVE_FILESYSTEM_PHYSFS_FILE_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_FILESYSTEM_PHYSFS_FILE_H
+#define LOVE_FILESYSTEM_PHYSFS_FILE_H
+
+// LOVE
+#include "filesystem/File.h"
+
+// PhysFS
+#ifdef LOVE_MACOSX // wacky Mac behavior means different #include syntax!
+#include <physfs/physfs.h>
+#else
+#include <physfs.h>
+#endif
+
+// STD
+#include <string>
+
+namespace love
+{
+namespace filesystem
+{
+namespace physfs
+{
+
+class File : public love::filesystem::File
+{
+private:
+
+	// filename
+	std::string filename;
+
+	// PHYSFS File handle.
+	PHYSFS_file *file;
+
+	// The current mode of the file.
+	Mode mode;
+
+public:
+
+	/**
+	 * Constructs an File with the given source and filename.
+	 * @param source The source from which to load the file. (Archive or directory)
+	 * @param filename The relative filepath of the file to load from the source.
+	 **/
+	File(std::string filename);
+
+	virtual ~File();
+
+	// Implements love::filesystem::File.
+	bool open(Mode mode);
+	bool close();
+	int64 getSize();
+	Data *read(int64 size = ALL);
+	int64 read(void *dst, int64 size);
+	bool write(const void *data, int64 size);
+	bool write(const Data *data, int64 size = ALL);
+	bool eof();
+	int64 tell();
+	bool seek(uint64 pos);
+	Mode getMode();
+	std::string getFilename() const;
+	std::string getExtension() const;
+
+}; // File
+
+} // physfs
+} // filesystem
+} // love
+
+#endif // LOVE_FILESYSTEM_PHYSFS_FILE_H

+ 610 - 605
src/modules/filesystem/physfs/Filesystem.cpp

@@ -1,605 +1,610 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include <common/config.h>
-
-#include <iostream>
-
-#include <common/utf8.h>
-#include <common/b64.h>
-
-#include "Filesystem.h"
-
-namespace love
-{
-namespace filesystem
-{
-namespace physfs
-{
-	Filesystem::Filesystem()
-		: open_count(0), buffer(0), isInited(false), release(false), releaseSet(false)
-	{
-	}
-
-	Filesystem::~Filesystem()
-	{
-		if (isInited)
-		{
-			isInited = false;
-			PHYSFS_deinit();
-		}
-	}
-
-	const char * Filesystem::getName() const
-	{
-		return "love.filesystem.physfs";
-	}
-
-	void Filesystem::init(const char * arg0)
-	{
-		if (!PHYSFS_init(arg0))
-			throw Exception(PHYSFS_getLastError());
-		isInited = true;
-	}
-
-	void Filesystem::setRelease(bool release)
-	{
-		if (releaseSet)
-			return;
-		this->release = release;
-		releaseSet = true;
-	}
-
-	bool Filesystem::isRelease() const
-	{
-		if (!releaseSet)
-			return false;
-		return release;
-	}
-
-	bool Filesystem::setIdentity( const char * ident )
-	{
-		if (!isInited)
-			return false;
-
-		// Store the save directory.
-		save_identity = std::string(ident);
-
-		// Generate the relative path to the game save folder.
-		save_path_relative = std::string(LOVE_APPDATA_PREFIX LOVE_APPDATA_FOLDER LOVE_PATH_SEPARATOR) + save_identity;
-
-		// Generate the full path to the game save folder.
-		save_path_full = std::string(getAppdataDirectory()) + std::string(LOVE_PATH_SEPARATOR);
-		if (release)
-			save_path_full += std::string(LOVE_APPDATA_PREFIX) + save_identity;
-		else
-			save_path_full += save_path_relative;
-
-		// We now have something like:
-		// save_identity: game
-		// save_path_relative: ./LOVE/game
-		// save_path_full: C:\Documents and Settings\user\Application Data/LOVE/game
-
-		// Try to add the save directory to the search path.
-		// (No error on fail, it means that the path doesn't exist).
-		PHYSFS_addToSearchPath(save_path_full.c_str(), 0);
-
-		return true;
-	}
-
-	const char * Filesystem::getIdentity() const
-	{
-		return save_identity.c_str();
-	}
-
-	bool Filesystem::setSource(const char * source)
-	{
-		if (!isInited)
-			return false;
-
-		// Check whether directory is already set.
-		if (!game_source.empty())
-			return false;
-
-		// Add the directory.
-		if (!PHYSFS_addToSearchPath(source, 1))
-			return false;
-
-		// Save the game source.
-		game_source = std::string(source);
-
-		return true;
-	}
-
-	bool Filesystem::setupWriteDirectory()
-	{
-		if (!isInited)
-			return false;
-
-		// These must all be set.
-		if (save_identity.empty() || save_path_full.empty() || save_path_relative.empty())
-			return false;
-
-		// Set the appdata folder as writable directory.
-		// (We must create the save folder before mounting it).
-		if (!PHYSFS_setWriteDir(getAppdataDirectory()))
-			return false;
-
-		// Create the save folder. (We're now "at" %APPDATA%).
-		bool success = false;
-		if (release)
-			success = mkdir(save_identity.c_str());
-		else
-			success = mkdir(save_path_relative.c_str());
-
-		if (!success)
-		{
-			PHYSFS_setWriteDir(0); // Clear the write directory in case of error.
-			return false;
-		}
-
-		// Set the final write directory.
-		if (!PHYSFS_setWriteDir(save_path_full.c_str()))
-			return false;
-
-		// Add the directory. (Will not be readded if already present).
-		if (!PHYSFS_addToSearchPath(save_path_full.c_str(), 0))
-		{
-			PHYSFS_setWriteDir(0); // Clear the write directory in case of error.
-			return false;
-		}
-
-		return true;
-	}
-
-	File * Filesystem::newFile(const char *filename)
-	{
-		return new File(filename);
-	}
-
-	FileData * Filesystem::newFileData(void * data, unsigned int size, const char * filename)
-	{
-		FileData * fd = new FileData(size, std::string(filename));
-
-		// Copy the data into FileData.
-		memcpy(fd->getData(), data, size);
-
-		return fd;
-	}
-
-	FileData * Filesystem::newFileData(const char * b64, const char * filename)
-	{
-		int size = strlen(b64);
-		int outsize = 0;
-		char * dst = b64_decode(b64, size, outsize);
-		FileData * fd = new FileData(outsize, std::string(filename));
-
-		// Copy the data into FileData.
-		memcpy(fd->getData(), dst, outsize);
-		delete [] dst;
-
-		return fd;
-	}
-
-	const char * Filesystem::getWorkingDirectory()
-	{
-		if (cwd.empty())
-		{
-#ifdef LOVE_WINDOWS
-
-			WCHAR w_cwd[LOVE_MAX_PATH];
-			_wgetcwd(w_cwd, LOVE_MAX_PATH);
-			cwd = to_utf8(w_cwd);
-			replace_char(cwd, '\\', '/');
-#else
-			char * cwd_char = new char[LOVE_MAX_PATH];
-
-			if (getcwd(cwd_char, LOVE_MAX_PATH))
-				cwd = cwd_char; // if getcwd fails, cwd_char (and thus cwd) will still be empty
-
-			delete [] cwd_char;
-#endif
-		}
-
-		return cwd.c_str();
-	}
-
-	const char * Filesystem::getUserDirectory()
-	{
-		return PHYSFS_getUserDir();
-	}
-
-	const char * Filesystem::getAppdataDirectory()
-	{
-#ifdef LOVE_WINDOWS
-		if (appdata.empty())
-		{
-			wchar_t * w_appdata = _wgetenv(TEXT("APPDATA"));
-			appdata = to_utf8(w_appdata);
-			replace_char(appdata, '\\', '/');
-		}
-		return appdata.c_str();
-#elif defined(LOVE_MACOSX)
-		if (appdata.empty())
-		{
-			std::string udir = getUserDirectory();
-			udir.append("/Library/Application Support");
-			appdata = udir;
-		}
-		return appdata.c_str();
-#elif defined(LOVE_LINUX)
-		if (appdata.empty())
-		{
-			char * xdgdatahome = getenv("XDG_DATA_HOME");
-			if (!xdgdatahome)
-				appdata = std::string(getUserDirectory()) + "/.local/share/";
-			else
-				appdata = xdgdatahome;
-		}
-		return appdata.c_str();
-#else
-		return getUserDirectory();
-#endif
-	}
-
-
-	const char * Filesystem::getSaveDirectory()
-	{
-		return save_path_full.c_str();
-	}
-
-	bool Filesystem::exists(const char * file)
-	{
-		if (PHYSFS_exists(file))
-			return true;
-		return false;
-	}
-
-	bool Filesystem::isDirectory(const char * file)
-	{
-		if (PHYSFS_isDirectory(file))
-			return true;
-		return false;
-	}
-
-	bool Filesystem::isFile(const char * file)
-	{
-		return exists(file) && !isDirectory(file);
-	}
-
-	bool Filesystem::mkdir(const char * file)
-	{
-		if (PHYSFS_getWriteDir() == 0 && !setupWriteDirectory())
-			return false;
-
-		if (!PHYSFS_mkdir(file))
-			return false;
-		return true;
-	}
-
-	bool Filesystem::remove(const char * file)
-	{
-		if (PHYSFS_getWriteDir() == 0 && !setupWriteDirectory())
-			return false;
-
-		if (!PHYSFS_delete(file))
-			return false;
-		return true;
-	}
-
-	int Filesystem::read(lua_State * L)
-	{
-		// The file to read from. The file must either be created
-		// on-the-fly, or passed as a parameter.
-		File * file;
-
-        if (lua_isstring(L, 1))
-		{
-			// Create the file.
-			file = newFile(lua_tostring(L, 1));
-		}
-		else
-			return luaL_error(L, "Expected filename.");
-
-		// Optionally, the caller can specify whether to read
-		// the whole file, or just a part of it.
-		int count = luaL_optint(L, 2, (lua_Integer)file->getSize()); // FIXME
-
-		// Read the data.
-		Data * data = file->read(count);
-
-		// Error check.
-		if (data == 0)
-			return luaL_error(L, "File could not be read.");
-
-		// Close and delete the file, if we created it.
-		// (I.e. if the first parameter is a string).
-		if (lua_isstring(L, 1))
-			file->release();
-
-		// Push the string.
-		lua_pushlstring(L, (char*)data->getData(), data->getSize());
-
-		// Push the size.
-		lua_pushinteger(L, data->getSize());
-
-		// Lua has a copy now, so we can free it.
-		data->release();
-
-		return 2;
-	}
-
-	int Filesystem::write(lua_State * L)
-	{
-		// The file to write to. The file must either be created
-		// on-the-fly, or passed as a parameter.
-		File * file;
-
-		// We know for sure that we need a second parameter, so
-		// let's check that first.
-		if (lua_isnoneornil(L, 2))
-			return luaL_error(L, "Second argument needed.");
-
-		if (lua_isstring(L, 1))
-		{
-			// Create the file.
-			file = newFile(lua_tostring(L, 1));
-		}
-		else
-			return luaL_error(L, "Expected filename.");
-
-		// Get the current mode of the file.
-		File::Mode mode = file->getMode();
-
-		if (mode == File::CLOSED)
-		{
-			// It should be possible to use append mode, but
-			// normal File::Mode::Write is the default.
-			int mode = luaL_optint(L, 4, File::WRITE);
-
-			// Open the file.
-			if (!file->open((File::Mode)mode))
-				return luaL_error(L, "Could not open file.");
-		}
-
-		size_t length = 0;
-		const char * input;
-		if (lua_isstring(L, 2))
-		{
-			input = lua_tolstring(L, 2, &length);
-		}
-		else if (luax_istype(L, 2, DATA_T))
-		{
-			love::Data * data = luax_totype<love::Data>(L, 2, "Data", DATA_T);
-			length = data->getSize();
-			input = (char *)data->getData();
-		}
-		else
-		{
-			return luaL_error(L, "Expected string or data for argument #2.");
-		}
-
-		// Get how much we should write. Length of string default.
-		length = luaL_optint(L, 3, length);
-
-		// Write the data.
-		bool success = file->write(input, length);
-
-		// Close and delete the file, if we created
-		// it in this function.
-		if (lua_isstring(L, 1))
-		{
-			// Kill the file if "we" created it.
-			file->close();
-			file->release();
-		}
-
-		if (!success)
-			return luaL_error(L, "Data could not be written.");
-
-		lua_pushboolean(L, success);
-		return 1;
-	}
-
-	int Filesystem::enumerate(lua_State * L)
-	{
-		int n = lua_gettop(L);
-
-		if ( n != 1 )
-			return luaL_error(L, "Function requires a single parameter.");
-
-		int type = lua_type(L, 1);
-
-		if (type != LUA_TSTRING)
-			return luaL_error(L, "Function requires parameter of type string.");
-
-		const char * dir = lua_tostring(L, 1);
-		char **rc = PHYSFS_enumerateFiles(dir);
-		char **i;
-		int index = 1;
-
-		lua_newtable(L);
-
-		for (i = rc; *i != 0; i++)
-		{
-			lua_pushinteger(L, index);
-			lua_pushstring(L, *i);
-			lua_settable(L, -3);
-			index++;
-		}
-
-		PHYSFS_freeList(rc);
-
-		return 1;
-	}
-
-	int Filesystem::lines_i(lua_State * L)
-	{
-		const int bufsize = 1024;
-		char buf[bufsize];
-		int linesize = 0;
-		bool newline = false;
-
-		File * file = luax_checktype<File>(L, lua_upvalueindex(1), "File", FILESYSTEM_FILE_T);
-
-		// Only accept read mode at this point.
-		if (file->getMode() != File::READ)
-			return luaL_error(L, "File needs to stay in read mode.");
-
-		int64 pos = file->tell();
-		int64 userpos = -1;
-
-		if (lua_isnoneornil(L, lua_upvalueindex(2)) == 0)
-		{
-			// User may have changed the file position.
-			userpos = pos;
-			pos = (int64) lua_tonumber(L, lua_upvalueindex(2));
-			if (userpos != pos)
-				file->seek(pos);
-		}
-
-		while (!newline && !file->eof())
-		{
-			// This 64-bit to 32-bit integer cast should be safe as it never exceeds bufsize.
-			int read = (int) file->read(buf, bufsize);
-			if (read < 0)
-				return luaL_error(L, "Could not read from file.");
-
-			linesize += read;
-
-			for (int i = 0; i < read; i++)
-			{
-				if (buf[i] == '\n')
-				{
-					linesize -= read - i;
-					newline = true;
-					break;
-				}
-			}
-		}
-
-		if (newline || (file->eof() && linesize > 0))
-		{
-			if (linesize < bufsize)
-			{
-				// We have the line in the buffer on the stack. No 'new' and 'read' needed.
-				lua_pushlstring(L, buf, linesize > 0 && buf[linesize - 1] == '\r' ? linesize - 1 : linesize);
-				if (userpos < 0)
-					file->seek(pos + linesize + 1);
-			}
-			else
-			{
-				char * str;
-				try
-				{
-					str = new char[linesize + 1];
-				}
-				catch (std::bad_alloc &)
-				{
-					return luaL_error(L, "Out of memory");
-				}
-				file->seek(pos);
-
-				// Read the \n anyway and save us a call to seek.
-				if (file->read(str, linesize + 1) == -1)
-				{
-					delete [] str;
-					return luaL_error(L, "Could not read from file.");
-				}
-
-				lua_pushlstring(L, str, str[linesize - 1] == '\r' ? linesize - 1 : linesize);
-				delete [] str;
-			}
-
-			if (userpos >= 0)
-			{
-				// Save new position in upvalue.
-				lua_pushnumber(L, (lua_Number) (pos + linesize + 1));
-				lua_replace(L, lua_upvalueindex(2));
-				file->seek(userpos);
-			}
-
-			return 1;
-		}
-
-		// EOF reached.
-		if (userpos >= 0 && luax_toboolean(L, lua_upvalueindex(3)))
-			file->seek(userpos);
-		else
-			file->close();
-
-		return 0;
- 	}
-
-	int Filesystem::load(lua_State * L)
-	{
-		// Need only one arg.
-		luax_assert_argc(L, 1, 1);
-
-		// Must be string.
-		if (!lua_isstring(L, -1))
-			return luaL_error(L, "The argument must be a string.");
-
-		std::string filename = lua_tostring(L, -1);
-
-		// The file must exist.
-		if (!exists(filename.c_str()))
-			return luaL_error(L, "File %s does not exist.", filename.c_str());
-
-		// Create the file.
-		File * file = newFile(filename.c_str());
-
-		// Get the data from the file.
-		Data * data = file->read();
-
-		int status = luaL_loadbuffer(L, (const char *)data->getData(), data->getSize(), ("@" + filename).c_str());
-
-		data->release();
-		file->release();
-
-		// Load the chunk, but don't run it.
-		switch (status)
-		{
-		case LUA_ERRMEM:
-			return luaL_error(L, "Memory allocation error: %s\n", lua_tostring(L, -1));
-		case LUA_ERRSYNTAX:
-			return luaL_error(L, "Syntax error: %s\n", lua_tostring(L, -1));
-		default: // success
-			return 1;
-		}
-	}
-
-	int Filesystem::getLastModified(lua_State * L)
-	{
-		const char * filename = luaL_checkstring(L, 1);
-		PHYSFS_sint64 time = PHYSFS_getLastModTime(filename);
-		if (time == -1)
-		{
-			lua_pushnil(L);
-			lua_pushstring(L, "Could not determine file modification date.");
-			return 2;
-		}
-		lua_pushnumber(L, static_cast<lua_Number>(time));
-		return 1;
-	}
-
-} // physfs
-} // filesystem
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "common/config.h"
+
+#include <iostream>
+
+#include "common/utf8.h"
+#include "common/b64.h"
+
+#include "Filesystem.h"
+
+namespace love
+{
+namespace filesystem
+{
+namespace physfs
+{
+
+Filesystem::Filesystem()
+	: open_count(0)
+	, buffer(0)
+	, isInited(false)
+	, release(false)
+	, releaseSet(false)
+{
+}
+
+Filesystem::~Filesystem()
+{
+	if (isInited)
+	{
+		isInited = false;
+		PHYSFS_deinit();
+	}
+}
+
+const char *Filesystem::getName() const
+{
+	return "love.filesystem.physfs";
+}
+
+void Filesystem::init(const char *arg0)
+{
+	if (!PHYSFS_init(arg0))
+		throw Exception(PHYSFS_getLastError());
+	isInited = true;
+}
+
+void Filesystem::setRelease(bool release)
+{
+	if (releaseSet)
+		return;
+	this->release = release;
+	releaseSet = true;
+}
+
+bool Filesystem::isRelease() const
+{
+	if (!releaseSet)
+		return false;
+	return release;
+}
+
+bool Filesystem::setIdentity(const char *ident)
+{
+	if (!isInited)
+		return false;
+
+	// Store the save directory.
+	save_identity = std::string(ident);
+
+	// Generate the relative path to the game save folder.
+	save_path_relative = std::string(LOVE_APPDATA_PREFIX LOVE_APPDATA_FOLDER LOVE_PATH_SEPARATOR) + save_identity;
+
+	// Generate the full path to the game save folder.
+	save_path_full = std::string(getAppdataDirectory()) + std::string(LOVE_PATH_SEPARATOR);
+	if (release)
+		save_path_full += std::string(LOVE_APPDATA_PREFIX) + save_identity;
+	else
+		save_path_full += save_path_relative;
+
+	// We now have something like:
+	// save_identity: game
+	// save_path_relative: ./LOVE/game
+	// save_path_full: C:\Documents and Settings\user\Application Data/LOVE/game
+
+	// Try to add the save directory to the search path.
+	// (No error on fail, it means that the path doesn't exist).
+	PHYSFS_addToSearchPath(save_path_full.c_str(), 0);
+
+	return true;
+}
+
+const char *Filesystem::getIdentity() const
+{
+	return save_identity.c_str();
+}
+
+bool Filesystem::setSource(const char *source)
+{
+	if (!isInited)
+		return false;
+
+	// Check whether directory is already set.
+	if (!game_source.empty())
+		return false;
+
+	// Add the directory.
+	if (!PHYSFS_addToSearchPath(source, 1))
+		return false;
+
+	// Save the game source.
+	game_source = std::string(source);
+
+	return true;
+}
+
+bool Filesystem::setupWriteDirectory()
+{
+	if (!isInited)
+		return false;
+
+	// These must all be set.
+	if (save_identity.empty() || save_path_full.empty() || save_path_relative.empty())
+		return false;
+
+	// Set the appdata folder as writable directory.
+	// (We must create the save folder before mounting it).
+	if (!PHYSFS_setWriteDir(getAppdataDirectory()))
+		return false;
+
+	// Create the save folder. (We're now "at" %APPDATA%).
+	bool success = false;
+	if (release)
+		success = mkdir(save_identity.c_str());
+	else
+		success = mkdir(save_path_relative.c_str());
+
+	if (!success)
+	{
+		PHYSFS_setWriteDir(0); // Clear the write directory in case of error.
+		return false;
+	}
+
+	// Set the final write directory.
+	if (!PHYSFS_setWriteDir(save_path_full.c_str()))
+		return false;
+
+	// Add the directory. (Will not be readded if already present).
+	if (!PHYSFS_addToSearchPath(save_path_full.c_str(), 0))
+	{
+		PHYSFS_setWriteDir(0); // Clear the write directory in case of error.
+		return false;
+	}
+
+	return true;
+}
+
+File *Filesystem::newFile(const char *filename)
+{
+	return new File(filename);
+}
+
+FileData *Filesystem::newFileData(void *data, unsigned int size, const char *filename)
+{
+	FileData *fd = new FileData(size, std::string(filename));
+
+	// Copy the data into FileData.
+	memcpy(fd->getData(), data, size);
+
+	return fd;
+}
+
+FileData *Filesystem::newFileData(const char *b64, const char *filename)
+{
+	int size = strlen(b64);
+	int outsize = 0;
+	char *dst = b64_decode(b64, size, outsize);
+	FileData *fd = new FileData(outsize, std::string(filename));
+
+	// Copy the data into FileData.
+	memcpy(fd->getData(), dst, outsize);
+	delete [] dst;
+
+	return fd;
+}
+
+const char *Filesystem::getWorkingDirectory()
+{
+	if (cwd.empty())
+	{
+#ifdef LOVE_WINDOWS
+
+		WCHAR w_cwd[LOVE_MAX_PATH];
+		_wgetcwd(w_cwd, LOVE_MAX_PATH);
+		cwd = to_utf8(w_cwd);
+		replace_char(cwd, '\\', '/');
+#else
+		char *cwd_char = new char[LOVE_MAX_PATH];
+
+		if (getcwd(cwd_char, LOVE_MAX_PATH))
+			cwd = cwd_char; // if getcwd fails, cwd_char (and thus cwd) will still be empty
+
+		delete [] cwd_char;
+#endif
+	}
+
+	return cwd.c_str();
+}
+
+const char *Filesystem::getUserDirectory()
+{
+	return PHYSFS_getUserDir();
+}
+
+const char *Filesystem::getAppdataDirectory()
+{
+#ifdef LOVE_WINDOWS
+	if (appdata.empty())
+	{
+		wchar_t *w_appdata = _wgetenv(TEXT("APPDATA"));
+		appdata = to_utf8(w_appdata);
+		replace_char(appdata, '\\', '/');
+	}
+	return appdata.c_str();
+#elif defined(LOVE_MACOSX)
+	if (appdata.empty())
+	{
+		std::string udir = getUserDirectory();
+		udir.append("/Library/Application Support");
+		appdata = udir;
+	}
+	return appdata.c_str();
+#elif defined(LOVE_LINUX)
+	if (appdata.empty())
+	{
+		char *xdgdatahome = getenv("XDG_DATA_HOME");
+		if (!xdgdatahome)
+			appdata = std::string(getUserDirectory()) + "/.local/share/";
+		else
+			appdata = xdgdatahome;
+	}
+	return appdata.c_str();
+#else
+	return getUserDirectory();
+#endif
+}
+
+
+const char *Filesystem::getSaveDirectory()
+{
+	return save_path_full.c_str();
+}
+
+bool Filesystem::exists(const char *file)
+{
+	if (PHYSFS_exists(file))
+		return true;
+	return false;
+}
+
+bool Filesystem::isDirectory(const char *file)
+{
+	if (PHYSFS_isDirectory(file))
+		return true;
+	return false;
+}
+
+bool Filesystem::isFile(const char *file)
+{
+	return exists(file) && !isDirectory(file);
+}
+
+bool Filesystem::mkdir(const char *file)
+{
+	if (PHYSFS_getWriteDir() == 0 && !setupWriteDirectory())
+		return false;
+
+	if (!PHYSFS_mkdir(file))
+		return false;
+	return true;
+}
+
+bool Filesystem::remove(const char *file)
+{
+	if (PHYSFS_getWriteDir() == 0 && !setupWriteDirectory())
+		return false;
+
+	if (!PHYSFS_delete(file))
+		return false;
+	return true;
+}
+
+int Filesystem::read(lua_State *L)
+{
+	// The file to read from. The file must either be created
+	// on-the-fly, or passed as a parameter.
+	File *file;
+
+	if (lua_isstring(L, 1))
+	{
+		// Create the file.
+		file = newFile(lua_tostring(L, 1));
+	}
+	else
+		return luaL_error(L, "Expected filename.");
+
+	// Optionally, the caller can specify whether to read
+	// the whole file, or just a part of it.
+	int count = luaL_optint(L, 2, (lua_Integer)file->getSize()); // FIXME
+
+	// Read the data.
+	Data *data = file->read(count);
+
+	// Error check.
+	if (data == 0)
+		return luaL_error(L, "File could not be read.");
+
+	// Close and delete the file, if we created it.
+	// (I.e. if the first parameter is a string).
+	if (lua_isstring(L, 1))
+		file->release();
+
+	// Push the string.
+	lua_pushlstring(L, (char *)data->getData(), data->getSize());
+
+	// Push the size.
+	lua_pushinteger(L, data->getSize());
+
+	// Lua has a copy now, so we can free it.
+	data->release();
+
+	return 2;
+}
+
+int Filesystem::write(lua_State *L)
+{
+	// The file to write to. The file must either be created
+	// on-the-fly, or passed as a parameter.
+	File *file;
+
+	// We know for sure that we need a second parameter, so
+	// let's check that first.
+	if (lua_isnoneornil(L, 2))
+		return luaL_error(L, "Second argument needed.");
+
+	if (lua_isstring(L, 1))
+	{
+		// Create the file.
+		file = newFile(lua_tostring(L, 1));
+	}
+	else
+		return luaL_error(L, "Expected filename.");
+
+	// Get the current mode of the file.
+	File::Mode mode = file->getMode();
+
+	if (mode == File::CLOSED)
+	{
+		// It should be possible to use append mode, but
+		// normal File::Mode::Write is the default.
+		int mode = luaL_optint(L, 4, File::WRITE);
+
+		// Open the file.
+		if (!file->open((File::Mode)mode))
+			return luaL_error(L, "Could not open file.");
+	}
+
+	size_t length = 0;
+	const char *input;
+	if (lua_isstring(L, 2))
+	{
+		input = lua_tolstring(L, 2, &length);
+	}
+	else if (luax_istype(L, 2, DATA_T))
+	{
+		love::Data *data = luax_totype<love::Data>(L, 2, "Data", DATA_T);
+		length = data->getSize();
+		input = (char *)data->getData();
+	}
+	else
+	{
+		return luaL_error(L, "Expected string or data for argument #2.");
+	}
+
+	// Get how much we should write. Length of string default.
+	length = luaL_optint(L, 3, length);
+
+	// Write the data.
+	bool success = file->write(input, length);
+
+	// Close and delete the file, if we created
+	// it in this function.
+	if (lua_isstring(L, 1))
+	{
+		// Kill the file if "we" created it.
+		file->close();
+		file->release();
+	}
+
+	if (!success)
+		return luaL_error(L, "Data could not be written.");
+
+	lua_pushboolean(L, success);
+	return 1;
+}
+
+int Filesystem::enumerate(lua_State *L)
+{
+	int n = lua_gettop(L);
+
+	if (n != 1)
+		return luaL_error(L, "Function requires a single parameter.");
+
+	int type = lua_type(L, 1);
+
+	if (type != LUA_TSTRING)
+		return luaL_error(L, "Function requires parameter of type string.");
+
+	const char *dir = lua_tostring(L, 1);
+	char **rc = PHYSFS_enumerateFiles(dir);
+	char **i;
+	int index = 1;
+
+	lua_newtable(L);
+
+	for (i = rc; *i != 0; i++)
+	{
+		lua_pushinteger(L, index);
+		lua_pushstring(L, *i);
+		lua_settable(L, -3);
+		index++;
+	}
+
+	PHYSFS_freeList(rc);
+
+	return 1;
+}
+
+int Filesystem::lines_i(lua_State *L)
+{
+	const int bufsize = 1024;
+	char buf[bufsize];
+	int linesize = 0;
+	bool newline = false;
+
+	File *file = luax_checktype<File>(L, lua_upvalueindex(1), "File", FILESYSTEM_FILE_T);
+
+	// Only accept read mode at this point.
+	if (file->getMode() != File::READ)
+		return luaL_error(L, "File needs to stay in read mode.");
+
+	int64 pos = file->tell();
+	int64 userpos = -1;
+
+	if (lua_isnoneornil(L, lua_upvalueindex(2)) == 0)
+	{
+		// User may have changed the file position.
+		userpos = pos;
+		pos = (int64) lua_tonumber(L, lua_upvalueindex(2));
+		if (userpos != pos)
+			file->seek(pos);
+	}
+
+	while (!newline && !file->eof())
+	{
+		// This 64-bit to 32-bit integer cast should be safe as it never exceeds bufsize.
+		int read = (int) file->read(buf, bufsize);
+		if (read < 0)
+			return luaL_error(L, "Could not read from file.");
+
+		linesize += read;
+
+		for (int i = 0; i < read; i++)
+		{
+			if (buf[i] == '\n')
+			{
+				linesize -= read - i;
+				newline = true;
+				break;
+			}
+		}
+	}
+
+	if (newline || (file->eof() && linesize > 0))
+	{
+		if (linesize < bufsize)
+		{
+			// We have the line in the buffer on the stack. No 'new' and 'read' needed.
+			lua_pushlstring(L, buf, linesize > 0 && buf[linesize - 1] == '\r' ? linesize - 1 : linesize);
+			if (userpos < 0)
+				file->seek(pos + linesize + 1);
+		}
+		else
+		{
+			char *str;
+			try
+			{
+				str = new char[linesize + 1];
+			}
+			catch(std::bad_alloc &)
+			{
+				return luaL_error(L, "Out of memory");
+			}
+			file->seek(pos);
+
+			// Read the \n anyway and save us a call to seek.
+			if (file->read(str, linesize + 1) == -1)
+			{
+				delete [] str;
+				return luaL_error(L, "Could not read from file.");
+			}
+
+			lua_pushlstring(L, str, str[linesize - 1] == '\r' ? linesize - 1 : linesize);
+			delete [] str;
+		}
+
+		if (userpos >= 0)
+		{
+			// Save new position in upvalue.
+			lua_pushnumber(L, (lua_Number)(pos + linesize + 1));
+			lua_replace(L, lua_upvalueindex(2));
+			file->seek(userpos);
+		}
+
+		return 1;
+	}
+
+	// EOF reached.
+	if (userpos >= 0 && luax_toboolean(L, lua_upvalueindex(3)))
+		file->seek(userpos);
+	else
+		file->close();
+
+	return 0;
+}
+
+int Filesystem::load(lua_State *L)
+{
+	// Need only one arg.
+	luax_assert_argc(L, 1, 1);
+
+	// Must be string.
+	if (!lua_isstring(L, -1))
+		return luaL_error(L, "The argument must be a string.");
+
+	std::string filename = lua_tostring(L, -1);
+
+	// The file must exist.
+	if (!exists(filename.c_str()))
+		return luaL_error(L, "File %s does not exist.", filename.c_str());
+
+	// Create the file.
+	File *file = newFile(filename.c_str());
+
+	// Get the data from the file.
+	Data *data = file->read();
+
+	int status = luaL_loadbuffer(L, (const char *)data->getData(), data->getSize(), ("@" + filename).c_str());
+
+	data->release();
+	file->release();
+
+	// Load the chunk, but don't run it.
+	switch (status)
+	{
+	case LUA_ERRMEM:
+		return luaL_error(L, "Memory allocation error: %s\n", lua_tostring(L, -1));
+	case LUA_ERRSYNTAX:
+		return luaL_error(L, "Syntax error: %s\n", lua_tostring(L, -1));
+	default: // success
+		return 1;
+	}
+}
+
+int Filesystem::getLastModified(lua_State *L)
+{
+	const char *filename = luaL_checkstring(L, 1);
+	PHYSFS_sint64 time = PHYSFS_getLastModTime(filename);
+	if (time == -1)
+	{
+		lua_pushnil(L);
+		lua_pushstring(L, "Could not determine file modification date.");
+		return 2;
+	}
+	lua_pushnumber(L, static_cast<lua_Number>(time));
+	return 1;
+}
+
+} // physfs
+} // filesystem
+} // love

+ 297 - 297
src/modules/filesystem/physfs/Filesystem.h

@@ -1,297 +1,297 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_FILESYSTEM_PHYSFS_FILESYSTEM_H
-#define LOVE_FILESYSTEM_PHYSFS_FILESYSTEM_H
-
-// STD
-#include <cstdlib>
-#include <cstring>
-#include <iostream>
-#include <string>
-
-// LOVE
-#include <common/Module.h>
-#include <common/config.h>
-#include <common/int.h>
-#include <filesystem/FileData.h>
-#include "File.h"
-
-// For great CWD. (Current Working Directory)
-// Using this instead of boost::filesystem which totally
-// cramped our style.
-#ifdef LOVE_WINDOWS
-#	include <windows.h>
-#	include <direct.h>
-#else
-#	include <sys/param.h>
-#	include <unistd.h>
-#endif
-
-// In Windows, we would like to use "LOVE" as the
-// application folder, but in Linux, we like .love.
-#define LOVE_APPDATA_PREFIX ""
-#ifdef LOVE_WINDOWS
-#	define LOVE_APPDATA_FOLDER "LOVE"
-#	define LOVE_PATH_SEPARATOR "/"
-#	define LOVE_MAX_PATH _MAX_PATH
-#else
-#	ifdef LOVE_MACOSX
-#		define LOVE_APPDATA_FOLDER "LOVE"
-#	elif defined(LOVE_LINUX)
-#		define LOVE_APPDATA_FOLDER "love"
-#	else
-#		define LOVE_APPDATA_PREFIX "."
-#		define LOVE_APPDATA_FOLDER "love"
-#	endif
-#	define LOVE_PATH_SEPARATOR "/"
-#	define LOVE_MAX_PATH MAXPATHLEN
-#endif
-
-namespace love
-{
-namespace filesystem
-{
-namespace physfs
-{
-	class Filesystem : public Module
-	{
-	private:
-
-		// Counts open files.
-		int open_count;
-
-		// Pointer used for file reads.
-		char * buffer;
-
-		// Contains the current working directory (UTF8).
-		std::string cwd;
-
-		// %APPDATA% on Windows.
-		std::string appdata;
-
-		// This name will be used to create the folder
-		// in the appdata/userdata folder.
-		std::string save_identity;
-
-		// Full and relative paths of the game save folder.
-		// (Relative to the %APPDATA% folder, meaning that the
-		// relative string will look something like: ./LOVE/game)
-		std::string save_path_relative, save_path_full;
-
-		// The full path to the source of the game.
-		std::string game_source;
-
-		// Workaround for machines without PhysFS 2.0
-		bool isInited;
-
-		// Allow saving outside of the LOVE_APPDATA_FOLDER
-		// for release 'builds'
-		bool release;
-		bool releaseSet;
-
-	protected:
-
-	public:
-
-		Filesystem();
-
-		~Filesystem();
-
-		const char * getName() const;
-
-		void init(const char * arg0);
-
-		void setRelease(bool release);
-		bool isRelease() const;
-
-		/**
-		* This sets up the save directory. If the
-		* it is already set up, nothing happens.
-		* @return True on success, false otherwise.
-		**/
-		bool setupWriteDirectory();
-
-		/**
-		* Sets the name of the save folder.
-		* @param ident The name of the game. Will be used to
-		* to create the folder in the LOVE data folder.
-		**/
-		bool setIdentity(const char * ident);
-		const char * getIdentity() const;
-
-		/**
-		* Sets the path to the game source.
-		* This can only be set once.
-		* @param source Path to a directory or a .love-file.
-		**/
-		bool setSource(const char * source);
-
-		/**
-		* Creates a new file.
-		**/
-		File * newFile(const char* filename);
-
-		/**
-		* Creates a new FileData object. Data will be copied.
-		* @param data Pointer to the data.
-		* @param size The size of the data.
-		* @param filename The full filename used to file type identification.
-		**/
-		FileData * newFileData(void * data, unsigned int size, const char * filename);
-
-		/**
-		* Creates a new FileData object from base64 data.
-		* @param b64 The base64 data.
-		**/
-		FileData * newFileData(const char * b64, const char * filename);
-
-		/**
-		* Gets the current working directory.
-		**/
-		const char * getWorkingDirectory();
-
-		/**
-		* Gets the user home directory.
-		**/
-		const char * getUserDirectory();
-
-		/**
-		* Gets the APPDATA directory. On Windows, this is the folder
-		* in the %APPDATA% enviroment variable. On Linux, this is the
-		* user home folder.
-		**/
-		const char * getAppdataDirectory();
-
-		/**
-		* Gets the full path of the save folder.
-		**/
-		const char * getSaveDirectory();
-
-		/**
-		* Checks whether a file exists in the current search path
-		* or not.
-		* @param file The filename to check.
-		**/
-		bool exists(const char * file);
-
-		/**
-		* Checks if an existing file really is a directory.
-		* @param file The filename to check.
-		**/
-		bool isDirectory(const char * file);
-
-		/**
-		* Checks if an existing file really is a file,
-		* and not a directory.
-		* @param file The filename to check.
-		**/
-		bool isFile(const char * file);
-
-		/**
-		* Creates a directory. Write dir must be set.
-		* @param file The directory to create.
-		**/
-		bool mkdir(const char * file);
-
-		/**
-		* Removes a file (or directory).
-		* @param file The file or directory to remove.
-		**/
-		bool remove(const char * file);
-
-		/**
-		* Opens a file for reading or writing. (Depends
-		* on the mode chosen at the time of creation).
-		* @param file The file to open.
-		* @param mode The mode to open the file in.
-		**/
-		bool open(File * file, File::Mode mode);
-
-		/**
-		* Closes a file.
-		* @param file The file to close.
-		**/
-		bool close(File * file);
-
-		/**
-		* Reads count bytes from an open file.
-		* The first parameter is either a File or
-		* a string. An optional second parameter specified the
-		* max number of bytes to read.
-		**/
-		int read(lua_State * L);
-
-		/**
-		* Write the bytes in data to the file. File
-		* must be opened for write.
-		* The first parameter is either a File or
-		* a string.
-		**/
-		int write(lua_State * L);
-
-		/**
-		* Check if end-of-file is reached.
-		* @return True if EOF, false otherwise.
-		**/
-		bool eof(File * file);
-
-		/**
-		* Gets the current position in a file.
-		* @param file An open File.
-		**/
-		int tell(File * file);
-
-		/**
-		* Seek to a position within a file.
-		* @param pos The position to seek to.
-		**/
-		bool seek(File * file, uint64 pos);
-
-		/**
-		* This "native" method returns a table of all
-		* files in a given directory.
-		**/
-		int enumerate(lua_State * L);
-
-		/**
-		* Loads a file without running it. The loaded
-		* chunk is returned as a function.
-		* @param filename The filename of the file to load.
-		* @return A function.
-		**/
-		int load(lua_State * L);
-
-		int getLastModified(lua_State * L);
-
-		/**
-		* Text file line-reading iterator function used and
-		* pushed on the Lua stack by love.filesystem.lines
-		* and File:lines.
-		**/
-		static int lines_i(lua_State * L);
-
-	}; // Filesystem
-
-} // physfs
-} // filesystem
-} // love
-
-#endif // LOVE_FILESYSTEM_PHYSFS_FILESYSTEM_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_FILESYSTEM_PHYSFS_FILESYSTEM_H
+#define LOVE_FILESYSTEM_PHYSFS_FILESYSTEM_H
+
+// STD
+#include <cstdlib>
+#include <cstring>
+#include <iostream>
+#include <string>
+
+// LOVE
+#include "common/Module.h"
+#include "common/config.h"
+#include "common/int.h"
+#include "filesystem/FileData.h"
+#include "File.h"
+
+// For great CWD. (Current Working Directory)
+// Using this instead of boost::filesystem which totally
+// cramped our style.
+#ifdef LOVE_WINDOWS
+#	include <windows.h>
+#	include <direct.h>
+#else
+#	include <sys/param.h>
+#	include <unistd.h>
+#endif
+
+// In Windows, we would like to use "LOVE" as the
+// application folder, but in Linux, we like .love.
+#define LOVE_APPDATA_PREFIX ""
+#ifdef LOVE_WINDOWS
+#	define LOVE_APPDATA_FOLDER "LOVE"
+#	define LOVE_PATH_SEPARATOR "/"
+#	define LOVE_MAX_PATH _MAX_PATH
+#else
+#	ifdef LOVE_MACOSX
+#		define LOVE_APPDATA_FOLDER "LOVE"
+#	elif defined(LOVE_LINUX)
+#		define LOVE_APPDATA_FOLDER "love"
+#	else
+#		define LOVE_APPDATA_PREFIX "."
+#		define LOVE_APPDATA_FOLDER "love"
+#	endif
+#	define LOVE_PATH_SEPARATOR "/"
+#	define LOVE_MAX_PATH MAXPATHLEN
+#endif
+
+namespace love
+{
+namespace filesystem
+{
+namespace physfs
+{
+class Filesystem : public Module
+{
+private:
+
+	// Counts open files.
+	int open_count;
+
+	// Pointer used for file reads.
+	char *buffer;
+
+	// Contains the current working directory (UTF8).
+	std::string cwd;
+
+	// %APPDATA% on Windows.
+	std::string appdata;
+
+	// This name will be used to create the folder
+	// in the appdata/userdata folder.
+	std::string save_identity;
+
+	// Full and relative paths of the game save folder.
+	// (Relative to the %APPDATA% folder, meaning that the
+	// relative string will look something like: ./LOVE/game)
+	std::string save_path_relative, save_path_full;
+
+	// The full path to the source of the game.
+	std::string game_source;
+
+	// Workaround for machines without PhysFS 2.0
+	bool isInited;
+
+	// Allow saving outside of the LOVE_APPDATA_FOLDER
+	// for release 'builds'
+	bool release;
+	bool releaseSet;
+
+protected:
+
+public:
+
+	Filesystem();
+
+	~Filesystem();
+
+	const char *getName() const;
+
+	void init(const char *arg0);
+
+	void setRelease(bool release);
+	bool isRelease() const;
+
+	/**
+	 * This sets up the save directory. If the
+	 * it is already set up, nothing happens.
+	 * @return True on success, false otherwise.
+	 **/
+	bool setupWriteDirectory();
+
+	/**
+	 * Sets the name of the save folder.
+	 * @param ident The name of the game. Will be used to
+	 * to create the folder in the LOVE data folder.
+	 **/
+	bool setIdentity(const char *ident);
+	const char *getIdentity() const;
+
+	/**
+	 * Sets the path to the game source.
+	 * This can only be set once.
+	 * @param source Path to a directory or a .love-file.
+	 **/
+	bool setSource(const char *source);
+
+	/**
+	 * Creates a new file.
+	 **/
+	File *newFile(const char *filename);
+
+	/**
+	 * Creates a new FileData object. Data will be copied.
+	 * @param data Pointer to the data.
+	 * @param size The size of the data.
+	 * @param filename The full filename used to file type identification.
+	 **/
+	FileData *newFileData(void *data, unsigned int size, const char *filename);
+
+	/**
+	 * Creates a new FileData object from base64 data.
+	 * @param b64 The base64 data.
+	 **/
+	FileData *newFileData(const char *b64, const char *filename);
+
+	/**
+	 * Gets the current working directory.
+	 **/
+	const char *getWorkingDirectory();
+
+	/**
+	 * Gets the user home directory.
+	 **/
+	const char *getUserDirectory();
+
+	/**
+	 * Gets the APPDATA directory. On Windows, this is the folder
+	 * in the %APPDATA% enviroment variable. On Linux, this is the
+	 * user home folder.
+	 **/
+	const char *getAppdataDirectory();
+
+	/**
+	 * Gets the full path of the save folder.
+	 **/
+	const char *getSaveDirectory();
+
+	/**
+	 * Checks whether a file exists in the current search path
+	 * or not.
+	 * @param file The filename to check.
+	 **/
+	bool exists(const char *file);
+
+	/**
+	 * Checks if an existing file really is a directory.
+	 * @param file The filename to check.
+	 **/
+	bool isDirectory(const char *file);
+
+	/**
+	 * Checks if an existing file really is a file,
+	 * and not a directory.
+	 * @param file The filename to check.
+	 **/
+	bool isFile(const char *file);
+
+	/**
+	 * Creates a directory. Write dir must be set.
+	 * @param file The directory to create.
+	 **/
+	bool mkdir(const char *file);
+
+	/**
+	 * Removes a file (or directory).
+	 * @param file The file or directory to remove.
+	 **/
+	bool remove(const char *file);
+
+	/**
+	 * Opens a file for reading or writing. (Depends
+	 * on the mode chosen at the time of creation).
+	 * @param file The file to open.
+	 * @param mode The mode to open the file in.
+	 **/
+	bool open(File *file, File::Mode mode);
+
+	/**
+	 * Closes a file.
+	 * @param file The file to close.
+	 **/
+	bool close(File *file);
+
+	/**
+	 * Reads count bytes from an open file.
+	 * The first parameter is either a File or
+	 * a string. An optional second parameter specified the
+	 * max number of bytes to read.
+	 **/
+	int read(lua_State *L);
+
+	/**
+	 * Write the bytes in data to the file. File
+	 * must be opened for write.
+	 * The first parameter is either a File or
+	 * a string.
+	 **/
+	int write(lua_State *L);
+
+	/**
+	 * Check if end-of-file is reached.
+	 * @return True if EOF, false otherwise.
+	 **/
+	bool eof(File *file);
+
+	/**
+	 * Gets the current position in a file.
+	 * @param file An open File.
+	 **/
+	int tell(File *file);
+
+	/**
+	 * Seek to a position within a file.
+	 * @param pos The position to seek to.
+	 **/
+	bool seek(File *file, uint64 pos);
+
+	/**
+	 * This "native" method returns a table of all
+	 * files in a given directory.
+	 **/
+	int enumerate(lua_State *L);
+
+	/**
+	 * Loads a file without running it. The loaded
+	 * chunk is returned as a function.
+	 * @param filename The filename of the file to load.
+	 * @return A function.
+	 **/
+	int load(lua_State *L);
+
+	int getLastModified(lua_State *L);
+
+	/**
+	 * Text file line-reading iterator function used and
+	 * pushed on the Lua stack by love.filesystem.lines
+	 * and File:lines.
+	 **/
+	static int lines_i(lua_State *L);
+
+}; // Filesystem
+
+} // physfs
+} // filesystem
+} // love
+
+#endif // LOVE_FILESYSTEM_PHYSFS_FILESYSTEM_H

+ 227 - 225
src/modules/filesystem/physfs/wrap_File.cpp

@@ -1,225 +1,227 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "wrap_File.h"
-
-#include <common/Data.h>
-#include <common/Exception.h>
-#include <common/int.h>
-
-namespace love
-{
-namespace filesystem
-{
-namespace physfs
-{
-	File * luax_checkfile(lua_State * L, int idx)
-	{
-		return luax_checktype<File>(L, idx, "File", FILESYSTEM_FILE_T);
-	}
-
-	int w_File_getSize(lua_State * L)
-	{
-		File * t = luax_checkfile(L, 1);
-		int64 size = t->getSize();
-
-		// Push nil on failure or if size does not fit into a double precision floating-point number.
-		if (size == -1 || size >= 0x20000000000000LL)
-			lua_pushnil(L);
-		else
-			lua_pushnumber(L, (lua_Number)size);
-
-		return 1;
-	}
-
-	int w_File_open(lua_State * L)
-	{
-		File * file = luax_checkfile(L, 1);
-		File::Mode mode;
-
-		if (!File::getConstant(luaL_checkstring(L, 2), mode))
-			return luaL_error(L, "Incorrect file open mode: %s", luaL_checkstring(L, 2));
-
-		try
-		{
-			lua_pushboolean(L, file->open(mode) ? 1 : 0);
-		}
-		catch (Exception e)
-		{
-			return luaL_error(L, e.what());
-		}
-
-		return 1;
-	}
-
-	int w_File_close(lua_State * L)
-	{
-		File * file = luax_checkfile(L, 1);
-		lua_pushboolean(L, file->close() ? 1 : 0);
-		return 1;
-	}
-
-	int w_File_read(lua_State * L)
-	{
-		File * file = luax_checkfile(L, 1);
-		Data * d = 0;
-
-		int64 size = (int64)luaL_optnumber(L, 2, (lua_Number) file->getSize());
-
-		try
-		{
-			d = file->read(size);
-		}
-		catch (Exception e)
-		{
-			return luaL_error(L, e.what());
-		}
-
-		lua_pushlstring(L, (const char*) d->getData(), d->getSize());
-		lua_pushnumber(L, d->getSize());
-		d->release();
-		return 2;
-	}
-
-	int w_File_write(lua_State * L)
-	{
-		File * file = luax_checkfile(L, 1);
-		bool result;
-		if ( file->getMode() == File::CLOSED )
-			return luaL_error(L, "File is not open.");
-		if ( lua_isstring(L, 2) )
-		{
-			try
-			{
-				result = file->write(lua_tostring(L, 2), luaL_optint(L, 3, lua_objlen(L, 2)));
-			}
-			catch (Exception e)
-			{
-				return luaL_error(L, e.what());
-			}
-
-		}
-		else if ( luax_istype(L, 2, DATA_T))
-		{
-			try
-			{
-				love::Data * data = luax_totype<love::Data>(L, 2, "Data", DATA_T);
-				result = file->write(data, luaL_optint(L, 3, data->getSize()));
-			}
-			catch (Exception e)
-			{
-				return luaL_error(L, e.what());
-			}
-		}
-		else
-		{
-			return luaL_error(L, "String or data expected.");
-		}
-		lua_pushboolean(L, result);
-		return 1;
-	}
-
-	int w_File_eof(lua_State * L)
-	{
-		File * file = luax_checkfile(L, 1);
-		luax_pushboolean(L, file->eof());
-		return 1;
-	}
-
-	int w_File_tell(lua_State * L)
-	{
-		File * file = luax_checkfile(L, 1);
-		int64 pos = file->tell();
-		// Push nil on failure or if pos does not fit into a double precision floating-point number.
-		if (pos == -1 || pos >= 0x20000000000000LL)
-			lua_pushnil(L);
-		else
-			lua_pushnumber(L, (lua_Number)pos);
-		return 1;
-	}
-
-	int w_File_seek(lua_State * L)
-	{
-		File * file = luax_checkfile(L, 1);
-		lua_Number pos = luaL_checknumber(L, 2);
-
-		// Push false on negative and precision-problematic numbers.
-		// Better fail than seek to an unknown position.
-		if (pos < 0.0 || pos >= 9007199254740992.0)
-			luax_pushboolean(L, false);
-		else
-			luax_pushboolean(L, file->seek((uint64)pos));
-		return 1;
-	}
-
-	int w_File_lines(lua_State * L)
-	{
-		File * file;
-
-		if (luax_istype(L, 1, FILESYSTEM_FILE_T))
-		{
-			file = luax_checktype<File>(L, 1, "File", FILESYSTEM_FILE_T);
-			lua_pushnumber(L, 0); // File position.
-			luax_pushboolean(L, file->getMode() != File::CLOSED); // Save current file mode.
-		}
-		else
-			return luaL_error(L, "Expected File.");
-
-		if (file->getMode() != File::READ)
-		{
-			if (file->getMode() != File::CLOSED)
-				file->close();
-
-			try
-			{
-				if (!file->open(File::READ))
-					return luaL_error(L, "Could not open file.");
-			}
-			catch (love::Exception & e)
-			{
-				return luaL_error(L, "%s", e.what());
-			}
-		}
-
-		lua_pushcclosure(L, Filesystem::lines_i, 3);
-		return 1;
-	}
-
-	static const luaL_Reg functions[] = {
-		{ "getSize", w_File_getSize },
-		{ "open", w_File_open },
-		{ "close", w_File_close },
-		{ "read", w_File_read },
-		{ "write", w_File_write },
-		{ "eof", w_File_eof },
-		{ "tell", w_File_tell },
-		{ "seek", w_File_seek },
-		{ "lines", w_File_lines },
-		{ 0, 0 }
-	};
-
-	extern "C" int luaopen_file(lua_State * L)
-	{
-		return luax_register_type(L, "File", functions);
-	}
-
-} // physfs
-} // filesystem
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "wrap_File.h"
+
+#include "common/Data.h"
+#include "common/Exception.h"
+#include "common/int.h"
+
+namespace love
+{
+namespace filesystem
+{
+namespace physfs
+{
+
+File *luax_checkfile(lua_State *L, int idx)
+{
+	return luax_checktype<File>(L, idx, "File", FILESYSTEM_FILE_T);
+}
+
+int w_File_getSize(lua_State *L)
+{
+	File *t = luax_checkfile(L, 1);
+	int64 size = t->getSize();
+
+	// Push nil on failure or if size does not fit into a double precision floating-point number.
+	if (size == -1 || size >= 0x20000000000000LL)
+		lua_pushnil(L);
+	else
+		lua_pushnumber(L, (lua_Number)size);
+
+	return 1;
+}
+
+int w_File_open(lua_State *L)
+{
+	File *file = luax_checkfile(L, 1);
+	File::Mode mode;
+
+	if (!File::getConstant(luaL_checkstring(L, 2), mode))
+		return luaL_error(L, "Incorrect file open mode: %s", luaL_checkstring(L, 2));
+
+	try
+	{
+		lua_pushboolean(L, file->open(mode) ? 1 : 0);
+	}
+	catch(Exception e)
+	{
+		return luaL_error(L, e.what());
+	}
+
+	return 1;
+}
+
+int w_File_close(lua_State *L)
+{
+	File *file = luax_checkfile(L, 1);
+	lua_pushboolean(L, file->close() ? 1 : 0);
+	return 1;
+}
+
+int w_File_read(lua_State *L)
+{
+	File *file = luax_checkfile(L, 1);
+	Data *d = 0;
+
+	int64 size = (int64)luaL_optnumber(L, 2, (lua_Number) file->getSize());
+
+	try
+	{
+		d = file->read(size);
+	}
+	catch(Exception e)
+	{
+		return luaL_error(L, e.what());
+	}
+
+	lua_pushlstring(L, (const char *) d->getData(), d->getSize());
+	lua_pushnumber(L, d->getSize());
+	d->release();
+	return 2;
+}
+
+int w_File_write(lua_State *L)
+{
+	File *file = luax_checkfile(L, 1);
+	bool result;
+	if (file->getMode() == File::CLOSED)
+		return luaL_error(L, "File is not open.");
+	if (lua_isstring(L, 2))
+	{
+		try
+		{
+			result = file->write(lua_tostring(L, 2), luaL_optint(L, 3, lua_objlen(L, 2)));
+		}
+		catch(Exception e)
+		{
+			return luaL_error(L, e.what());
+		}
+
+	}
+	else if (luax_istype(L, 2, DATA_T))
+	{
+		try
+		{
+			love::Data *data = luax_totype<love::Data>(L, 2, "Data", DATA_T);
+			result = file->write(data, luaL_optint(L, 3, data->getSize()));
+		}
+		catch(Exception e)
+		{
+			return luaL_error(L, e.what());
+		}
+	}
+	else
+	{
+		return luaL_error(L, "String or data expected.");
+	}
+	lua_pushboolean(L, result);
+	return 1;
+}
+
+int w_File_eof(lua_State *L)
+{
+	File *file = luax_checkfile(L, 1);
+	luax_pushboolean(L, file->eof());
+	return 1;
+}
+
+int w_File_tell(lua_State *L)
+{
+	File *file = luax_checkfile(L, 1);
+	int64 pos = file->tell();
+	// Push nil on failure or if pos does not fit into a double precision floating-point number.
+	if (pos == -1 || pos >= 0x20000000000000LL)
+		lua_pushnil(L);
+	else
+		lua_pushnumber(L, (lua_Number)pos);
+	return 1;
+}
+
+int w_File_seek(lua_State *L)
+{
+	File *file = luax_checkfile(L, 1);
+	lua_Number pos = luaL_checknumber(L, 2);
+
+	// Push false on negative and precision-problematic numbers.
+	// Better fail than seek to an unknown position.
+	if (pos < 0.0 || pos >= 9007199254740992.0)
+		luax_pushboolean(L, false);
+	else
+		luax_pushboolean(L, file->seek((uint64)pos));
+	return 1;
+}
+
+int w_File_lines(lua_State *L)
+{
+	File *file;
+
+	if (luax_istype(L, 1, FILESYSTEM_FILE_T))
+	{
+		file = luax_checktype<File>(L, 1, "File", FILESYSTEM_FILE_T);
+		lua_pushnumber(L, 0); // File position.
+		luax_pushboolean(L, file->getMode() != File::CLOSED); // Save current file mode.
+	}
+	else
+		return luaL_error(L, "Expected File.");
+
+	if (file->getMode() != File::READ)
+	{
+		if (file->getMode() != File::CLOSED)
+			file->close();
+
+		try
+		{
+			if (!file->open(File::READ))
+				return luaL_error(L, "Could not open file.");
+		}
+		catch(love::Exception &e)
+		{
+			return luaL_error(L, "%s", e.what());
+		}
+	}
+
+	lua_pushcclosure(L, Filesystem::lines_i, 3);
+	return 1;
+}
+
+static const luaL_Reg functions[] =
+{
+	{ "getSize", w_File_getSize },
+	{ "open", w_File_open },
+	{ "close", w_File_close },
+	{ "read", w_File_read },
+	{ "write", w_File_write },
+	{ "eof", w_File_eof },
+	{ "tell", w_File_tell },
+	{ "seek", w_File_seek },
+	{ "lines", w_File_lines },
+	{ 0, 0 }
+};
+
+extern "C" int luaopen_file(lua_State *L)
+{
+	return luax_register_type(L, "File", functions);
+}
+
+} // physfs
+} // filesystem
+} // love

+ 52 - 50
src/modules/filesystem/physfs/wrap_File.h

@@ -1,50 +1,52 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_FILESYSTEM_PHYSFS_WRAP_FILE_H
-#define LOVE_FILESYSTEM_PHYSFS_WRAP_FILE_H
-
-// LOVE
-#include <common/runtime.h>
-#include "Filesystem.h"
-#include "File.h"
-
-namespace love
-{
-namespace filesystem
-{
-namespace physfs
-{
-	File * luax_checkfile(lua_State * L, int idx);
-	int w_File_getSize(lua_State * L);
-	int w_File_open(lua_State * L);
-	int w_File_close(lua_State * L);
-	int w_File_read(lua_State * L);
-	int w_File_write(lua_State * L);
-	int w_File_eof(lua_State * L);
-	int w_File_tell(lua_State * L);
-	int w_File_seek(lua_State * L);
-	int w_File_lines(lua_State * L);
-	extern "C" int luaopen_file(lua_State * L);
-} // physfs
-} // filesystem
-} // love
-
-#endif // LOVE_FILESYSTEM_PHYSFS_WRAP_FILE_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_FILESYSTEM_PHYSFS_WRAP_FILE_H
+#define LOVE_FILESYSTEM_PHYSFS_WRAP_FILE_H
+
+// LOVE
+#include "common/runtime.h"
+#include "Filesystem.h"
+#include "File.h"
+
+namespace love
+{
+namespace filesystem
+{
+namespace physfs
+{
+
+File *luax_checkfile(lua_State *L, int idx);
+int w_File_getSize(lua_State *L);
+int w_File_open(lua_State *L);
+int w_File_close(lua_State *L);
+int w_File_read(lua_State *L);
+int w_File_write(lua_State *L);
+int w_File_eof(lua_State *L);
+int w_File_tell(lua_State *L);
+int w_File_seek(lua_State *L);
+int w_File_lines(lua_State *L);
+extern "C" int luaopen_file(lua_State *L);
+
+} // physfs
+} // filesystem
+} // love
+
+#endif // LOVE_FILESYSTEM_PHYSFS_WRAP_FILE_H

+ 71 - 69
src/modules/filesystem/physfs/wrap_FileData.cpp

@@ -1,69 +1,71 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "wrap_FileData.h"
-
-#include <common/wrap_Data.h>
-
-namespace love
-{
-namespace filesystem
-{
-namespace physfs
-{
-	FileData * luax_checkfiledata(lua_State * L, int idx)
-	{
-		return luax_checktype<FileData>(L, idx, "FileData", FILESYSTEM_FILE_DATA_T);
-	}
-
-	int w_FileData_getFilename(lua_State * L)
-	{
-		FileData * t = luax_checkfiledata(L, 1);
-		lua_pushstring(L, t->getFilename().c_str());
-		return 1;
-	}
-
-	int w_FileData_getExtension(lua_State * L)
-	{
-		FileData * t = luax_checkfiledata(L, 1);
-		lua_pushstring(L, t->getExtension().c_str());
-		return 1;
-	}
-
-	static const luaL_Reg w_FileData_functions[] = {
-
-		// Data
-		{ "getPointer", w_Data_getPointer },
-		{ "getSize", w_Data_getSize },
-
-		{ "getFilename", w_FileData_getFilename },
-		{ "getExtension", w_FileData_getExtension },
-
-		{ 0, 0 }
-	};
-
-	extern "C" int luaopen_filedata(lua_State * L)
-	{
-		return luax_register_type(L, "FileData", w_FileData_functions);
-	}
-
-} // physfs
-} // filesystem
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "wrap_FileData.h"
+
+#include "common/wrap_Data.h"
+
+namespace love
+{
+namespace filesystem
+{
+namespace physfs
+{
+
+FileData *luax_checkfiledata(lua_State *L, int idx)
+{
+	return luax_checktype<FileData>(L, idx, "FileData", FILESYSTEM_FILE_DATA_T);
+}
+
+int w_FileData_getFilename(lua_State *L)
+{
+	FileData *t = luax_checkfiledata(L, 1);
+	lua_pushstring(L, t->getFilename().c_str());
+	return 1;
+}
+
+int w_FileData_getExtension(lua_State *L)
+{
+	FileData *t = luax_checkfiledata(L, 1);
+	lua_pushstring(L, t->getExtension().c_str());
+	return 1;
+}
+
+static const luaL_Reg w_FileData_functions[] =
+{
+
+	// Data
+	{ "getPointer", w_Data_getPointer },
+	{ "getSize", w_Data_getSize },
+
+	{ "getFilename", w_FileData_getFilename },
+	{ "getExtension", w_FileData_getExtension },
+
+	{ 0, 0 }
+};
+
+extern "C" int luaopen_filedata(lua_State *L)
+{
+	return luax_register_type(L, "FileData", w_FileData_functions);
+}
+
+} // physfs
+} // filesystem
+} // love

+ 45 - 43
src/modules/filesystem/physfs/wrap_FileData.h

@@ -1,43 +1,45 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_FILESYSTEM_PHYSFS_WRAP_FILE_DATA_H
-#define LOVE_FILESYSTEM_PHYSFS_WRAP_FILE_DATA_H
-
-// LOVE
-#include <common/runtime.h>
-
-#include <filesystem/FileData.h>
-
-namespace love
-{
-namespace filesystem
-{
-namespace physfs
-{
-	FileData * luax_checkfiledata(lua_State * L, int idx);
-	int w_FileData_getFilename(lua_State * L);
-	int w_FileData_getExtension(lua_State * L);
-	extern "C" int luaopen_filedata(lua_State * L);
-} // physfs
-} // filesystem
-} // love
-
-#endif // LOVE_FILESYSTEM_PHYSFS_WRAP_FILE_DATA_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_FILESYSTEM_PHYSFS_WRAP_FILE_DATA_H
+#define LOVE_FILESYSTEM_PHYSFS_WRAP_FILE_DATA_H
+
+// LOVE
+#include "common/runtime.h"
+
+#include "filesystem/FileData.h"
+
+namespace love
+{
+namespace filesystem
+{
+namespace physfs
+{
+
+FileData *luax_checkfiledata(lua_State *L, int idx);
+int w_FileData_getFilename(lua_State *L);
+int w_FileData_getExtension(lua_State *L);
+extern "C" int luaopen_filedata(lua_State *L);
+
+} // physfs
+} // filesystem
+} // love
+
+#endif // LOVE_FILESYSTEM_PHYSFS_WRAP_FILE_DATA_H

+ 443 - 440
src/modules/filesystem/physfs/wrap_Filesystem.cpp

@@ -1,440 +1,443 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-// LOVE
-#include "wrap_Filesystem.h"
-
-namespace love
-{
-namespace filesystem
-{
-namespace physfs
-{
-	static Filesystem * instance = 0;
-
-	bool hack_setupWriteDirectory()
-	{
-		if (instance != 0)
-			return instance->setupWriteDirectory();
-		return false;
-	}
-
-	int w_init(lua_State * L)
-	{
-		const char * arg0 = luaL_checkstring(L, 1);
-
-		try
-		{
-			instance->init(arg0);
-		}
-		catch (Exception & e)
-		{
-			return luaL_error(L, e.what());
-		}
-
-		return 0;
-	}
-
-	int w_setRelease(lua_State * L)
-	{
-		// no error checking needed, everything, even nothing
-		// can be converted to a boolean
-		instance->setRelease(luax_toboolean(L, 1));
-		return 0;
-	}
-
-	int w_setIdentity(lua_State * L)
-	{
-		const char * arg = luaL_checkstring(L, 1);
-
-		if (!instance->setIdentity(arg))
-			return luaL_error(L, "Could not set write directory.");
-
-		return 0;
-	}
-
-	int w_getIdentity(lua_State * L)
-	{
-		lua_pushstring(L, instance->getIdentity());
-		return 1;
-	}
-
-	int w_setSource(lua_State * L)
-	{
-		const char * arg = luaL_checkstring(L, 1);
-
-		if (!instance->setSource(arg))
-			return luaL_error(L, "Could not set source.");
-
-		return 0;
-	}
-
-	int w_newFile(lua_State * L)
-	{
-		const char * filename = luaL_checkstring(L, 1);
-		File * t;
-		try
-		{
-			t = instance->newFile(filename);
-		}
-		catch (Exception e)
-		{
-			return luaL_error(L, e.what());
-		}
-		luax_newtype(L, "File", FILESYSTEM_FILE_T, (void*)t);
-		return 1;
-	}
-
-	int w_newFileData(lua_State * L)
-	{
-		if (!lua_isstring(L, 1))
-			return luaL_error(L, "String expected.");
-		if (!lua_isstring(L, 2))
-			return luaL_error(L, "String expected.");
-
-		size_t length = 0;
-		const char * str = lua_tolstring(L, 1, &length);
-		const char * filename = lua_tostring(L, 2);
-		const char * decstr = lua_isstring(L, 3) ? lua_tostring(L, 3) : 0;
-
-		FileData::Decoder decoder = FileData::FILE;
-
-		if (decstr)
-			FileData::getConstant(decstr, decoder);
-
-		FileData * t = 0;
-
-		switch(decoder)
-		{
-		case FileData::FILE:
-			t = instance->newFileData((void*)str, (int)length, filename);
-			break;
-		case FileData::BASE64:
-			t = instance->newFileData(str, filename);
-			break;
-		default:
-			return luaL_error(L, "Unrecognized FileData decoder: %s", decstr);
-		}
-
-		luax_newtype(L, "FileData", FILESYSTEM_FILE_DATA_T, (void*)t);
-		return 1;
-	}
-
-	int w_getWorkingDirectory(lua_State * L)
-	{
-		lua_pushstring(L, instance->getWorkingDirectory());
-		return 1;
-	}
-
-	int w_getUserDirectory(lua_State * L)
-	{
-		lua_pushstring(L, instance->getUserDirectory());
-		return 1;
-	}
-
-	int w_getAppdataDirectory(lua_State * L)
-	{
-		lua_pushstring(L, instance->getAppdataDirectory());
-		return 1;
-	}
-
-	int w_getSaveDirectory(lua_State * L)
-	{
-		lua_pushstring(L, instance->getSaveDirectory());
-		return 1;
-	}
-
-	int w_exists(lua_State * L)
-	{
-		const char * arg = luaL_checkstring(L, 1);
-		lua_pushboolean(L, instance->exists(arg) ? 1 : 0);
-		return 1;
-	}
-
-	int w_isDirectory(lua_State * L)
-	{
-		const char * arg = luaL_checkstring(L, 1);
-		lua_pushboolean(L, instance->isDirectory(arg) ? 1 : 0);
-		return 1;
-	}
-
-	int w_isFile(lua_State * L)
-	{
-		const char * arg = luaL_checkstring(L, 1);
-		lua_pushboolean(L, instance->isFile(arg) ? 1 : 0);
-		return 1;
-	}
-
-	int w_mkdir(lua_State * L)
-	{
-		const char * arg = luaL_checkstring(L, 1);
-		lua_pushboolean(L, instance->mkdir(arg) ? 1 : 0);
-		return 1;
-	}
-
-	int w_remove(lua_State * L)
-	{
-		const char * arg = luaL_checkstring(L, 1);
-		lua_pushboolean(L, instance->remove(arg) ? 1 : 0);
-		return 1;
-	}
-
-	int w_read(lua_State * L)
-	{
-		try
-		{
-			return instance->read(L);
-		}
-		catch (Exception e)
-		{
-			return luaL_error(L, e.what());
-		}
-	}
-
-	int w_write(lua_State * L)
-	{
-		try
-		{
-			return instance->write(L);
-		}
-		catch (Exception e)
-		{
-			return luaL_error(L, e.what());
-		}
-	}
-
-	int w_enumerate(lua_State * L)
-	{
-		return instance->enumerate(L);
-	}
-
-	int w_lines(lua_State * L)
-	{
-		File * file;
-
-		if(lua_isstring(L, 1))
-		{
-			file = instance->newFile(lua_tostring(L, 1));
-			try
-			{
-				if (!file->open(File::READ))
-					return luaL_error(L, "Could not open file.");
-			}
-			catch (love::Exception & e)
-			{
-				return luaL_error(L, "%s", e.what());
-			}
-			luax_newtype(L, "File", FILESYSTEM_FILE_T, file);
-		}
-		else
-			return luaL_error(L, "Expected filename.");
-
-		lua_pushcclosure(L, Filesystem::lines_i, 1);
-		return 1;
-	}
-
-	int w_load(lua_State * L)
-	{
-		try
-		{
-			return instance->load(L);
-		}
-		catch (love::Exception & e)
-		{
-			return luaL_error(L, e.what());
-		}
-	}
-
-	int w_getLastModified(lua_State * L)
-	{
-		return instance->getLastModified(L);
-	}
-
-	int loader(lua_State * L)
-	{
-		const char * filename = lua_tostring(L, -1);
-
-		std::string tmp(filename);
-		tmp += ".lua";
-
-		int size = tmp.size();
-
-		for (int i=0;i<size-4;i++)
-		{
-			if (tmp[i] == '.')
-			{
-				tmp[i] = '/';
-			}
-		}
-
-		// Check whether file exists.
-		if (instance->exists(tmp.c_str()))
-		{
-			lua_pop(L, 1);
-			lua_pushstring(L, tmp.c_str());
-			// Ok, load it.
-			return instance->load(L);
-		}
-
-		tmp = filename;
-		size = tmp.size();
-		for (int i=0;i<size;i++)
-		{
-			if (tmp[i] == '.')
-			{
-				tmp[i] = '/';
-			}
-		}
-
-		if (instance->isDirectory(tmp.c_str()))
-		{
-			tmp += "/init.lua";
-			if (instance->exists(tmp.c_str()))
-			{
-				lua_pop(L, 1);
-				lua_pushstring(L, tmp.c_str());
-				// Ok, load it.
-				return instance->load(L);
-			}
-		}
-
-		lua_pushfstring(L, "\n\tno file \"%s\" in LOVE game directories.\n", (tmp + ".lua").c_str());
-		return 1;
-	}
-
-	inline const char * library_extension()
-	{
-#ifdef LOVE_WINDOWS
-		return ".dll";
-#else
-		return ".so";
-#endif
-	}
-
-	int extloader(lua_State * L)
-	{
-		const char * filename = lua_tostring(L, -1);
-		std::string tokenized_name(filename);
-		std::string tokenized_function(filename);
-
-		for (unsigned int i = 0; i < tokenized_name.size(); i++)
-		{
-			if (tokenized_name[i] == '.')
-			{
-				tokenized_name[i] = '/';
-				tokenized_function[i] = '_';
-			}
-		}
-
-		tokenized_name += library_extension();
-
-		void * handle = SDL_LoadObject((std::string(instance->getAppdataDirectory()) + LOVE_PATH_SEPARATOR LOVE_APPDATA_FOLDER LOVE_PATH_SEPARATOR + tokenized_name).c_str());
-		if (!handle && instance->isRelease())
-			handle = SDL_LoadObject((std::string(instance->getSaveDirectory()) + LOVE_PATH_SEPARATOR + tokenized_name).c_str());
-
-		if (!handle)
-		{
-			lua_pushfstring(L, "\n\tno extension \"%s\" in LOVE paths.\n", filename);
-			return 1;
-		}
-
-		void * func = SDL_LoadFunction(handle, ("loveopen_" + tokenized_function).c_str());
-		if (!func)
-			func = SDL_LoadFunction(handle, ("luaopen_" + tokenized_function).c_str());
-
-		if (!func)
-		{
-			SDL_UnloadObject(handle);
-			lua_pushfstring(L, "\n\textension \"%s\" is incompatible.\n", filename);
-			return 1;
-		}
-
-		lua_pushcfunction(L, (lua_CFunction) func);
-		return 1;
-	}
-
-	// List of functions to wrap.
-	static const luaL_Reg functions[] = {
-		{ "init",  w_init },
-		{ "setRelease", w_setRelease },
-		{ "setIdentity",  w_setIdentity },
-		{ "getIdentity", w_getIdentity },
-		{ "setSource",  w_setSource },
-		{ "newFile",  w_newFile },
-		{ "getWorkingDirectory",  w_getWorkingDirectory },
-		{ "getUserDirectory",  w_getUserDirectory },
-		{ "getAppdataDirectory",  w_getAppdataDirectory },
-		{ "getSaveDirectory",  w_getSaveDirectory },
-		{ "exists",  w_exists },
-		{ "isDirectory",  w_isDirectory },
-		{ "isFile",  w_isFile },
-		{ "mkdir",  w_mkdir },
-		{ "remove",  w_remove },
-		{ "read",  w_read },
-		{ "write",  w_write },
-		{ "enumerate",  w_enumerate },
-		{ "lines",  w_lines },
-		{ "load",  w_load },
-		{ "getLastModified", w_getLastModified },
-		{ "newFileData", w_newFileData },
-		{ 0, 0 }
-	};
-
-	static const lua_CFunction types[] = {
-		luaopen_file,
-		luaopen_filedata,
-		0
-	};
-
-	extern "C" int luaopen_love_filesystem(lua_State * L)
-	{
-		if (instance == 0)
-		{
-			try
-			{
-				instance = new Filesystem();
-				love::luax_register_searcher(L, loader, 1);
-				love::luax_register_searcher(L, extloader, 2);
-			}
-			catch (Exception & e)
-			{
-				return luaL_error(L, e.what());
-			}
-		}
-		else
-		{
-			instance->retain();
-			love::luax_register_searcher(L, loader, 1);
-			love::luax_register_searcher(L, extloader, 2);
-		}
-
-		WrappedModule w;
-		w.module = instance;
-		w.name = "filesystem";
-		w.flags = MODULE_FILESYSTEM_T;
-		w.functions = functions;
-		w.types = types;
-
-		return luax_register_module(L, w);
-	}
-
-} // physfs
-} // filesystem
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+// LOVE
+#include "wrap_Filesystem.h"
+
+namespace love
+{
+namespace filesystem
+{
+namespace physfs
+{
+
+static Filesystem *instance = 0;
+
+bool hack_setupWriteDirectory()
+{
+	if (instance != 0)
+		return instance->setupWriteDirectory();
+	return false;
+}
+
+int w_init(lua_State *L)
+{
+	const char *arg0 = luaL_checkstring(L, 1);
+
+	try
+	{
+		instance->init(arg0);
+	}
+	catch(Exception &e)
+	{
+		return luaL_error(L, e.what());
+	}
+
+	return 0;
+}
+
+int w_setRelease(lua_State *L)
+{
+	// no error checking needed, everything, even nothing
+	// can be converted to a boolean
+	instance->setRelease(luax_toboolean(L, 1));
+	return 0;
+}
+
+int w_setIdentity(lua_State *L)
+{
+	const char *arg = luaL_checkstring(L, 1);
+
+	if (!instance->setIdentity(arg))
+		return luaL_error(L, "Could not set write directory.");
+
+	return 0;
+}
+
+int w_getIdentity(lua_State *L)
+{
+	lua_pushstring(L, instance->getIdentity());
+	return 1;
+}
+
+int w_setSource(lua_State *L)
+{
+	const char *arg = luaL_checkstring(L, 1);
+
+	if (!instance->setSource(arg))
+		return luaL_error(L, "Could not set source.");
+
+	return 0;
+}
+
+int w_newFile(lua_State *L)
+{
+	const char *filename = luaL_checkstring(L, 1);
+	File *t;
+	try
+	{
+		t = instance->newFile(filename);
+	}
+	catch(Exception e)
+	{
+		return luaL_error(L, e.what());
+	}
+	luax_newtype(L, "File", FILESYSTEM_FILE_T, (void *)t);
+	return 1;
+}
+
+int w_newFileData(lua_State *L)
+{
+	if (!lua_isstring(L, 1))
+		return luaL_error(L, "String expected.");
+	if (!lua_isstring(L, 2))
+		return luaL_error(L, "String expected.");
+
+	size_t length = 0;
+	const char *str = lua_tolstring(L, 1, &length);
+	const char *filename = lua_tostring(L, 2);
+	const char *decstr = lua_isstring(L, 3) ? lua_tostring(L, 3) : 0;
+
+	FileData::Decoder decoder = FileData::FILE;
+
+	if (decstr)
+		FileData::getConstant(decstr, decoder);
+
+	FileData *t = 0;
+
+	switch (decoder)
+	{
+	case FileData::FILE:
+		t = instance->newFileData((void *)str, (int)length, filename);
+		break;
+	case FileData::BASE64:
+		t = instance->newFileData(str, filename);
+		break;
+	default:
+		return luaL_error(L, "Unrecognized FileData decoder: %s", decstr);
+	}
+
+	luax_newtype(L, "FileData", FILESYSTEM_FILE_DATA_T, (void *)t);
+	return 1;
+}
+
+int w_getWorkingDirectory(lua_State *L)
+{
+	lua_pushstring(L, instance->getWorkingDirectory());
+	return 1;
+}
+
+int w_getUserDirectory(lua_State *L)
+{
+	lua_pushstring(L, instance->getUserDirectory());
+	return 1;
+}
+
+int w_getAppdataDirectory(lua_State *L)
+{
+	lua_pushstring(L, instance->getAppdataDirectory());
+	return 1;
+}
+
+int w_getSaveDirectory(lua_State *L)
+{
+	lua_pushstring(L, instance->getSaveDirectory());
+	return 1;
+}
+
+int w_exists(lua_State *L)
+{
+	const char *arg = luaL_checkstring(L, 1);
+	lua_pushboolean(L, instance->exists(arg) ? 1 : 0);
+	return 1;
+}
+
+int w_isDirectory(lua_State *L)
+{
+	const char *arg = luaL_checkstring(L, 1);
+	lua_pushboolean(L, instance->isDirectory(arg) ? 1 : 0);
+	return 1;
+}
+
+int w_isFile(lua_State *L)
+{
+	const char *arg = luaL_checkstring(L, 1);
+	lua_pushboolean(L, instance->isFile(arg) ? 1 : 0);
+	return 1;
+}
+
+int w_mkdir(lua_State *L)
+{
+	const char *arg = luaL_checkstring(L, 1);
+	lua_pushboolean(L, instance->mkdir(arg) ? 1 : 0);
+	return 1;
+}
+
+int w_remove(lua_State *L)
+{
+	const char *arg = luaL_checkstring(L, 1);
+	lua_pushboolean(L, instance->remove(arg) ? 1 : 0);
+	return 1;
+}
+
+int w_read(lua_State *L)
+{
+	try
+	{
+		return instance->read(L);
+	}
+	catch(Exception e)
+	{
+		return luaL_error(L, e.what());
+	}
+}
+
+int w_write(lua_State *L)
+{
+	try
+	{
+		return instance->write(L);
+	}
+	catch(Exception e)
+	{
+		return luaL_error(L, e.what());
+	}
+}
+
+int w_enumerate(lua_State *L)
+{
+	return instance->enumerate(L);
+}
+
+int w_lines(lua_State *L)
+{
+	File *file;
+
+	if (lua_isstring(L, 1))
+	{
+		file = instance->newFile(lua_tostring(L, 1));
+		try
+		{
+			if (!file->open(File::READ))
+				return luaL_error(L, "Could not open file.");
+		}
+		catch(love::Exception &e)
+		{
+			return luaL_error(L, "%s", e.what());
+		}
+		luax_newtype(L, "File", FILESYSTEM_FILE_T, file);
+	}
+	else
+		return luaL_error(L, "Expected filename.");
+
+	lua_pushcclosure(L, Filesystem::lines_i, 1);
+	return 1;
+}
+
+int w_load(lua_State *L)
+{
+	try
+	{
+		return instance->load(L);
+	}
+	catch(love::Exception &e)
+	{
+		return luaL_error(L, e.what());
+	}
+}
+
+int w_getLastModified(lua_State *L)
+{
+	return instance->getLastModified(L);
+}
+
+int loader(lua_State *L)
+{
+	const char *filename = lua_tostring(L, -1);
+
+	std::string tmp(filename);
+	tmp += ".lua";
+
+	int size = tmp.size();
+
+	for (int i=0; i<size-4; i++)
+	{
+		if (tmp[i] == '.')
+		{
+			tmp[i] = '/';
+		}
+	}
+
+	// Check whether file exists.
+	if (instance->exists(tmp.c_str()))
+	{
+		lua_pop(L, 1);
+		lua_pushstring(L, tmp.c_str());
+		// Ok, load it.
+		return instance->load(L);
+	}
+
+	tmp = filename;
+	size = tmp.size();
+	for (int i=0; i<size; i++)
+	{
+		if (tmp[i] == '.')
+		{
+			tmp[i] = '/';
+		}
+	}
+
+	if (instance->isDirectory(tmp.c_str()))
+	{
+		tmp += "/init.lua";
+		if (instance->exists(tmp.c_str()))
+		{
+			lua_pop(L, 1);
+			lua_pushstring(L, tmp.c_str());
+			// Ok, load it.
+			return instance->load(L);
+		}
+	}
+
+	lua_pushfstring(L, "\n\tno file \"%s\" in LOVE game directories.\n", (tmp + ".lua").c_str());
+	return 1;
+}
+
+inline const char *library_extension()
+{
+#ifdef LOVE_WINDOWS
+	return ".dll";
+#else
+	return ".so";
+#endif
+}
+
+int extloader(lua_State *L)
+{
+	const char *filename = lua_tostring(L, -1);
+	std::string tokenized_name(filename);
+	std::string tokenized_function(filename);
+
+	for (unsigned int i = 0; i < tokenized_name.size(); i++)
+	{
+		if (tokenized_name[i] == '.')
+		{
+			tokenized_name[i] = '/';
+			tokenized_function[i] = '_';
+		}
+	}
+
+	tokenized_name += library_extension();
+
+	void *handle = SDL_LoadObject((std::string(instance->getAppdataDirectory()) + LOVE_PATH_SEPARATOR LOVE_APPDATA_FOLDER LOVE_PATH_SEPARATOR + tokenized_name).c_str());
+	if (!handle && instance->isRelease())
+		handle = SDL_LoadObject((std::string(instance->getSaveDirectory()) + LOVE_PATH_SEPARATOR + tokenized_name).c_str());
+
+	if (!handle)
+	{
+		lua_pushfstring(L, "\n\tno extension \"%s\" in LOVE paths.\n", filename);
+		return 1;
+	}
+
+	void *func = SDL_LoadFunction(handle, ("loveopen_" + tokenized_function).c_str());
+	if (!func)
+		func = SDL_LoadFunction(handle, ("luaopen_" + tokenized_function).c_str());
+
+	if (!func)
+	{
+		SDL_UnloadObject(handle);
+		lua_pushfstring(L, "\n\textension \"%s\" is incompatible.\n", filename);
+		return 1;
+	}
+
+	lua_pushcfunction(L, (lua_CFunction) func);
+	return 1;
+}
+
+// List of functions to wrap.
+static const luaL_Reg functions[] =
+{
+	{ "init",  w_init },
+	{ "setRelease", w_setRelease },
+	{ "setIdentity",  w_setIdentity },
+	{ "getIdentity", w_getIdentity },
+	{ "setSource",  w_setSource },
+	{ "newFile",  w_newFile },
+	{ "getWorkingDirectory",  w_getWorkingDirectory },
+	{ "getUserDirectory",  w_getUserDirectory },
+	{ "getAppdataDirectory",  w_getAppdataDirectory },
+	{ "getSaveDirectory",  w_getSaveDirectory },
+	{ "exists",  w_exists },
+	{ "isDirectory",  w_isDirectory },
+	{ "isFile",  w_isFile },
+	{ "mkdir",  w_mkdir },
+	{ "remove",  w_remove },
+	{ "read",  w_read },
+	{ "write",  w_write },
+	{ "enumerate",  w_enumerate },
+	{ "lines",  w_lines },
+	{ "load",  w_load },
+	{ "getLastModified", w_getLastModified },
+	{ "newFileData", w_newFileData },
+	{ 0, 0 }
+};
+
+static const lua_CFunction types[] =
+{
+	luaopen_file,
+	luaopen_filedata,
+	0
+};
+
+extern "C" int luaopen_love_filesystem(lua_State *L)
+{
+	if (instance == 0)
+	{
+		try
+		{
+			instance = new Filesystem();
+			love::luax_register_searcher(L, loader, 1);
+			love::luax_register_searcher(L, extloader, 2);
+		}
+		catch(Exception &e)
+		{
+			return luaL_error(L, e.what());
+		}
+	}
+	else
+	{
+		instance->retain();
+		love::luax_register_searcher(L, loader, 1);
+		love::luax_register_searcher(L, extloader, 2);
+	}
+
+	WrappedModule w;
+	w.module = instance;
+	w.name = "filesystem";
+	w.flags = MODULE_FILESYSTEM_T;
+	w.functions = functions;
+	w.types = types;
+
+	return luax_register_module(L, w);
+}
+
+} // physfs
+} // filesystem
+} // love

+ 75 - 74
src/modules/filesystem/physfs/wrap_Filesystem.h

@@ -1,74 +1,75 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_FILESYSTEM_PHYSFS_WRAP_FILESYSTEM_H
-#define LOVE_FILESYSTEM_PHYSFS_WRAP_FILESYSTEM_H
-
-// LOVE
-#include "Filesystem.h"
-#include "wrap_File.h"
-#include "wrap_FileData.h"
-
-// SDL
-#include <SDL_loadso.h>
-
-namespace love
-{
-namespace filesystem
-{
-namespace physfs
-{
-	bool hack_setupWriteDirectory();
-	int w_init(lua_State * L);
-	int w_setRelease(lua_State * L);
-	int w_setIdentity(lua_State * L);
-	int w_getIdentity(lua_State * L);
-	int w_setSource(lua_State * L);
-	int w_newFile(lua_State * L);
-	int w_newFileData(lua_State * L);
-	int w_getWorkingDirectory(lua_State * L);
-	int w_getUserDirectory(lua_State * L);
-	int w_getAppdataDirectory(lua_State * L);
-	int w_getSaveDirectory(lua_State * L);
-	int w_exists(lua_State * L);
-	int w_isDirectory(lua_State * L);
-	int w_isFile(lua_State * L);
-	int w_mkdir(lua_State * L);
-	int w_remove(lua_State * L);
-	int w_open(lua_State * L);
-	int w_close(lua_State * L);
-	int w_read(lua_State * L);
-	int w_write(lua_State * L);
-	int w_eof(lua_State * L);
-	int w_tell(lua_State * L);
-	int w_seek(lua_State * L);
-	int w_enumerate(lua_State * L);
-	int w_lines(lua_State * L);
-	int w_load(lua_State * L);
-	int w_getLastModified(lua_State * L);
-	int loader(lua_State * L);
-	int extloader(lua_State * L);
-	extern "C" LOVE_EXPORT int luaopen_love_filesystem(lua_State * L);
-
-} // physfs
-} // filesystem
-} // love
-
-#endif // LOVE_FILESYSTEM_PHYSFS_WRAP_FILESYSTEM_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_FILESYSTEM_PHYSFS_WRAP_FILESYSTEM_H
+#define LOVE_FILESYSTEM_PHYSFS_WRAP_FILESYSTEM_H
+
+// LOVE
+#include "Filesystem.h"
+#include "wrap_File.h"
+#include "wrap_FileData.h"
+
+// SDL
+#include <SDL_loadso.h>
+
+namespace love
+{
+namespace filesystem
+{
+namespace physfs
+{
+
+bool hack_setupWriteDirectory();
+int w_init(lua_State *L);
+int w_setRelease(lua_State *L);
+int w_setIdentity(lua_State *L);
+int w_getIdentity(lua_State *L);
+int w_setSource(lua_State *L);
+int w_newFile(lua_State *L);
+int w_newFileData(lua_State *L);
+int w_getWorkingDirectory(lua_State *L);
+int w_getUserDirectory(lua_State *L);
+int w_getAppdataDirectory(lua_State *L);
+int w_getSaveDirectory(lua_State *L);
+int w_exists(lua_State *L);
+int w_isDirectory(lua_State *L);
+int w_isFile(lua_State *L);
+int w_mkdir(lua_State *L);
+int w_remove(lua_State *L);
+int w_open(lua_State *L);
+int w_close(lua_State *L);
+int w_read(lua_State *L);
+int w_write(lua_State *L);
+int w_eof(lua_State *L);
+int w_tell(lua_State *L);
+int w_seek(lua_State *L);
+int w_enumerate(lua_State *L);
+int w_lines(lua_State *L);
+int w_load(lua_State *L);
+int w_getLastModified(lua_State *L);
+int loader(lua_State *L);
+int extloader(lua_State *L);
+extern "C" LOVE_EXPORT int luaopen_love_filesystem(lua_State *L);
+
+} // physfs
+} // filesystem
+} // love
+
+#endif // LOVE_FILESYSTEM_PHYSFS_WRAP_FILESYSTEM_H

+ 54 - 54
src/modules/font/Font.h

@@ -1,55 +1,55 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_FONT_FONT_H
-#define LOVE_FONT_FONT_H
-
-// LOVE
-#include "Rasterizer.h"
-#include <image/ImageData.h>
-#include <common/Module.h>
-
-// STD
-#include <string>
-
-namespace love
-{
-namespace font
-{
-
-	class Font : public Module
-	{
-
-	public:
-
-		virtual Rasterizer * newRasterizer(Data * data, int size) = 0;
-		virtual Rasterizer * newRasterizer(love::image::ImageData * data, std::string glyphs) = 0;
-		virtual Rasterizer * newRasterizer(love::image::ImageData * data, unsigned short * glyphs, int length) = 0;
-		virtual GlyphData * newGlyphData(Rasterizer * r, unsigned short glyph) = 0;
-
-		// Implement Module
-		virtual const char * getName() const = 0;
-
-	}; // Font
-
-} // font
-} // love
-
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_FONT_FONT_H
+#define LOVE_FONT_FONT_H
+
+// LOVE
+#include "Rasterizer.h"
+#include "image/ImageData.h"
+#include "common/Module.h"
+
+// STD
+#include <string>
+
+namespace love
+{
+namespace font
+{
+
+class Font : public Module
+{
+
+public:
+
+	virtual Rasterizer *newRasterizer(Data *data, int size) = 0;
+	virtual Rasterizer *newRasterizer(love::image::ImageData *data, std::string glyphs) = 0;
+	virtual Rasterizer *newRasterizer(love::image::ImageData *data, unsigned short *glyphs, int length) = 0;
+	virtual GlyphData *newGlyphData(Rasterizer *r, unsigned short glyph) = 0;
+
+	// Implement Module
+	virtual const char *getName() const = 0;
+
+}; // Font
+
+} // font
+} // love
+
 #endif // LOVE_FONT_FONT_H

+ 127 - 122
src/modules/font/GlyphData.cpp

@@ -1,122 +1,127 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "GlyphData.h"
-
-#include <iostream>
-
-namespace love
-{
-namespace font
-{
-
-	GlyphData::GlyphData(unsigned short glyph, GlyphMetrics glyphMetrics, GlyphData::Format f)
-		: glyph(glyph), metrics(glyphMetrics), data(0), format(f)
-	{
-		if (metrics.width && metrics.height)
-		{
-			switch (f) {
-				case GlyphData::FORMAT_LUMINANCE_ALPHA:
-					data = new unsigned char[metrics.width * metrics.height * 2];
-					break;
-				case GlyphData::FORMAT_RGBA:
-				default:
-					data = new unsigned char[metrics.width * metrics.height * 4];
-					break;
-			}
-		}
-	}
-
-	GlyphData::~GlyphData()
-	{
-		delete[] data;
-	}
-
-	void * GlyphData::getData() const
-	{
-		return (void *) data;
-	}
-
-	int GlyphData::getSize() const
-	{
-		switch(format) {
-			case GlyphData::FORMAT_LUMINANCE_ALPHA:
-				return getWidth() * getHeight() * 2;
-				break;
-			case GlyphData::FORMAT_RGBA:
-			default:
-				return getWidth() * getHeight() * 4;
-				break;
-		}
-
-	}
-
-	int GlyphData::getHeight() const
-	{
-		return metrics.height;
-	}
-
-	int GlyphData::getWidth() const
-	{
-		return metrics.width;
-	}
-
-	int GlyphData::getAdvance() const
-	{
-		return metrics.advance;
-	}
-
-	int GlyphData::getBearingX() const
-	{
-		return metrics.bearingX;
-	}
-
-	int GlyphData::getBearingY() const
-	{
-		return metrics.bearingY;
-	}
-
-	int GlyphData::getMinX() const
-	{
-		return this->getBearingX();
-	}
-
-	int GlyphData::getMinY() const
-	{
-		return this->getHeight() - this->getBearingY();
-	}
-
-	int GlyphData::getMaxX() const
-	{
-		return this->getBearingX() + this->getWidth();
-	}
-
-	int GlyphData::getMaxY() const
-	{
-		return this->getBearingY();
-	}
-
-	GlyphData::Format GlyphData::getFormat() const
-	{
-		return format;
-	}
-
-} // font
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "GlyphData.h"
+
+#include <iostream>
+
+namespace love
+{
+namespace font
+{
+
+GlyphData::GlyphData(unsigned short glyph, GlyphMetrics glyphMetrics, GlyphData::Format f)
+	: glyph(glyph)
+	, metrics(glyphMetrics)
+	, data(0)
+	, format(f)
+{
+	if (metrics.width && metrics.height)
+	{
+		switch (f)
+		{
+		case GlyphData::FORMAT_LUMINANCE_ALPHA:
+			data = new unsigned char[metrics.width * metrics.height * 2];
+			break;
+		case GlyphData::FORMAT_RGBA:
+		default:
+			data = new unsigned char[metrics.width * metrics.height * 4];
+			break;
+		}
+	}
+}
+
+GlyphData::~GlyphData()
+{
+	delete[] data;
+}
+
+void *GlyphData::getData() const
+{
+	return (void *) data;
+}
+
+int GlyphData::getSize() const
+{
+	switch (format)
+	{
+	case GlyphData::FORMAT_LUMINANCE_ALPHA:
+		return getWidth() * getHeight() * 2;
+		break;
+	case GlyphData::FORMAT_RGBA:
+	default:
+		return getWidth() * getHeight() * 4;
+		break;
+	}
+
+}
+
+int GlyphData::getHeight() const
+{
+	return metrics.height;
+}
+
+int GlyphData::getWidth() const
+{
+	return metrics.width;
+}
+
+int GlyphData::getAdvance() const
+{
+	return metrics.advance;
+}
+
+int GlyphData::getBearingX() const
+{
+	return metrics.bearingX;
+}
+
+int GlyphData::getBearingY() const
+{
+	return metrics.bearingY;
+}
+
+int GlyphData::getMinX() const
+{
+	return this->getBearingX();
+}
+
+int GlyphData::getMinY() const
+{
+	return this->getHeight() - this->getBearingY();
+}
+
+int GlyphData::getMaxX() const
+{
+	return this->getBearingX() + this->getWidth();
+}
+
+int GlyphData::getMaxY() const
+{
+	return this->getBearingY();
+}
+
+GlyphData::Format GlyphData::getFormat() const
+{
+	return format;
+}
+
+} // font
+} // love

+ 134 - 133
src/modules/font/GlyphData.h

@@ -1,133 +1,134 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_FONT_GLYPH_DATA_H
-#define LOVE_FONT_GLYPH_DATA_H
-
-// LOVE
-#include <common/config.h>
-#include <common/Data.h>
-
-namespace love
-{
-namespace font
-{
-	/**
-	* Holds the specific glyph data.
-	**/
-	struct GlyphMetrics
-	{
-		int height;
-		int width;
-		int advance;
-		int bearingX;
-		int bearingY;
-		int spacing;
-	};
-
-	/**
-	* Holds data for a specic glyph object.
-	**/
-	class GlyphData : public Data
-	{
-
-	public:
-		enum Format
-		{
-			FORMAT_LUMINANCE_ALPHA,
-			FORMAT_RGBA
-		};
-
-		GlyphData(unsigned short glyph, GlyphMetrics glyphMetrics, Format f);
-		virtual ~GlyphData();
-
-		// Implements Data.
-		void * getData() const;
-		int getSize() const;
-
-		/**
-		* Gets the height of the glyph.
-		**/
-		virtual int getHeight() const;
-
-		/**
-		* Gets the width of the glyph.
-		**/
-		virtual int getWidth() const;
-
-		/**
-		* Gets the advance (the space the glyph takes up) of the glyph.
-		**/
-		int getAdvance() const;
-
-		/**
-		* Gets bearing (the spacing from origin) along the x-axis of the glyph.
-		**/
-		int getBearingX() const;
-
-		/**
-		* Gets bearing (the spacing from origin) along the y-axis of the glyph.
-		**/
-		int getBearingY() const;
-
-		/**
-		* Gets the min x value of the glyph.
-		**/
-		int getMinX() const;
-
-		/**
-		* Gets the min y value of the glyph.
-		**/
-		int getMinY() const;
-
-		/**
-		* Gets the max x value of the glyph.
-		**/
-		int getMaxX() const;
-
-		/**
-		* Gets the max y value of the glyph.
-		**/
-		int getMaxY() const;
-
-		/**
-		* Gets the format of the glyph data.
-		**/
-		Format getFormat() const;
-
-	private:
-		// The glyph itself
-		unsigned short glyph;
-
-		// Glyph metrics
-		GlyphMetrics metrics;
-
-		// Glyph texture data
-		unsigned char * data;
-
-		// The format the data's in
-		Format format;
-
-	}; // GlyphData
-
-} // font
-} // love
-
-#endif // LOVE_FONT_GLYPH_DATA_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_FONT_GLYPH_DATA_H
+#define LOVE_FONT_GLYPH_DATA_H
+
+// LOVE
+#include "common/config.h"
+#include "common/Data.h"
+
+namespace love
+{
+namespace font
+{
+
+/**
+ * Holds the specific glyph data.
+ **/
+struct GlyphMetrics
+{
+	int height;
+	int width;
+	int advance;
+	int bearingX;
+	int bearingY;
+	int spacing;
+};
+
+/**
+ * Holds data for a specic glyph object.
+ **/
+class GlyphData : public Data
+{
+
+public:
+	enum Format
+	{
+		FORMAT_LUMINANCE_ALPHA,
+		FORMAT_RGBA
+	};
+
+	GlyphData(unsigned short glyph, GlyphMetrics glyphMetrics, Format f);
+	virtual ~GlyphData();
+
+	// Implements Data.
+	void *getData() const;
+	int getSize() const;
+
+	/**
+	 * Gets the height of the glyph.
+	 **/
+	virtual int getHeight() const;
+
+	/**
+	 * Gets the width of the glyph.
+	 **/
+	virtual int getWidth() const;
+
+	/**
+	 * Gets the advance (the space the glyph takes up) of the glyph.
+	 **/
+	int getAdvance() const;
+
+	/**
+	 * Gets bearing (the spacing from origin) along the x-axis of the glyph.
+	 **/
+	int getBearingX() const;
+
+	/**
+	 * Gets bearing (the spacing from origin) along the y-axis of the glyph.
+	 **/
+	int getBearingY() const;
+
+	/**
+	 * Gets the min x value of the glyph.
+	 **/
+	int getMinX() const;
+
+	/**
+	 * Gets the min y value of the glyph.
+	 **/
+	int getMinY() const;
+
+	/**
+	 * Gets the max x value of the glyph.
+	 **/
+	int getMaxX() const;
+
+	/**
+	 * Gets the max y value of the glyph.
+	 **/
+	int getMaxY() const;
+
+	/**
+	 * Gets the format of the glyph data.
+	 **/
+	Format getFormat() const;
+
+private:
+	// The glyph itself
+	unsigned short glyph;
+
+	// Glyph metrics
+	GlyphMetrics metrics;
+
+	// Glyph texture data
+	unsigned char *data;
+
+	// The format the data's in
+	Format format;
+
+}; // GlyphData
+
+} // font
+} // love
+
+#endif // LOVE_FONT_GLYPH_DATA_H

+ 153 - 151
src/modules/font/ImageRasterizer.cpp

@@ -1,151 +1,153 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-// LOVE
-#include "ImageRasterizer.h"
-
-#include <common/Exception.h>
-#include <string.h>
-
-namespace love
-{
-namespace font
-{
-
-	inline bool equal(const love::image::pixel& a, const love::image::pixel& b)
-	{
-		return (a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a);
-	}
-
-	ImageRasterizer::ImageRasterizer(love::image::ImageData * data, unsigned short * glyphs, int length)
-		: imageData(data), glyphs(glyphs), length(length)
-	{
-		imageData->retain();
-		positions = new unsigned int[MAX_CHARS];
-		memset(positions, 0, MAX_CHARS*4);
-		widths = new unsigned int[MAX_CHARS];
-		memset(widths, 0, MAX_CHARS*4);
-		spacing = new unsigned int[MAX_CHARS];
-		memset(spacing, 0, MAX_CHARS*4);
-		load();
-	}
-
-	ImageRasterizer::~ImageRasterizer()
-	{
-		imageData->release();
-		delete[] positions;
-		delete[] widths;
-		delete[] spacing;
-	}
-
-	int ImageRasterizer::getLineHeight() const
-	{
-		return getHeight();
-	}
-
-	GlyphData * ImageRasterizer::getGlyphData(unsigned short glyph) const
-	{
-		GlyphMetrics gm;
-		gm.height = metrics.height;
-		gm.width = widths[glyph];
-		gm.advance = spacing[glyph] + widths[glyph];
-		gm.bearingX = 0;
-		gm.bearingY = 0;
-		GlyphData * g = new GlyphData(glyph, gm, GlyphData::FORMAT_RGBA);
-		if (gm.width == 0) return g;
-		unsigned char * gd = (unsigned char*)g->getData();
-		love::image::pixel * pixels = (love::image::pixel *)(imageData->getData());
-		for (unsigned int i = 0; i < widths[glyph]*getHeight(); i++)
-		{
-			love::image::pixel p = pixels[ positions[glyph] + (i % widths[glyph]) + (imageData->getWidth() * (i / widths[glyph])) ];
-			gd[i*4] = p.r;
-			gd[i*4+1] = p.g;
-			gd[i*4+2] = p.b;
-			gd[i*4+3] = p.a;
-		}
-		return g;
-	}
-
-	void ImageRasterizer::load()
-	{
-		love::image::pixel * pixels = (love::image::pixel *)(imageData->getData());
-
-		unsigned imgw = (unsigned)imageData->getWidth();
-		unsigned imgh = (unsigned)imageData->getHeight();
-		unsigned imgs = imgw*imgh;
-
-		// Set the only metric that matters
-		metrics.height = imgh;
-
-		// Reading texture data begins
-		love::image::pixel spacer = pixels[0];
-
-		unsigned int start = 0;
-		unsigned int end = 0;
-
-		for (unsigned int i = 0; i < length; ++i)
-		{
-			if (i >= MAX_CHARS)
-				break;
-
-			start = end;
-
-			// Finds out where the first character starts
-			while (start < imgw && equal(pixels[start], spacer))
-				++start;
-
-			if (i > 0)
-				spacing[glyphs[i - 1]] = (start > end) ? (start - end) : 0;
-
-			end = start;
-
-			// Find where glyph ends.
-			while (end < imgw && !equal(pixels[end], spacer))
-				++end;
-
-			if (start >= end)
-				break;
-
-			unsigned c = glyphs[i];
-
-			positions[c] = start;
-			widths[c] = (end - start);
-		}
-
-		// Replace spacer color with an empty pixel
-		for (unsigned int i = 0; i < imgs; ++i)
-		{
-			if (equal(pixels[i], spacer))
-			{
-				pixels[i].r = 0;
-				pixels[i].g = 0;
-				pixels[i].b = 0;
-				pixels[i].a = 0;
-			}
-		}
-	}
-
-	int ImageRasterizer::getNumGlyphs() const
-	{
-		return length;
-	}
-
-} // font
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+// LOVE
+#include "ImageRasterizer.h"
+
+#include "common/Exception.h"
+#include <string.h>
+
+namespace love
+{
+namespace font
+{
+
+inline bool equal(const love::image::pixel &a, const love::image::pixel &b)
+{
+	return (a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a);
+}
+
+ImageRasterizer::ImageRasterizer(love::image::ImageData *data, unsigned short *glyphs, int length)
+	: imageData(data)
+	, glyphs(glyphs)
+	, length(length)
+{
+	imageData->retain();
+	positions = new unsigned int[MAX_CHARS];
+	memset(positions, 0, MAX_CHARS*4);
+	widths = new unsigned int[MAX_CHARS];
+	memset(widths, 0, MAX_CHARS*4);
+	spacing = new unsigned int[MAX_CHARS];
+	memset(spacing, 0, MAX_CHARS*4);
+	load();
+}
+
+ImageRasterizer::~ImageRasterizer()
+{
+	imageData->release();
+	delete[] positions;
+	delete[] widths;
+	delete[] spacing;
+}
+
+int ImageRasterizer::getLineHeight() const
+{
+	return getHeight();
+}
+
+GlyphData *ImageRasterizer::getGlyphData(unsigned short glyph) const
+{
+	GlyphMetrics gm;
+	gm.height = metrics.height;
+	gm.width = widths[glyph];
+	gm.advance = spacing[glyph] + widths[glyph];
+	gm.bearingX = 0;
+	gm.bearingY = 0;
+	GlyphData *g = new GlyphData(glyph, gm, GlyphData::FORMAT_RGBA);
+	if (gm.width == 0) return g;
+	unsigned char *gd = (unsigned char *)g->getData();
+	love::image::pixel *pixels = (love::image::pixel *)(imageData->getData());
+	for (unsigned int i = 0; i < widths[glyph]*getHeight(); i++)
+	{
+		love::image::pixel p = pixels[ positions[glyph] + (i % widths[glyph]) + (imageData->getWidth() * (i / widths[glyph])) ];
+		gd[i*4] = p.r;
+		gd[i*4+1] = p.g;
+		gd[i*4+2] = p.b;
+		gd[i*4+3] = p.a;
+	}
+	return g;
+}
+
+void ImageRasterizer::load()
+{
+	love::image::pixel *pixels = (love::image::pixel *)(imageData->getData());
+
+	unsigned imgw = (unsigned)imageData->getWidth();
+	unsigned imgh = (unsigned)imageData->getHeight();
+	unsigned imgs = imgw*imgh;
+
+	// Set the only metric that matters
+	metrics.height = imgh;
+
+	// Reading texture data begins
+	love::image::pixel spacer = pixels[0];
+
+	unsigned int start = 0;
+	unsigned int end = 0;
+
+	for (unsigned int i = 0; i < length; ++i)
+	{
+		if (i >= MAX_CHARS)
+			break;
+
+		start = end;
+
+		// Finds out where the first character starts
+		while (start < imgw && equal(pixels[start], spacer))
+			++start;
+
+		if (i > 0)
+			spacing[glyphs[i - 1]] = (start > end) ? (start - end) : 0;
+
+		end = start;
+
+		// Find where glyph ends.
+		while (end < imgw && !equal(pixels[end], spacer))
+			++end;
+
+		if (start >= end)
+			break;
+
+		unsigned c = glyphs[i];
+
+		positions[c] = start;
+		widths[c] = (end - start);
+	}
+
+	// Replace spacer color with an empty pixel
+	for (unsigned int i = 0; i < imgs; ++i)
+	{
+		if (equal(pixels[i], spacer))
+		{
+			pixels[i].r = 0;
+			pixels[i].g = 0;
+			pixels[i].b = 0;
+			pixels[i].a = 0;
+		}
+	}
+}
+
+int ImageRasterizer::getNumGlyphs() const
+{
+	return length;
+}
+
+} // font
+} // love

+ 71 - 70
src/modules/font/ImageRasterizer.h

@@ -1,71 +1,72 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_FONT_IMAGE_RASTERIZER_H
-#define LOVE_FONT_IMAGE_RASTERIZER_H
-
-// LOVE
-#include <filesystem/File.h>
-#include <font/Rasterizer.h>
-#include <image/ImageData.h>
-
-namespace love
-{
-namespace font
-{
-	/**
-	* Holds data for a font object.
-	**/
-	class ImageRasterizer : public Rasterizer
-	{
-	private:
-		// Load all the glyph positions into memory
-		void load();
-
-		// The image data
-		love::image::ImageData * imageData;
-		// The glyphs in the font
-		unsigned short * glyphs;
-		// The length of the glyph array
-		unsigned int length;
-		// The positions of each glyph
-		unsigned int * positions;
-		// The widths of each glyph
-		unsigned int * widths;
-		// The spacing of each glyph
-		unsigned int * spacing;
-
-	public:
-		ImageRasterizer(love::image::ImageData * imageData, unsigned short * glyphs, int length);
-		virtual ~ImageRasterizer();
-
-		// Implement Rasterizer
-		virtual int getLineHeight() const;
-		virtual GlyphData * getGlyphData(unsigned short glyph) const;
-		virtual int getNumGlyphs() const;
-
-		static const unsigned int MAX_CHARS = 256;
-
-	}; // ImageRasterizer
-
-} // font
-} // love
-
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_FONT_IMAGE_RASTERIZER_H
+#define LOVE_FONT_IMAGE_RASTERIZER_H
+
+// LOVE
+#include "filesystem/File.h"
+#include "font/Rasterizer.h"
+#include "image/ImageData.h"
+
+namespace love
+{
+namespace font
+{
+
+/**
+ * Holds data for a font object.
+ **/
+class ImageRasterizer : public Rasterizer
+{
+private:
+	// Load all the glyph positions into memory
+	void load();
+
+	// The image data
+	love::image::ImageData *imageData;
+	// The glyphs in the font
+	unsigned short *glyphs;
+	// The length of the glyph array
+	unsigned int length;
+	// The positions of each glyph
+	unsigned int *positions;
+	// The widths of each glyph
+	unsigned int *widths;
+	// The spacing of each glyph
+	unsigned int *spacing;
+
+public:
+	ImageRasterizer(love::image::ImageData *imageData, unsigned short *glyphs, int length);
+	virtual ~ImageRasterizer();
+
+	// Implement Rasterizer
+	virtual int getLineHeight() const;
+	virtual GlyphData *getGlyphData(unsigned short glyph) const;
+	virtual int getNumGlyphs() const;
+
+	static const unsigned int MAX_CHARS = 256;
+
+}; // ImageRasterizer
+
+} // font
+} // love
+
 #endif // LOVE_FONT_IMAGE_RASTERIZER_H

+ 53 - 53
src/modules/font/Rasterizer.cpp

@@ -1,54 +1,54 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-// LOVE
-#include "Rasterizer.h"
-
-namespace love
-{
-namespace font
-{
-
-	Rasterizer::~Rasterizer()
-	{
-	}
-
-	int Rasterizer::getHeight() const
-	{
-		return metrics.height;
-	}
-
-	int Rasterizer::getAdvance() const
-	{
-		return metrics.advance;
-	}
-
-	int Rasterizer::getAscent() const
-	{
-		return metrics.ascent;
-	}
-
-	int Rasterizer::getDescent() const
-	{
-		return metrics.descent;
-	}
-
-} // font
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+// LOVE
+#include "Rasterizer.h"
+
+namespace love
+{
+namespace font
+{
+
+Rasterizer::~Rasterizer()
+{
+}
+
+int Rasterizer::getHeight() const
+{
+	return metrics.height;
+}
+
+int Rasterizer::getAdvance() const
+{
+	return metrics.advance;
+}
+
+int Rasterizer::getAscent() const
+{
+	return metrics.ascent;
+}
+
+int Rasterizer::getDescent() const
+{
+	return metrics.descent;
+}
+
+} // font
 } // love

+ 97 - 96
src/modules/font/Rasterizer.h

@@ -1,97 +1,98 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_FONT_RASTERIZER_H
-#define LOVE_FONT_RASTERIZER_H
-
-// LOVE
-#include <common/Object.h>
-#include "GlyphData.h"
-
-namespace love
-{
-namespace font
-{
-	/**
-	* Holds the specific font metrics.
-	**/
-	struct FontMetrics
-	{
-		int advance;
-		int ascent;
-		int descent;
-		int height;
-	};
-
-	/**
-	* Holds data for a font object.
-	**/
-	class Rasterizer : public Object
-	{
-	protected:
-		FontMetrics metrics;
-
-	public:
-
-		virtual ~Rasterizer();
-
-		/**
-		* Gets the max height of the glyphs.
-		**/
-		virtual int getHeight() const;
-
-		/**
-		* Gets the max advance of the glyphs.
-		**/
-		virtual int getAdvance() const;
-
-		/**
-		* Gets the max ascent (height above baseline) for the font.
-		**/
-		virtual int getAscent() const;
-
-		/**
-		* Gets the max descent (height below baseline) for the font.
-		**/
-		virtual int getDescent() const;
-
-		/**
-		* Gets the line height of the font.
-		**/
-		virtual int getLineHeight() const = 0;
-
-		/**
-		* Gets a specific glyph.
-		* @param glyph The (UNICODE) glyph to get data for
-		**/
-		virtual GlyphData * getGlyphData(unsigned short glyph) const = 0;
-
-		/**
-		* Gets the number of glyphs the rasterizer has data for.
-		**/
-		virtual int getNumGlyphs() const = 0;
-
-
-	}; // Rasterizer
-
-} // font
-} // love
-
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_FONT_RASTERIZER_H
+#define LOVE_FONT_RASTERIZER_H
+
+// LOVE
+#include "common/Object.h"
+#include "GlyphData.h"
+
+namespace love
+{
+namespace font
+{
+
+/**
+ * Holds the specific font metrics.
+ **/
+struct FontMetrics
+{
+	int advance;
+	int ascent;
+	int descent;
+	int height;
+};
+
+/**
+ * Holds data for a font object.
+ **/
+class Rasterizer : public Object
+{
+protected:
+	FontMetrics metrics;
+
+public:
+
+	virtual ~Rasterizer();
+
+	/**
+	 * Gets the max height of the glyphs.
+	 **/
+	virtual int getHeight() const;
+
+	/**
+	 * Gets the max advance of the glyphs.
+	 **/
+	virtual int getAdvance() const;
+
+	/**
+	 * Gets the max ascent (height above baseline) for the font.
+	 **/
+	virtual int getAscent() const;
+
+	/**
+	 * Gets the max descent (height below baseline) for the font.
+	 **/
+	virtual int getDescent() const;
+
+	/**
+	 * Gets the line height of the font.
+	 **/
+	virtual int getLineHeight() const = 0;
+
+	/**
+	 * Gets a specific glyph.
+	 * @param glyph The (UNICODE) glyph to get data for
+	 **/
+	virtual GlyphData *getGlyphData(unsigned short glyph) const = 0;
+
+	/**
+	 * Gets the number of glyphs the rasterizer has data for.
+	 **/
+	virtual int getNumGlyphs() const = 0;
+
+
+}; // Rasterizer
+
+} // font
+} // love
+
 #endif // LOVE_FONT_RASTERIZER_H

+ 79 - 78
src/modules/font/freetype/Font.cpp

@@ -1,78 +1,79 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "Font.h"
-
-#include "TrueTypeRasterizer.h"
-#include <font/ImageRasterizer.h>
-
-namespace love
-{
-namespace font
-{
-namespace freetype
-{
-	Font::Font()
-	{
-		if (FT_Init_FreeType(&library))
-			throw love::Exception("TrueTypeFont Loading error: FT_Init_FreeType failed\n");
-	}
-
-	Font::~Font()
-	{
-		FT_Done_FreeType(library);
-	}
-
-	Rasterizer * Font::newRasterizer(Data * data, int size)
-	{
-		return new TrueTypeRasterizer(library, data, size);
-	}
-
-	Rasterizer * Font::newRasterizer(love::image::ImageData * data, std::string glyphs)
-	{
-		int length = glyphs.size();
-		unsigned short * g = new unsigned short[length];
-		for (int i = 0; i < length; i++)
-		{
-			g[i] = (unsigned char)glyphs[i];
-		}
-		Rasterizer * r = newRasterizer(data, g, length);
-		delete [] g;
-		return r;
-	}
-
-	Rasterizer * Font::newRasterizer(love::image::ImageData * data, unsigned short * glyphs, int length)
-	{
-		return new ImageRasterizer(data, glyphs, length);
-	}
-
-	GlyphData * Font::newGlyphData(Rasterizer * r, unsigned short glyph)
-	{
-		return r->getGlyphData(glyph);
-	}
-
-	const char * Font::getName() const
-	{
-		return "love.font.freetype";
-	}
-
-} // freetype
-} // font
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "Font.h"
+
+#include "TrueTypeRasterizer.h"
+#include "font/ImageRasterizer.h"
+
+namespace love
+{
+namespace font
+{
+namespace freetype
+{
+
+Font::Font()
+{
+	if (FT_Init_FreeType(&library))
+		throw love::Exception("TrueTypeFont Loading error: FT_Init_FreeType failed\n");
+}
+
+Font::~Font()
+{
+	FT_Done_FreeType(library);
+}
+
+Rasterizer *Font::newRasterizer(Data *data, int size)
+{
+	return new TrueTypeRasterizer(library, data, size);
+}
+
+Rasterizer *Font::newRasterizer(love::image::ImageData *data, std::string glyphs)
+{
+	int length = glyphs.size();
+	unsigned short *g = new unsigned short[length];
+	for (int i = 0; i < length; i++)
+	{
+		g[i] = (unsigned char)glyphs[i];
+	}
+	Rasterizer *r = newRasterizer(data, g, length);
+	delete [] g;
+	return r;
+}
+
+Rasterizer *Font::newRasterizer(love::image::ImageData *data, unsigned short *glyphs, int length)
+{
+	return new ImageRasterizer(data, glyphs, length);
+}
+
+GlyphData *Font::newGlyphData(Rasterizer *r, unsigned short glyph)
+{
+	return r->getGlyphData(glyph);
+}
+
+const char *Font::getName() const
+{
+	return "love.font.freetype";
+}
+
+} // freetype
+} // font
+} // love

+ 74 - 75
src/modules/font/freetype/Font.h

@@ -1,76 +1,75 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_FONT_FREETYPE_FONT_H
-#define LOVE_FONT_FREETYPE_FONT_H
-
-// LOVE
-#include <font/Font.h>
-
-// FreeType2
-#ifdef LOVE_MACOSX
-#include <freetype/ft2build.h>
-#else
-#include <ft2build.h>
-#endif
-#include <freetype/freetype.h>
-#include <freetype/ftglyph.h>
-#include <freetype/ftoutln.h>
-#include <freetype/fttrigon.h>
-
-namespace love
-{
-namespace font
-{
-namespace freetype
-{
-
-	class Font : public love::font::Font
-	{
-	private:
-
-		// FreeType library
-		FT_Library library;
-
-	public:
-
-		Font();
-
-		/**
-		* Destructor.
-		**/
-		virtual ~Font();
-
-		// Implements Font
-		Rasterizer * newRasterizer(Data * data, int size);
-		Rasterizer * newRasterizer(love::image::ImageData * data, std::string glyphs);
-		Rasterizer * newRasterizer(love::image::ImageData * data, unsigned short * glyphs, int length);
-		GlyphData * newGlyphData(Rasterizer * r, unsigned short glyph);
-
-		// Implement Module
-		const char * getName() const;
-
-	}; // Font
-
-} // freetype
-} // font
-} // love
-
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_FONT_FREETYPE_FONT_H
+#define LOVE_FONT_FREETYPE_FONT_H
+
+// LOVE
+#include "font/Font.h"
+
+// FreeType2
+#ifdef LOVE_MACOSX
+#include <freetype/ft2build.h>
+#else
+#include <ft2build.h>
+#endif
+#include <freetype/freetype.h>
+#include <freetype/ftglyph.h>
+#include <freetype/ftoutln.h>
+#include <freetype/fttrigon.h>
+
+namespace love
+{
+namespace font
+{
+namespace freetype
+{
+
+class Font : public love::font::Font
+{
+public:
+
+	Font();
+
+	/**
+	 * Destructor.
+	 **/
+	virtual ~Font();
+
+	// Implements Font
+	Rasterizer *newRasterizer(Data *data, int size);
+	Rasterizer *newRasterizer(love::image::ImageData *data, std::string glyphs);
+	Rasterizer *newRasterizer(love::image::ImageData *data, unsigned short *glyphs, int length);
+	GlyphData *newGlyphData(Rasterizer *r, unsigned short glyph);
+
+	// Implement Module
+	const char *getName() const;
+
+private:
+
+	// FreeType library
+	FT_Library library;
+}; // Font
+
+} // freetype
+} // font
+} // love
+
 #endif // LOVE_FONT_FREETYPE_FONT_H

+ 122 - 118
src/modules/font/freetype/TrueTypeRasterizer.cpp

@@ -1,119 +1,123 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-// LOVE
-#include "TrueTypeRasterizer.h"
-
-#include <common/Exception.h>
-
-namespace love
-{
-namespace font
-{
-namespace freetype
-{
-	struct la { unsigned char l,a; };
-
-	TrueTypeRasterizer::TrueTypeRasterizer(FT_Library library, Data * data, int size)
-		: data(data)
-	{
-		data->retain();
-
-		if (FT_New_Memory_Face(	library,
-								(const FT_Byte *)data->getData(),	/* first byte in memory */
-								data->getSize(),					/* size in bytes        */
-								0,									/* face_index           */
-								&face))
-			throw love::Exception("TrueTypeFont Loading error: FT_New_Face failed (there is probably a problem with your font file)\n");
-
-		FT_Set_Pixel_Sizes(face, size, size);
-
-		// Set global metrics
-		FT_Size_Metrics s = face->size->metrics;
-		metrics.advance = s.max_advance >> 6;
-		metrics.ascent = s.ascender >> 6;
-		metrics.descent = s.descender >> 6;
-		metrics.height = s.height >> 6;
-	}
-
-	TrueTypeRasterizer::~TrueTypeRasterizer()
-	{
-		FT_Done_Face(face);
-		data->release();
-	}
-
-	int TrueTypeRasterizer::getLineHeight() const
-	{
-		return (int)(getHeight() * 1.25);
-	}
-
-	GlyphData * TrueTypeRasterizer::getGlyphData(unsigned short glyph) const
-	{
-		love::font::GlyphMetrics glyphMetrics;
-		FT_Glyph ftglyph;
-
-		// Initialize
-		if (FT_Load_Glyph(face, FT_Get_Char_Index(face, glyph), FT_LOAD_DEFAULT))
-			throw love::Exception("TrueTypeFont Loading vm->error: FT_Load_Glyph failed\n");
-
-		if ( FT_Get_Glyph(face->glyph, &ftglyph) )
-			throw love::Exception("TrueTypeFont Loading vm->error: FT_Get_Glyph failed\n");
-
-		FT_Glyph_To_Bitmap(&ftglyph, FT_RENDER_MODE_NORMAL, 0, 1);
-		FT_BitmapGlyph bitmap_glyph = (FT_BitmapGlyph)ftglyph;
-		FT_Bitmap& bitmap = bitmap_glyph->bitmap; //just to make things easier
-
-		// Get metrics
-		glyphMetrics.bearingX = face->glyph->metrics.horiBearingX >> 6;
-		glyphMetrics.bearingY = face->glyph->metrics.horiBearingY >> 6;
-		glyphMetrics.height = bitmap.rows;
-		glyphMetrics.width = bitmap.width;
-		glyphMetrics.advance = face->glyph->metrics.horiAdvance >> 6;
-
-		GlyphData * glyphData = new GlyphData(glyph, glyphMetrics, GlyphData::FORMAT_LUMINANCE_ALPHA);
-
-		{
-			int size = bitmap.rows*bitmap.width;
-			unsigned char * dst = (unsigned char *)glyphData->getData();
-
-			// Note that bitmap.buffer contains only luminosity. We copy that single value to
-			// our luminosity-alpha format.
-			for (int i = 0; i<size; i++)
-			{
-				dst[2*i] = 255;
-				dst[2*i+1] = bitmap.buffer[i];
-			}
-		}
-
-		// Having copied the data over, we can destroy the glyph
-		FT_Done_Glyph(ftglyph);
-
-		// Return data
-		return glyphData;
-	}
-
-	int TrueTypeRasterizer::getNumGlyphs() const
-	{
-		return 256;
-	}
-
-} // freetype
-} // font
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+// LOVE
+#include "TrueTypeRasterizer.h"
+
+#include "common/Exception.h"
+
+namespace love
+{
+namespace font
+{
+namespace freetype
+{
+
+struct la
+{
+	unsigned char l,a;
+};
+
+TrueTypeRasterizer::TrueTypeRasterizer(FT_Library library, Data *data, int size)
+	: data(data)
+{
+	data->retain();
+
+	if (FT_New_Memory_Face(library,
+						  (const FT_Byte *)data->getData(),	/* first byte in memory */
+						  data->getSize(),					/* size in bytes        */
+						  0,									/* face_index           */
+						  &face))
+		throw love::Exception("TrueTypeFont Loading error: FT_New_Face failed (there is probably a problem with your font file)\n");
+
+	FT_Set_Pixel_Sizes(face, size, size);
+
+	// Set global metrics
+	FT_Size_Metrics s = face->size->metrics;
+	metrics.advance = s.max_advance >> 6;
+	metrics.ascent = s.ascender >> 6;
+	metrics.descent = s.descender >> 6;
+	metrics.height = s.height >> 6;
+}
+
+TrueTypeRasterizer::~TrueTypeRasterizer()
+{
+	FT_Done_Face(face);
+	data->release();
+}
+
+int TrueTypeRasterizer::getLineHeight() const
+{
+	return (int)(getHeight() * 1.25);
+}
+
+GlyphData *TrueTypeRasterizer::getGlyphData(unsigned short glyph) const
+{
+	love::font::GlyphMetrics glyphMetrics;
+	FT_Glyph ftglyph;
+
+	// Initialize
+	if (FT_Load_Glyph(face, FT_Get_Char_Index(face, glyph), FT_LOAD_DEFAULT))
+		throw love::Exception("TrueTypeFont Loading vm->error: FT_Load_Glyph failed\n");
+
+	if (FT_Get_Glyph(face->glyph, &ftglyph))
+		throw love::Exception("TrueTypeFont Loading vm->error: FT_Get_Glyph failed\n");
+
+	FT_Glyph_To_Bitmap(&ftglyph, FT_RENDER_MODE_NORMAL, 0, 1);
+	FT_BitmapGlyph bitmap_glyph = (FT_BitmapGlyph)ftglyph;
+	FT_Bitmap &bitmap = bitmap_glyph->bitmap; //just to make things easier
+
+	// Get metrics
+	glyphMetrics.bearingX = face->glyph->metrics.horiBearingX >> 6;
+	glyphMetrics.bearingY = face->glyph->metrics.horiBearingY >> 6;
+	glyphMetrics.height = bitmap.rows;
+	glyphMetrics.width = bitmap.width;
+	glyphMetrics.advance = face->glyph->metrics.horiAdvance >> 6;
+
+	GlyphData *glyphData = new GlyphData(glyph, glyphMetrics, GlyphData::FORMAT_LUMINANCE_ALPHA);
+
+	{
+		int size = bitmap.rows*bitmap.width;
+		unsigned char *dst = (unsigned char *)glyphData->getData();
+
+		// Note that bitmap.buffer contains only luminosity. We copy that single value to
+		// our luminosity-alpha format.
+		for (int i = 0; i<size; i++)
+		{
+			dst[2*i] = 255;
+			dst[2*i+1] = bitmap.buffer[i];
+		}
+	}
+
+	// Having copied the data over, we can destroy the glyph
+	FT_Done_Glyph(ftglyph);
+
+	// Return data
+	return glyphData;
+}
+
+int TrueTypeRasterizer::getNumGlyphs() const
+{
+	return 256;
+}
+
+} // freetype
+} // font
 } // love

+ 68 - 69
src/modules/font/freetype/TrueTypeRasterizer.h

@@ -1,70 +1,69 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_FONT_FREETYPE_TRUE_TYPE_RASTERIZER_H
-#define LOVE_FONT_FREETYPE_TRUE_TYPE_RASTERIZER_H
-
-// LOVE
-#include <filesystem/File.h>
-#include <font/Rasterizer.h>
-
-// TrueType2
-#include <ft2build.h>
-#include <freetype/freetype.h>
-#include <freetype/ftglyph.h>
-#include <freetype/ftoutln.h>
-#include <freetype/fttrigon.h>
-
-namespace love
-{
-namespace font
-{
-namespace freetype
-{
-	/**
-	* Holds data for a font object.
-	**/
-	class TrueTypeRasterizer : public Rasterizer
-	{
-	private:
-
-
-		// TrueType face
-		FT_Face face;
-
-		// File data
-		Data * data;
-
-	public:
-		TrueTypeRasterizer(FT_Library library, Data * data, int size);
-		virtual ~TrueTypeRasterizer();
-
-		// Implement Rasterizer
-		virtual int getLineHeight() const;
-		virtual GlyphData * getGlyphData(unsigned short glyph) const;
-		virtual int getNumGlyphs() const;
-
-	}; // FreetypeRasterizer
-
-} // freetype
-} // font
-} // love
-
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_FONT_FREETYPE_TRUE_TYPE_RASTERIZER_H
+#define LOVE_FONT_FREETYPE_TRUE_TYPE_RASTERIZER_H
+
+// LOVE
+#include "filesystem/File.h"
+#include "font/Rasterizer.h"
+
+// TrueType2
+#include <ft2build.h>
+#include <freetype/freetype.h>
+#include <freetype/ftglyph.h>
+#include <freetype/ftoutln.h>
+#include <freetype/fttrigon.h>
+
+namespace love
+{
+namespace font
+{
+namespace freetype
+{
+
+/**
+ * Holds data for a font object.
+ **/
+class TrueTypeRasterizer : public Rasterizer
+{
+public:
+	TrueTypeRasterizer(FT_Library library, Data *data, int size);
+	virtual ~TrueTypeRasterizer();
+
+	// Implement Rasterizer
+	virtual int getLineHeight() const;
+	virtual GlyphData *getGlyphData(unsigned short glyph) const;
+	virtual int getNumGlyphs() const;
+
+private:
+
+	// TrueType face
+	FT_Face face;
+
+	// File data
+	Data *data;
+}; // FreetypeRasterizer
+
+} // freetype
+} // font
+} // love
+
 #endif // LOVE_FONT_FREETYPE_TRUE_TYPE_RASTERIZER_H

+ 113 - 110
src/modules/font/freetype/wrap_Font.cpp

@@ -1,110 +1,113 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "wrap_Font.h"
-
-#include "Font.h"
-
-#include <font/wrap_GlyphData.h>
-#include <font/wrap_Rasterizer.h>
-
-#include "TrueTypeRasterizer.h"
-
-namespace love
-{
-namespace font
-{
-namespace freetype
-{
-	static Font * instance = 0;
-
-	int w_newRasterizer(lua_State * L)
-	{
-		Rasterizer * t = NULL;
-		if (luax_istype(L, 1, IMAGE_IMAGE_DATA_T))
-		{
-			love::image::ImageData * d = luax_checktype<love::image::ImageData>(L, 1, "ImageData", IMAGE_IMAGE_DATA_T);
-			const char * g = luaL_checkstring(L, 2);
-			std::string glyphs(g);
-			t = instance->newRasterizer(d, glyphs);
-		}
-		else if (luax_istype(L, 1, DATA_T))
-		{
-			Data * d = luax_checkdata(L, 1);
-			int size = luaL_checkint(L, 2);
-			t = instance->newRasterizer(d, size);
-		}
-
-		luax_newtype(L, "Rasterizer", FONT_RASTERIZER_T, t);
-		return 1;
-	}
-
-	int w_newGlyphData(lua_State * L)
-	{
-		Rasterizer * r = luax_checkrasterizer(L, 1);
-		unsigned short g = (unsigned short)luaL_checkint(L, 2);
-
-		GlyphData * t = instance->newGlyphData(r, g);
-		luax_newtype(L, "GlyphData", FONT_GLYPH_DATA_T, t);
-		return 1;
-	}
-
-	// List of functions to wrap.
-	static const luaL_Reg functions[] = {
-		{ "newRasterizer",  w_newRasterizer },
-		{ "newGlyphData",  w_newGlyphData },
-		{ 0, 0 }
-	};
-
-	static const lua_CFunction types[] = {
-		luaopen_glyphdata,
-		luaopen_rasterizer,
-		0
-	};
-
-	extern "C" int luaopen_love_font(lua_State * L)
-	{
-		if (instance == 0)
-		{
-			try
-			{
-				instance = new Font();
-			}
-			catch (Exception & e)
-			{
-				return luaL_error(L, e.what());
-			}
-		}
-		else
-			instance->retain();
-
-		WrappedModule w;
-		w.module = instance;
-		w.name = "font";
-		w.flags = MODULE_T;
-		w.functions = functions;
-		w.types = types;
-
-		return luax_register_module(L, w);
-	}
-
-} // freetype
-} // font
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "wrap_Font.h"
+
+#include "Font.h"
+
+#include "font/wrap_GlyphData.h"
+#include "font/wrap_Rasterizer.h"
+
+#include "TrueTypeRasterizer.h"
+
+namespace love
+{
+namespace font
+{
+namespace freetype
+{
+
+static Font *instance = 0;
+
+int w_newRasterizer(lua_State *L)
+{
+	Rasterizer *t = NULL;
+	if (luax_istype(L, 1, IMAGE_IMAGE_DATA_T))
+	{
+		love::image::ImageData *d = luax_checktype<love::image::ImageData>(L, 1, "ImageData", IMAGE_IMAGE_DATA_T);
+		const char *g = luaL_checkstring(L, 2);
+		std::string glyphs(g);
+		t = instance->newRasterizer(d, glyphs);
+	}
+	else if (luax_istype(L, 1, DATA_T))
+	{
+		Data *d = luax_checkdata(L, 1);
+		int size = luaL_checkint(L, 2);
+		t = instance->newRasterizer(d, size);
+	}
+
+	luax_newtype(L, "Rasterizer", FONT_RASTERIZER_T, t);
+	return 1;
+}
+
+int w_newGlyphData(lua_State *L)
+{
+	Rasterizer *r = luax_checkrasterizer(L, 1);
+	unsigned short g = (unsigned short)luaL_checkint(L, 2);
+
+	GlyphData *t = instance->newGlyphData(r, g);
+	luax_newtype(L, "GlyphData", FONT_GLYPH_DATA_T, t);
+	return 1;
+}
+
+// List of functions to wrap.
+static const luaL_Reg functions[] =
+{
+	{ "newRasterizer",  w_newRasterizer },
+	{ "newGlyphData",  w_newGlyphData },
+	{ 0, 0 }
+};
+
+static const lua_CFunction types[] =
+{
+	luaopen_glyphdata,
+	luaopen_rasterizer,
+	0
+};
+
+extern "C" int luaopen_love_font(lua_State *L)
+{
+	if (instance == 0)
+	{
+		try
+		{
+			instance = new Font();
+		}
+		catch(Exception &e)
+		{
+			return luaL_error(L, e.what());
+		}
+	}
+	else
+		instance->retain();
+
+	WrappedModule w;
+	w.module = instance;
+	w.name = "font";
+	w.flags = MODULE_T;
+	w.functions = functions;
+	w.types = types;
+
+	return luax_register_module(L, w);
+}
+
+} // freetype
+} // font
+} // love

+ 43 - 42
src/modules/font/freetype/wrap_Font.h

@@ -1,42 +1,43 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_FONT_FREETYPE_WRAP_FONT_H
-#define LOVE_FONT_FREETYPE_WRAP_FONT_H
-
-// LOVE
-#include <common/config.h>
-#include <common/runtime.h>
-
-namespace love
-{
-namespace font
-{
-namespace freetype
-{
-	int w_newRasterizer(lua_State * L);
-	int w_newGlyphData(lua_State * L);
-	extern "C" LOVE_EXPORT int luaopen_love_font(lua_State * L);
-
-} // freetype
-} // font
-} // love
-
-#endif // LOVE_FONT_FREETYPE_WRAP_FONT_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_FONT_FREETYPE_WRAP_FONT_H
+#define LOVE_FONT_FREETYPE_WRAP_FONT_H
+
+// LOVE
+#include "common/config.h"
+#include "common/runtime.h"
+
+namespace love
+{
+namespace font
+{
+namespace freetype
+{
+
+int w_newRasterizer(lua_State *L);
+int w_newGlyphData(lua_State *L);
+extern "C" LOVE_EXPORT int luaopen_love_font(lua_State *L);
+
+} // freetype
+} // font
+} // love
+
+#endif // LOVE_FONT_FREETYPE_WRAP_FONT_H

+ 46 - 44
src/modules/font/wrap_GlyphData.cpp

@@ -1,44 +1,46 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "wrap_GlyphData.h"
-
-namespace love
-{
-namespace font
-{
-	GlyphData * luax_checkglyphdata(lua_State * L, int idx)
-	{
-		return luax_checktype<GlyphData>(L, idx, "GlyphData", FONT_GLYPH_DATA_T);
-	}
-
-	static const luaL_Reg functions[] = {
-		{ "getPointer", w_Data_getPointer },
-		{ "getSize", w_Data_getSize },
-		{ 0, 0 }
-	};
-
-	extern "C" int luaopen_glyphdata(lua_State * L)
-	{
-		return luax_register_type(L, "GlyphData", functions);
-	}
-
-} // font
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "wrap_GlyphData.h"
+
+namespace love
+{
+namespace font
+{
+
+GlyphData *luax_checkglyphdata(lua_State *L, int idx)
+{
+	return luax_checktype<GlyphData>(L, idx, "GlyphData", FONT_GLYPH_DATA_T);
+}
+
+static const luaL_Reg functions[] =
+{
+	{ "getPointer", w_Data_getPointer },
+	{ "getSize", w_Data_getSize },
+	{ 0, 0 }
+};
+
+extern "C" int luaopen_glyphdata(lua_State *L)
+{
+	return luax_register_type(L, "GlyphData", functions);
+}
+
+} // font
+} // love

+ 41 - 40
src/modules/font/wrap_GlyphData.h

@@ -1,40 +1,41 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_FONT_WRAP_GLYPH_DATA_H
-#define LOVE_FONT_WRAP_GLYPH_DATA_H
-
-// LOVE
-#include <common/runtime.h>
-#include <common/wrap_Data.h>
-
-#include "GlyphData.h"
-
-namespace love
-{
-namespace font
-{
-	GlyphData * luax_checkglyphdata(lua_State * L, int idx);
-	extern "C" int luaopen_glyphdata(lua_State * L);
-
-} // font
-} // love
-
-#endif // LOVE_FONT_WRAP_GLYPH_DATA_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_FONT_WRAP_GLYPH_DATA_H
+#define LOVE_FONT_WRAP_GLYPH_DATA_H
+
+// LOVE
+#include "common/runtime.h"
+#include "common/wrap_Data.h"
+
+#include "GlyphData.h"
+
+namespace love
+{
+namespace font
+{
+
+GlyphData *luax_checkglyphdata(lua_State *L, int idx);
+extern "C" int luaopen_glyphdata(lua_State *L);
+
+} // font
+} // love
+
+#endif // LOVE_FONT_WRAP_GLYPH_DATA_H

+ 46 - 44
src/modules/font/wrap_Rasterizer.cpp

@@ -1,44 +1,46 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "wrap_Rasterizer.h"
-
-#include <common/wrap_Data.h>
-
-namespace love
-{
-namespace font
-{
-	Rasterizer * luax_checkrasterizer(lua_State * L, int idx)
-	{
-		return luax_checktype<Rasterizer>(L, idx, "Rasterizer", FONT_RASTERIZER_T);
-	}
-
-	static const luaL_Reg functions[] = {
-		{ 0, 0 }
-	};
-
-	extern "C" int luaopen_rasterizer(lua_State * L)
-	{
-		return luax_register_type(L, "Rasterizer", functions);
-	}
-
-} // font
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "wrap_Rasterizer.h"
+
+#include "common/wrap_Data.h"
+
+namespace love
+{
+namespace font
+{
+
+Rasterizer *luax_checkrasterizer(lua_State *L, int idx)
+{
+	return luax_checktype<Rasterizer>(L, idx, "Rasterizer", FONT_RASTERIZER_T);
+}
+
+static const luaL_Reg functions[] =
+{
+	{ 0, 0 }
+};
+
+extern "C" int luaopen_rasterizer(lua_State *L)
+{
+	return luax_register_type(L, "Rasterizer", functions);
+}
+
+} // font
+} // love

+ 39 - 38
src/modules/font/wrap_Rasterizer.h

@@ -1,38 +1,39 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_FONT_WRAP_RASTERIZER_H
-#define LOVE_FONT_WRAP_RASTERIZER_H
-
-// LOVE
-#include <common/runtime.h>
-#include "Rasterizer.h"
-
-namespace love
-{
-namespace font
-{
-	Rasterizer * luax_checkrasterizer(lua_State * L, int idx);
-	extern "C" int luaopen_rasterizer(lua_State * L);
-
-} // font
-} // love
-
-#endif // LOVE_FONT_WRAP_RASTERIZER_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_FONT_WRAP_RASTERIZER_H
+#define LOVE_FONT_WRAP_RASTERIZER_H
+
+// LOVE
+#include "common/runtime.h"
+#include "Rasterizer.h"
+
+namespace love
+{
+namespace font
+{
+
+Rasterizer *luax_checkrasterizer(lua_State *L, int idx);
+extern "C" int luaopen_rasterizer(lua_State *L);
+
+} // font
+} // love
+
+#endif // LOVE_FONT_WRAP_RASTERIZER_H

+ 109 - 103
src/modules/graphics/Color.h

@@ -1,103 +1,109 @@
-/**
- * Copyright (c) 2006-2011 LOVE Development Team
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- **/
-
-#ifndef LOVE_GRAPHICS_COLOR_H
-#define LOVE_GRAPHICS_COLOR_H
-
-namespace love
-{
-namespace graphics
-{
-
-	template <typename T>
-	struct ColorT
-	{
-		T r;
-		T g;
-		T b;
-		T a;
-
-		ColorT() : r(0), g(0), b(0), a(0) {}
-		ColorT(T r_, T g_, T b_, T a_) : r(r_), g(g_), b(b_), a(a_) {}
-		void set(T r_, T g_, T b_, T a_) { r = r_; g = g_; b = b_; a = a_; }
-
-		ColorT<T> operator+=(const ColorT<T>& other);
-		ColorT<T> operator*=(T s);
-		ColorT<T> operator/=(T s);
-	};
-
-	template <typename T>
-	ColorT<T> ColorT<T>::operator+=(const ColorT<T>& other)
-	{
-		r += other.r;
-		g += other.g;
-		b += other.b;
-		a += other.a;
-		return *this;
-	}
-
-	template <typename T>
-	ColorT<T> ColorT<T>::operator*=(T s)
-	{
-		r *= s;
-		g *= s;
-		b *= s;
-		a *= s;
-		return *this;
-	}
-
-	template <typename T>
-	ColorT<T> ColorT<T>::operator/=(T s)
-	{
-		r /= s;
-		g /= s;
-		b /= s;
-		a /= s;
-		return *this;
-	}
-
-	template <typename T>
-	ColorT<T> operator+(const ColorT<T>& a, const ColorT<T>& b)
-	{
-		ColorT<T> tmp(a);
-		return tmp += b;
-	}
-
-	template <typename T>
-	ColorT<T> operator*(const ColorT<T>& a, T s)
-	{
-		ColorT<T> tmp(a);
-		return tmp *= s;
-	}
-
-	template <typename T>
-	ColorT<T> operator/(const ColorT<T>& a, T s)
-	{
-		ColorT<T> tmp(a);
-		return tmp /= s;
-	}
-
-	typedef ColorT<unsigned char> Color;
-	typedef ColorT<float> Colorf;
-
-} // graphics
-} // love
-
-#endif // LOVE_GRAPHICS_COLOR_H
+/**
+ * Copyright (c) 2006-2011 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_GRAPHICS_COLOR_H
+#define LOVE_GRAPHICS_COLOR_H
+
+namespace love
+{
+namespace graphics
+{
+
+template <typename T>
+struct ColorT
+{
+	T r;
+	T g;
+	T b;
+	T a;
+
+	ColorT() : r(0), g(0), b(0), a(0) {}
+	ColorT(T r_, T g_, T b_, T a_) : r(r_), g(g_), b(b_), a(a_) {}
+	void set(T r_, T g_, T b_, T a_)
+	{
+		r = r_;
+		g = g_;
+		b = b_;
+		a = a_;
+	}
+
+	ColorT<T> operator+=(const ColorT<T> &other);
+	ColorT<T> operator*=(T s);
+	ColorT<T> operator/=(T s);
+};
+
+template <typename T>
+ColorT<T> ColorT<T>::operator+=(const ColorT<T> &other)
+{
+	r += other.r;
+	g += other.g;
+	b += other.b;
+	a += other.a;
+	return *this;
+}
+
+template <typename T>
+ColorT<T> ColorT<T>::operator*=(T s)
+{
+	r *= s;
+	g *= s;
+	b *= s;
+	a *= s;
+	return *this;
+}
+
+template <typename T>
+ColorT<T> ColorT<T>::operator/=(T s)
+{
+	r /= s;
+	g /= s;
+	b /= s;
+	a /= s;
+	return *this;
+}
+
+template <typename T>
+ColorT<T> operator+(const ColorT<T> &a, const ColorT<T> &b)
+{
+	ColorT<T> tmp(a);
+	return tmp += b;
+}
+
+template <typename T>
+ColorT<T> operator*(const ColorT<T> &a, T s)
+{
+	ColorT<T> tmp(a);
+	return tmp *= s;
+}
+
+template <typename T>
+ColorT<T> operator/(const ColorT<T> &a, T s)
+{
+	ColorT<T> tmp(a);
+	return tmp /= s;
+}
+
+typedef ColorT<unsigned char> Color;
+typedef ColorT<float> Colorf;
+
+} // graphics
+} // love
+
+#endif // LOVE_GRAPHICS_COLOR_H

+ 33 - 33
src/modules/graphics/DrawQable.cpp

@@ -1,33 +1,33 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "DrawQable.h"
-
-namespace love
-{
-namespace graphics
-{
-
-	DrawQable::~DrawQable()
-	{
-	}
-
-} // graphics
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "DrawQable.h"
+
+namespace love
+{
+namespace graphics
+{
+
+DrawQable::~DrawQable()
+{
+}
+
+} // graphics
+} // love

+ 65 - 64
src/modules/graphics/DrawQable.h

@@ -1,64 +1,65 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_GRAPHICS_DRAWQABLE_H
-#define LOVE_GRAPHICS_DRAWQABLE_H
-
-// LOVE
-#include "Drawable.h"
-#include "Quad.h"
-
-namespace love
-{
-namespace graphics
-{
-	/**
-	* A DrawQable is anything that be drawn in part with a Quad.
-	**/
-	class DrawQable : public Drawable
-	{
-	public:
-
-		/**
-		* Destructor.
-		**/
-		virtual ~DrawQable();
-
-		/**
-		* Draws the object with the specified transformation.
-		*
-		* @param quad The Quad to use to draw the object.
-		* @param x The position of the object along the x-axis.
-		* @param y The position of the object along the y-axis.
-		* @param angle The angle of the object (in radians).
-		* @param sx The scale factor along the x-axis.
-		* @param sy The scale factor along the y-axis.
-		* @param ox The origin offset along the x-axis.
-		* @param oy The origin offset along the y-axis.
-		* @param kx Shear along the x-axis.
-		* @param ky Shear along the y-axis.
-		**/
-		virtual void drawq(Quad * quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const = 0;
-	};
-
-} // graphics
-} // love
-
-#endif // LOVE_GRAPHICS_DRAWQABLE_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_GRAPHICS_DRAWQABLE_H
+#define LOVE_GRAPHICS_DRAWQABLE_H
+
+// LOVE
+#include "Drawable.h"
+#include "Quad.h"
+
+namespace love
+{
+namespace graphics
+{
+
+/**
+ * A DrawQable is anything that be drawn in part with a Quad.
+ **/
+class DrawQable : public Drawable
+{
+public:
+
+	/**
+	 * Destructor.
+	 **/
+	virtual ~DrawQable();
+
+	/**
+	 * Draws the object with the specified transformation.
+	 *
+	 * @param quad The Quad to use to draw the object.
+	 * @param x The position of the object along the x-axis.
+	 * @param y The position of the object along the y-axis.
+	 * @param angle The angle of the object (in radians).
+	 * @param sx The scale factor along the x-axis.
+	 * @param sy The scale factor along the y-axis.
+	 * @param ox The origin offset along the x-axis.
+	 * @param oy The origin offset along the y-axis.
+	 * @param kx Shear along the x-axis.
+	 * @param ky Shear along the y-axis.
+	 **/
+	virtual void drawq(Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const = 0;
+};
+
+} // graphics
+} // love
+
+#endif // LOVE_GRAPHICS_DRAWQABLE_H

+ 33 - 33
src/modules/graphics/Drawable.cpp

@@ -1,33 +1,33 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "Drawable.h"
-
-namespace love
-{
-namespace graphics
-{
-
-	Drawable::~Drawable()
-	{
-	}
-
-} // graphics
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "Drawable.h"
+
+namespace love
+{
+namespace graphics
+{
+
+Drawable::~Drawable()
+{
+}
+
+} // graphics
+} // love

+ 64 - 63
src/modules/graphics/Drawable.h

@@ -1,63 +1,64 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_GRAPHICS_DRAWABLE_H
-#define LOVE_GRAPHICS_DRAWABLE_H
-
-// LOVE
-#include <common/Object.h>
-
-namespace love
-{
-namespace graphics
-{
-	/**
-	* A Drawable is anything that can be drawn on screen with a
-	* position, scale and orientation.
-	**/
-	class Drawable : public Object
-	{
-	public:
-
-		/**
-		* Destructor.
-		**/
-		virtual ~Drawable();
-
-		/**
-		* Draws the object with the specified transformation.
-		*
-		* @param x The position of the object along the x-axis.
-		* @param y The position of the object along the y-axis.
-		* @param angle The angle of the object (in radians).
-		* @param sx The scale factor along the x-axis.
-		* @param sy The scale factor along the y-axis.
-		* @param ox The origin offset along the x-axis.
-		* @param oy The origin offset along the y-axis.
-		* @param kx Shear along the x-axis.
-		* @param ky Shear along the y-axis.
-		**/
-		virtual void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const = 0;
-	};
-
-} // graphics
-} // love
-
-#endif // LOVE_GRAPHICS_DRAWABLE_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_GRAPHICS_DRAWABLE_H
+#define LOVE_GRAPHICS_DRAWABLE_H
+
+// LOVE
+#include "common/Object.h"
+
+namespace love
+{
+namespace graphics
+{
+
+/**
+ * A Drawable is anything that can be drawn on screen with a
+ * position, scale and orientation.
+ **/
+class Drawable : public Object
+{
+public:
+
+	/**
+	 * Destructor.
+	 **/
+	virtual ~Drawable();
+
+	/**
+	 * Draws the object with the specified transformation.
+	 *
+	 * @param x The position of the object along the x-axis.
+	 * @param y The position of the object along the y-axis.
+	 * @param angle The angle of the object (in radians).
+	 * @param sx The scale factor along the x-axis.
+	 * @param sy The scale factor along the y-axis.
+	 * @param ox The origin offset along the x-axis.
+	 * @param oy The origin offset along the y-axis.
+	 * @param kx Shear along the x-axis.
+	 * @param ky Shear along the y-axis.
+	 **/
+	virtual void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const = 0;
+};
+
+} // graphics
+} // love
+
+#endif // LOVE_GRAPHICS_DRAWABLE_H

+ 166 - 165
src/modules/graphics/Graphics.cpp

@@ -1,165 +1,166 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "Graphics.h"
-
-namespace love
-{
-namespace graphics
-{
-	Graphics::~Graphics()
-	{
-	}
-
-	bool Graphics::getConstant(const char * in, DrawMode & out)
-	{
-		return drawModes.find(in, out);
-	}
-
-	bool Graphics::getConstant(DrawMode in, const char *& out)
-	{
-		return drawModes.find(in, out);
-	}
-
-	bool Graphics::getConstant(const char * in, AlignMode & out)
-	{
-		return alignModes.find(in, out);
-	}
-
-	bool Graphics::getConstant(AlignMode in, const char *& out)
-	{
-		return alignModes.find(in, out);
-	}
-
-	bool Graphics::getConstant(const char * in, BlendMode & out)
-	{
-		return blendModes.find(in, out);
-	}
-
-	bool Graphics::getConstant(BlendMode in, const char *& out)
-	{
-		return blendModes.find(in, out);
-	}
-
-	bool Graphics::getConstant(const char * in, ColorMode & out)
-	{
-		return colorModes.find(in, out);
-	}
-
-	bool Graphics::getConstant(ColorMode in, const char *& out)
-	{
-		return colorModes.find(in, out);
-	}
-
-	bool Graphics::getConstant(const char * in, LineStyle & out)
-	{
-		return lineStyles.find(in, out);
-	}
-
-	bool Graphics::getConstant(LineStyle in, const char *& out)
-	{
-		return lineStyles.find(in, out);
-	}
-
-	bool Graphics::getConstant(const char * in, PointStyle & out)
-	{
-		return pointStyles.find(in, out);
-	}
-
-	bool Graphics::getConstant(PointStyle in, const char *& out)
-	{
-		return pointStyles.find(in, out);
-	}
-
-	bool Graphics::getConstant(const char * in, Support & out)
-	{
-		return support.find(in, out);
-	}
-
-	bool Graphics::getConstant(Support in, const char *& out)
-	{
-		return support.find(in, out);
-	}
-
-	StringMap<Graphics::DrawMode, Graphics::DRAW_MAX_ENUM>::Entry Graphics::drawModeEntries[] =
-	{
-		{ "line", Graphics::DRAW_LINE },
-		{ "fill", Graphics::DRAW_FILL },
-	};
-
-	StringMap<Graphics::DrawMode, Graphics::DRAW_MAX_ENUM> Graphics::drawModes(Graphics::drawModeEntries, sizeof(Graphics::drawModeEntries));
-
-	StringMap<Graphics::AlignMode, Graphics::ALIGN_MAX_ENUM>::Entry Graphics::alignModeEntries[] =
-	{
-		{ "left", Graphics::ALIGN_LEFT },
-		{ "right", Graphics::ALIGN_RIGHT },
-		{ "center", Graphics::ALIGN_CENTER },
-	};
-
-	StringMap<Graphics::AlignMode, Graphics::ALIGN_MAX_ENUM> Graphics::alignModes(Graphics::alignModeEntries, sizeof(Graphics::alignModeEntries));
-
-	StringMap<Graphics::BlendMode, Graphics::BLEND_MAX_ENUM>::Entry Graphics::blendModeEntries[] =
-	{
-		{ "alpha", Graphics::BLEND_ALPHA },
-		{ "additive", Graphics::BLEND_ADDITIVE },
-		{ "subtractive", Graphics::BLEND_SUBTRACTIVE },
-		{ "multiplicative", Graphics::BLEND_MULTIPLICATIVE },
-		{ "premultiplied", Graphics::BLEND_PREMULTIPLIED },
-	};
-
-	StringMap<Graphics::BlendMode, Graphics::BLEND_MAX_ENUM> Graphics::blendModes(Graphics::blendModeEntries, sizeof(Graphics::blendModeEntries));
-
-	StringMap<Graphics::ColorMode, Graphics::COLOR_MAX_ENUM>::Entry Graphics::colorModeEntries[] =
-	{
-		{ "replace", Graphics::COLOR_REPLACE },
-		{ "modulate", Graphics::COLOR_MODULATE },
-		{ "combine", Graphics::COLOR_COMBINE },
-	};
-
-	StringMap<Graphics::ColorMode, Graphics::COLOR_MAX_ENUM> Graphics::colorModes(Graphics::colorModeEntries, sizeof(Graphics::colorModeEntries));
-
-	StringMap<Graphics::LineStyle, Graphics::LINE_MAX_ENUM>::Entry Graphics::lineStyleEntries[] =
-	{
-		{ "smooth", Graphics::LINE_SMOOTH },
-		{ "rough", Graphics::LINE_ROUGH }
-	};
-
-	StringMap<Graphics::LineStyle, Graphics::LINE_MAX_ENUM> Graphics::lineStyles(Graphics::lineStyleEntries, sizeof(Graphics::lineStyleEntries));
-
-	StringMap<Graphics::PointStyle, Graphics::POINT_MAX_ENUM>::Entry Graphics::pointStyleEntries[] =
-	{
-		{ "smooth", Graphics::POINT_SMOOTH },
-		{ "rough", Graphics::POINT_ROUGH }
-	};
-
-	StringMap<Graphics::PointStyle, Graphics::POINT_MAX_ENUM> Graphics::pointStyles(Graphics::pointStyleEntries, sizeof(Graphics::pointStyleEntries));
-
-	StringMap<Graphics::Support, Graphics::SUPPORT_MAX_ENUM>::Entry Graphics::supportEntries[] =
-	{
-		{ "canvas", Graphics::SUPPORT_CANVAS },
-		{ "pixeleffect", Graphics::SUPPORT_PIXELEFFECT },
-		{ "npot", Graphics::SUPPORT_NPOT },
-		{ "subtractive", Graphics::SUPPORT_SUBTRACTIVE },
-	};
-
-	StringMap<Graphics::Support, Graphics::SUPPORT_MAX_ENUM> Graphics::support(Graphics::supportEntries, sizeof(Graphics::supportEntries));
-
-} // graphics
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "Graphics.h"
+
+namespace love
+{
+namespace graphics
+{
+
+Graphics::~Graphics()
+{
+}
+
+bool Graphics::getConstant(const char *in, DrawMode &out)
+{
+	return drawModes.find(in, out);
+}
+
+bool Graphics::getConstant(DrawMode in, const char  *&out)
+{
+	return drawModes.find(in, out);
+}
+
+bool Graphics::getConstant(const char *in, AlignMode &out)
+{
+	return alignModes.find(in, out);
+}
+
+bool Graphics::getConstant(AlignMode in, const char  *&out)
+{
+	return alignModes.find(in, out);
+}
+
+bool Graphics::getConstant(const char *in, BlendMode &out)
+{
+	return blendModes.find(in, out);
+}
+
+bool Graphics::getConstant(BlendMode in, const char  *&out)
+{
+	return blendModes.find(in, out);
+}
+
+bool Graphics::getConstant(const char *in, ColorMode &out)
+{
+	return colorModes.find(in, out);
+}
+
+bool Graphics::getConstant(ColorMode in, const char  *&out)
+{
+	return colorModes.find(in, out);
+}
+
+bool Graphics::getConstant(const char *in, LineStyle &out)
+{
+	return lineStyles.find(in, out);
+}
+
+bool Graphics::getConstant(LineStyle in, const char  *&out)
+{
+	return lineStyles.find(in, out);
+}
+
+bool Graphics::getConstant(const char *in, PointStyle &out)
+{
+	return pointStyles.find(in, out);
+}
+
+bool Graphics::getConstant(PointStyle in, const char  *&out)
+{
+	return pointStyles.find(in, out);
+}
+
+bool Graphics::getConstant(const char *in, Support &out)
+{
+	return support.find(in, out);
+}
+
+bool Graphics::getConstant(Support in, const char  *&out)
+{
+	return support.find(in, out);
+}
+
+StringMap<Graphics::DrawMode, Graphics::DRAW_MAX_ENUM>::Entry Graphics::drawModeEntries[] =
+{
+	{ "line", Graphics::DRAW_LINE },
+	{ "fill", Graphics::DRAW_FILL },
+};
+
+StringMap<Graphics::DrawMode, Graphics::DRAW_MAX_ENUM> Graphics::drawModes(Graphics::drawModeEntries, sizeof(Graphics::drawModeEntries));
+
+StringMap<Graphics::AlignMode, Graphics::ALIGN_MAX_ENUM>::Entry Graphics::alignModeEntries[] =
+{
+	{ "left", Graphics::ALIGN_LEFT },
+	{ "right", Graphics::ALIGN_RIGHT },
+	{ "center", Graphics::ALIGN_CENTER },
+};
+
+StringMap<Graphics::AlignMode, Graphics::ALIGN_MAX_ENUM> Graphics::alignModes(Graphics::alignModeEntries, sizeof(Graphics::alignModeEntries));
+
+StringMap<Graphics::BlendMode, Graphics::BLEND_MAX_ENUM>::Entry Graphics::blendModeEntries[] =
+{
+	{ "alpha", Graphics::BLEND_ALPHA },
+	{ "additive", Graphics::BLEND_ADDITIVE },
+	{ "subtractive", Graphics::BLEND_SUBTRACTIVE },
+	{ "multiplicative", Graphics::BLEND_MULTIPLICATIVE },
+	{ "premultiplied", Graphics::BLEND_PREMULTIPLIED },
+};
+
+StringMap<Graphics::BlendMode, Graphics::BLEND_MAX_ENUM> Graphics::blendModes(Graphics::blendModeEntries, sizeof(Graphics::blendModeEntries));
+
+StringMap<Graphics::ColorMode, Graphics::COLOR_MAX_ENUM>::Entry Graphics::colorModeEntries[] =
+{
+	{ "replace", Graphics::COLOR_REPLACE },
+	{ "modulate", Graphics::COLOR_MODULATE },
+	{ "combine", Graphics::COLOR_COMBINE },
+};
+
+StringMap<Graphics::ColorMode, Graphics::COLOR_MAX_ENUM> Graphics::colorModes(Graphics::colorModeEntries, sizeof(Graphics::colorModeEntries));
+
+StringMap<Graphics::LineStyle, Graphics::LINE_MAX_ENUM>::Entry Graphics::lineStyleEntries[] =
+{
+	{ "smooth", Graphics::LINE_SMOOTH },
+	{ "rough", Graphics::LINE_ROUGH }
+};
+
+StringMap<Graphics::LineStyle, Graphics::LINE_MAX_ENUM> Graphics::lineStyles(Graphics::lineStyleEntries, sizeof(Graphics::lineStyleEntries));
+
+StringMap<Graphics::PointStyle, Graphics::POINT_MAX_ENUM>::Entry Graphics::pointStyleEntries[] =
+{
+	{ "smooth", Graphics::POINT_SMOOTH },
+	{ "rough", Graphics::POINT_ROUGH }
+};
+
+StringMap<Graphics::PointStyle, Graphics::POINT_MAX_ENUM> Graphics::pointStyles(Graphics::pointStyleEntries, sizeof(Graphics::pointStyleEntries));
+
+StringMap<Graphics::Support, Graphics::SUPPORT_MAX_ENUM>::Entry Graphics::supportEntries[] =
+{
+	{ "canvas", Graphics::SUPPORT_CANVAS },
+	{ "pixeleffect", Graphics::SUPPORT_PIXELEFFECT },
+	{ "npot", Graphics::SUPPORT_NPOT },
+	{ "subtractive", Graphics::SUPPORT_SUBTRACTIVE },
+};
+
+StringMap<Graphics::Support, Graphics::SUPPORT_MAX_ENUM> Graphics::support(Graphics::supportEntries, sizeof(Graphics::supportEntries));
+
+} // graphics
+} // love

+ 144 - 143
src/modules/graphics/Graphics.h

@@ -1,143 +1,144 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_GRAPHICS_GRAPHICS_H
-#define LOVE_GRAPHICS_GRAPHICS_H
-
-// LOVE
-#include <common/Module.h>
-#include <common/StringMap.h>
-
-namespace love
-{
-namespace graphics
-{
-	class Graphics : public Module
-	{
-	public:
-
-		enum DrawMode
-		{
-			DRAW_LINE = 1,
-			DRAW_FILL,
-			DRAW_MAX_ENUM
-		};
-
-		enum AlignMode
-		{
-			ALIGN_LEFT = 1,
-			ALIGN_CENTER,
-			ALIGN_RIGHT,
-			ALIGN_MAX_ENUM
-		};
-
-		enum BlendMode
-		{
-			BLEND_ALPHA = 1,
-			BLEND_ADDITIVE,
-			BLEND_SUBTRACTIVE,
-			BLEND_MULTIPLICATIVE,
-			BLEND_PREMULTIPLIED,
-			BLEND_MAX_ENUM
-		};
-
-		enum ColorMode
-		{
-			COLOR_MODULATE = 1,
-			COLOR_REPLACE,
-			COLOR_COMBINE,
-			COLOR_MAX_ENUM
-		};
-
-		enum LineStyle
-		{
-			LINE_ROUGH = 1,
-			LINE_SMOOTH,
-			LINE_MAX_ENUM
-		};
-
-		enum PointStyle
-		{
-			POINT_ROUGH = 1,
-			POINT_SMOOTH,
-			POINT_MAX_ENUM
-		};
-
-		enum Support
-		{
-			SUPPORT_CANVAS = 1,
-			SUPPORT_PIXELEFFECT,
-			SUPPORT_NPOT,
-			SUPPORT_SUBTRACTIVE,
-			SUPPORT_MAX_ENUM
-		};
-
-		virtual ~Graphics();
-
-		static bool getConstant(const char * in, DrawMode & out);
-		static bool getConstant(DrawMode in, const char *& out);
-
-		static bool getConstant(const char * in, AlignMode & out);
-		static bool getConstant(AlignMode in, const char *& out);
-
-		static bool getConstant(const char * in, BlendMode & out);
-		static bool getConstant(BlendMode in, const char *& out);
-
-		static bool getConstant(const char * in, ColorMode & out);
-		static bool getConstant(ColorMode in, const char *& out);
-
-		static bool getConstant(const char * in, LineStyle & out);
-		static bool getConstant(LineStyle in, const char *& out);
-
-		static bool getConstant(const char * in, PointStyle & out);
-		static bool getConstant(PointStyle in, const char *& out);
-
-		static bool getConstant(const char * in, Support & out);
-		static bool getConstant(Support in, const char *& out);
-
-	private:
-
-		static StringMap<DrawMode, DRAW_MAX_ENUM>::Entry drawModeEntries[];
-		static StringMap<DrawMode, DRAW_MAX_ENUM> drawModes;
-
-		static StringMap<AlignMode, ALIGN_MAX_ENUM>::Entry alignModeEntries[];
-		static StringMap<AlignMode, ALIGN_MAX_ENUM> alignModes;
-
-		static StringMap<BlendMode, BLEND_MAX_ENUM>::Entry blendModeEntries[];
-		static StringMap<BlendMode, BLEND_MAX_ENUM> blendModes;
-
-		static StringMap<ColorMode, COLOR_MAX_ENUM>::Entry colorModeEntries[];
-		static StringMap<ColorMode, COLOR_MAX_ENUM> colorModes;
-
-		static StringMap<LineStyle, LINE_MAX_ENUM>::Entry lineStyleEntries[];
-		static StringMap<LineStyle, LINE_MAX_ENUM> lineStyles;
-
-		static StringMap<PointStyle, POINT_MAX_ENUM>::Entry pointStyleEntries[];
-		static StringMap<PointStyle, POINT_MAX_ENUM> pointStyles;
-
-		static StringMap<Support, SUPPORT_MAX_ENUM>::Entry supportEntries[];
-		static StringMap<Support, SUPPORT_MAX_ENUM> support;
-
-	}; // Graphics
-
-} // graphics
-} // love
-
-#endif // LOVE_GRAPHICS_GRAPHICS_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_GRAPHICS_GRAPHICS_H
+#define LOVE_GRAPHICS_GRAPHICS_H
+
+// LOVE
+#include "common/Module.h"
+#include "common/StringMap.h"
+
+namespace love
+{
+namespace graphics
+{
+
+class Graphics : public Module
+{
+public:
+
+	enum DrawMode
+	{
+		DRAW_LINE = 1,
+		DRAW_FILL,
+		DRAW_MAX_ENUM
+	};
+
+	enum AlignMode
+	{
+		ALIGN_LEFT = 1,
+		ALIGN_CENTER,
+		ALIGN_RIGHT,
+		ALIGN_MAX_ENUM
+	};
+
+	enum BlendMode
+	{
+		BLEND_ALPHA = 1,
+		BLEND_ADDITIVE,
+		BLEND_SUBTRACTIVE,
+		BLEND_MULTIPLICATIVE,
+		BLEND_PREMULTIPLIED,
+		BLEND_MAX_ENUM
+	};
+
+	enum ColorMode
+	{
+		COLOR_MODULATE = 1,
+		COLOR_REPLACE,
+		COLOR_COMBINE,
+		COLOR_MAX_ENUM
+	};
+
+	enum LineStyle
+	{
+		LINE_ROUGH = 1,
+		LINE_SMOOTH,
+		LINE_MAX_ENUM
+	};
+
+	enum PointStyle
+	{
+		POINT_ROUGH = 1,
+		POINT_SMOOTH,
+		POINT_MAX_ENUM
+	};
+
+	enum Support
+	{
+		SUPPORT_CANVAS = 1,
+		SUPPORT_PIXELEFFECT,
+		SUPPORT_NPOT,
+		SUPPORT_SUBTRACTIVE,
+		SUPPORT_MAX_ENUM
+	};
+
+	virtual ~Graphics();
+
+	static bool getConstant(const char *in, DrawMode &out);
+	static bool getConstant(DrawMode in, const char  *&out);
+
+	static bool getConstant(const char *in, AlignMode &out);
+	static bool getConstant(AlignMode in, const char  *&out);
+
+	static bool getConstant(const char *in, BlendMode &out);
+	static bool getConstant(BlendMode in, const char  *&out);
+
+	static bool getConstant(const char *in, ColorMode &out);
+	static bool getConstant(ColorMode in, const char  *&out);
+
+	static bool getConstant(const char *in, LineStyle &out);
+	static bool getConstant(LineStyle in, const char  *&out);
+
+	static bool getConstant(const char *in, PointStyle &out);
+	static bool getConstant(PointStyle in, const char  *&out);
+
+	static bool getConstant(const char *in, Support &out);
+	static bool getConstant(Support in, const char  *&out);
+
+private:
+
+	static StringMap<DrawMode, DRAW_MAX_ENUM>::Entry drawModeEntries[];
+	static StringMap<DrawMode, DRAW_MAX_ENUM> drawModes;
+
+	static StringMap<AlignMode, ALIGN_MAX_ENUM>::Entry alignModeEntries[];
+	static StringMap<AlignMode, ALIGN_MAX_ENUM> alignModes;
+
+	static StringMap<BlendMode, BLEND_MAX_ENUM>::Entry blendModeEntries[];
+	static StringMap<BlendMode, BLEND_MAX_ENUM> blendModes;
+
+	static StringMap<ColorMode, COLOR_MAX_ENUM>::Entry colorModeEntries[];
+	static StringMap<ColorMode, COLOR_MAX_ENUM> colorModes;
+
+	static StringMap<LineStyle, LINE_MAX_ENUM>::Entry lineStyleEntries[];
+	static StringMap<LineStyle, LINE_MAX_ENUM> lineStyles;
+
+	static StringMap<PointStyle, POINT_MAX_ENUM>::Entry pointStyleEntries[];
+	static StringMap<PointStyle, POINT_MAX_ENUM> pointStyles;
+
+	static StringMap<Support, SUPPORT_MAX_ENUM>::Entry supportEntries[];
+	static StringMap<Support, SUPPORT_MAX_ENUM> support;
+
+}; // Graphics
+
+} // graphics
+} // love
+
+#endif // LOVE_GRAPHICS_GRAPHICS_H

+ 82 - 77
src/modules/graphics/Image.cpp

@@ -1,77 +1,82 @@
-/**
- * Copyright (c) 2006-2012 LOVE Development Team
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- **/
-
-#include "Image.h"
-
-namespace love
-{
-namespace graphics
-{
-	Image::Filter::Filter() : min(FILTER_LINEAR), mag(FILTER_LINEAR)
-	{
-	}
-
-	Image::Wrap::Wrap() : s(WRAP_CLAMP), t(WRAP_CLAMP)
-	{
-	}
-
-	Image::~Image()
-	{
-	}
-
-	bool Image::getConstant(const char * in, FilterMode & out)
-	{
-		return filterModes.find(in, out);
-	}
-
-	bool Image::getConstant(FilterMode in, const char *& out)
-	{
-		return filterModes.find(in, out);
-	}
-
-	bool Image::getConstant(const char * in, WrapMode & out)
-	{
-		return wrapModes.find(in, out);
-	}
-
-	bool Image::getConstant(WrapMode in, const char *& out)
-	{
-		return wrapModes.find(in, out);
-	}
-
-	StringMap<Image::FilterMode, Image::FILTER_MAX_ENUM>::Entry Image::filterModeEntries[] =
-	{
-		{ "linear", Image::FILTER_LINEAR },
-		{ "nearest", Image::FILTER_NEAREST },
-	};
-
-	StringMap<Image::FilterMode, Image::FILTER_MAX_ENUM> Image::filterModes(Image::filterModeEntries, sizeof(Image::filterModeEntries));
-
-	StringMap<Image::WrapMode, Image::WRAP_MAX_ENUM>::Entry Image::wrapModeEntries[] =
-	{
-		{ "clamp", Image::WRAP_CLAMP },
-		{ "repeat", Image::WRAP_REPEAT },
-	};
-
-	StringMap<Image::WrapMode, Image::WRAP_MAX_ENUM> Image::wrapModes(Image::wrapModeEntries, sizeof(Image::wrapModeEntries));
-
-
-} // graphics
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "Image.h"
+
+namespace love
+{
+namespace graphics
+{
+
+Image::Filter::Filter()
+	: min(FILTER_LINEAR)
+	, mag(FILTER_LINEAR)
+{
+}
+
+Image::Wrap::Wrap()
+	: s(WRAP_CLAMP)
+	, t(WRAP_CLAMP)
+{
+}
+
+Image::~Image()
+{
+}
+
+bool Image::getConstant(const char *in, FilterMode &out)
+{
+	return filterModes.find(in, out);
+}
+
+bool Image::getConstant(FilterMode in, const char  *&out)
+{
+	return filterModes.find(in, out);
+}
+
+bool Image::getConstant(const char *in, WrapMode &out)
+{
+	return wrapModes.find(in, out);
+}
+
+bool Image::getConstant(WrapMode in, const char  *&out)
+{
+	return wrapModes.find(in, out);
+}
+
+StringMap<Image::FilterMode, Image::FILTER_MAX_ENUM>::Entry Image::filterModeEntries[] =
+{
+	{ "linear", Image::FILTER_LINEAR },
+	{ "nearest", Image::FILTER_NEAREST },
+};
+
+StringMap<Image::FilterMode, Image::FILTER_MAX_ENUM> Image::filterModes(Image::filterModeEntries, sizeof(Image::filterModeEntries));
+
+StringMap<Image::WrapMode, Image::WRAP_MAX_ENUM>::Entry Image::wrapModeEntries[] =
+{
+	{ "clamp", Image::WRAP_CLAMP },
+	{ "repeat", Image::WRAP_REPEAT },
+};
+
+StringMap<Image::WrapMode, Image::WRAP_MAX_ENUM> Image::wrapModes(Image::wrapModeEntries, sizeof(Image::wrapModeEntries));
+
+
+} // graphics
+} // love

+ 85 - 85
src/modules/graphics/Image.h

@@ -1,85 +1,85 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_GRAPHICS_IMAGE_H
-#define LOVE_GRAPHICS_IMAGE_H
-
-// LOVE
-#include <graphics/Volatile.h>
-#include <graphics/DrawQable.h>
-#include <common/StringMap.h>
-
-namespace love
-{
-namespace graphics
-{
-
-	class Image : public DrawQable, public Volatile
-	{
-	public:
-
-		enum WrapMode
-		{
-			WRAP_CLAMP = 1,
-			WRAP_REPEAT,
-			WRAP_MAX_ENUM
-		};
-
-		enum FilterMode
-		{
-			FILTER_LINEAR = 1,
-			FILTER_NEAREST,
-			FILTER_MAX_ENUM
-		};
-
-		struct Filter
-		{
-			Filter();
-			FilterMode min;
-			FilterMode mag;
-		};
-
-		struct Wrap
-		{
-			Wrap();
-			WrapMode s;
-			WrapMode t;
-		};
-
-		virtual ~Image();
-
-		static bool getConstant(const char * in, FilterMode & out);
-		static bool getConstant(FilterMode in, const char *& out);
-		static bool getConstant(const char * in, WrapMode & out);
-		static bool getConstant(WrapMode in, const char *& out);
-
-	private:
-
-		static StringMap<FilterMode, FILTER_MAX_ENUM>::Entry filterModeEntries[];
-		static StringMap<FilterMode, FILTER_MAX_ENUM> filterModes;
-		static StringMap<WrapMode, WRAP_MAX_ENUM>::Entry wrapModeEntries[];
-		static StringMap<WrapMode, WRAP_MAX_ENUM> wrapModes;
-
-	}; // Image
-
-} // graphics
-} // love
-
-#endif // LOVE_GRAPHICS_IMAGE_H
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_GRAPHICS_IMAGE_H
+#define LOVE_GRAPHICS_IMAGE_H
+
+// LOVE
+#include "graphics/Volatile.h"
+#include "graphics/DrawQable.h"
+#include "common/StringMap.h"
+
+namespace love
+{
+namespace graphics
+{
+
+class Image : public DrawQable, public Volatile
+{
+public:
+
+	enum WrapMode
+	{
+		WRAP_CLAMP = 1,
+		WRAP_REPEAT,
+		WRAP_MAX_ENUM
+	};
+
+	enum FilterMode
+	{
+		FILTER_LINEAR = 1,
+		FILTER_NEAREST,
+		FILTER_MAX_ENUM
+	};
+
+	struct Filter
+	{
+		Filter();
+		FilterMode min;
+		FilterMode mag;
+	};
+
+	struct Wrap
+	{
+		Wrap();
+		WrapMode s;
+		WrapMode t;
+	};
+
+	virtual ~Image();
+
+	static bool getConstant(const char *in, FilterMode &out);
+	static bool getConstant(FilterMode in, const char  *&out);
+	static bool getConstant(const char *in, WrapMode &out);
+	static bool getConstant(WrapMode in, const char  *&out);
+
+private:
+
+	static StringMap<FilterMode, FILTER_MAX_ENUM>::Entry filterModeEntries[];
+	static StringMap<FilterMode, FILTER_MAX_ENUM> filterModes;
+	static StringMap<WrapMode, WRAP_MAX_ENUM>::Entry wrapModeEntries[];
+	static StringMap<WrapMode, WRAP_MAX_ENUM> wrapModes;
+
+}; // Image
+
+} // graphics
+} // love
+
+#endif // LOVE_GRAPHICS_IMAGE_H

+ 37 - 36
src/modules/graphics/Quad.cpp

@@ -1,36 +1,37 @@
-/**
-* Copyright (c) 2006-2012 LOVE Development Team
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "Quad.h"
-
-namespace love
-{
-namespace graphics
-{
-	Quad::Quad()
-	{
-	}
-
-	Quad::~Quad()
-	{
-	}
-
-} // graphics
-} // love
+/**
+ * Copyright (c) 2006-2012 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "Quad.h"
+
+namespace love
+{
+namespace graphics
+{
+
+Quad::Quad()
+{
+}
+
+Quad::~Quad()
+{
+}
+
+} // graphics
+} // love

Some files were not shown because too many files changed in this diff