Browse Source

updated from latest love-android (228a26ab99bb)

fysx 11 years ago
parent
commit
b875fffedb
50 changed files with 984 additions and 228 deletions
  1. 5 0
      jni/love/.hg_archival.txt
  2. 45 0
      jni/love/.hgignore
  3. 9 0
      jni/love/.hgtags
  4. 73 12
      jni/love/CMakeLists.txt
  5. 123 20
      jni/love/changes.txt
  6. 4 4
      jni/love/license.txt
  7. 2 2
      jni/love/platform/macosx/Info-Framework.plist
  8. 1 1
      jni/love/platform/macosx/love-Info.plist
  9. 217 12
      jni/love/platform/macosx/love-framework.xcodeproj/project.pbxproj
  10. 80 1
      jni/love/platform/macosx/love.xcodeproj/project.pbxproj
  11. 2 2
      jni/love/platform/unix/configure.ac
  12. 1 1
      jni/love/platform/unix/debian/control.in
  13. 5 0
      jni/love/platform/unix/debian/love.install
  14. 9 7
      jni/love/platform/unix/genmodules
  15. 12 2
      jni/love/platform/unix/love.1
  16. 1 1
      jni/love/platform/unix/love.desktop.in
  17. 4 1
      jni/love/readme.md
  18. 11 15
      jni/love/src/modules/audio/openal/Pool.cpp
  19. 4 1
      jni/love/src/modules/audio/openal/Source.cpp
  20. 1 0
      jni/love/src/modules/audio/openal/Source.h
  21. 22 0
      jni/love/src/modules/graphics/Graphics.cpp
  22. 27 0
      jni/love/src/modules/graphics/Graphics.h
  23. 4 13
      jni/love/src/modules/graphics/Volatile.cpp
  24. 42 1
      jni/love/src/modules/graphics/opengl/Canvas.cpp
  25. 7 0
      jni/love/src/modules/graphics/opengl/Canvas.h
  26. 17 2
      jni/love/src/modules/graphics/opengl/Font.cpp
  27. 4 0
      jni/love/src/modules/graphics/opengl/Font.h
  28. 21 3
      jni/love/src/modules/graphics/opengl/Graphics.cpp
  29. 6 1
      jni/love/src/modules/graphics/opengl/Graphics.h
  30. 32 1
      jni/love/src/modules/graphics/opengl/Image.cpp
  31. 4 0
      jni/love/src/modules/graphics/opengl/Image.h
  32. 2 2
      jni/love/src/modules/graphics/opengl/Mesh.cpp
  33. 33 39
      jni/love/src/modules/graphics/opengl/OpenGL.cpp
  34. 15 8
      jni/love/src/modules/graphics/opengl/OpenGL.h
  35. 1 1
      jni/love/src/modules/graphics/opengl/ParticleSystem.cpp
  36. 4 4
      jni/love/src/modules/graphics/opengl/Polyline.cpp
  37. 1 1
      jni/love/src/modules/graphics/opengl/SpriteBatch.cpp
  38. 36 0
      jni/love/src/modules/graphics/opengl/wrap_Graphics.cpp
  39. 1 0
      jni/love/src/modules/graphics/opengl/wrap_Graphics.h
  40. 24 28
      jni/love/src/modules/image/magpie/PNGHandler.cpp
  41. 0 9
      jni/love/src/modules/image/magpie/ddsHandler.cpp
  42. 12 8
      jni/love/src/modules/joystick/sdl/JoystickModule.cpp
  43. 2 0
      jni/love/src/modules/window/Window.cpp
  44. 2 0
      jni/love/src/modules/window/Window.h
  45. 6 0
      jni/love/src/modules/window/sdl/Window.cpp
  46. 6 4
      jni/love/src/modules/window/wrap_Window.cpp
  47. 7 1
      jni/love/src/scripts/boot.lua
  48. 14 3
      jni/love/src/scripts/boot.lua.h
  49. 9 6
      jni/love/src/scripts/graphics.lua
  50. 14 11
      jni/love/src/scripts/graphics.lua.h

+ 5 - 0
jni/love/.hg_archival.txt

@@ -0,0 +1,5 @@
+repo: d362ae6ab7f5005b8dbc7cba9ce592637de60f99
+node: 228a26ab99bbb41e47d7ff792c670dba220fca88
+branch: android
+latesttag: 0.9.1
+latesttagdistance: 105

+ 45 - 0
jni/love/.hgignore

@@ -0,0 +1,45 @@
+relre:platform/msvc2008/include/
+glob:platform/msvc2008/lib/
+relre:platform/msvc2008/(.*)txt
+relre:platform/msvc2008/(.*)suo
+glob:extra/reshax/Release/
+glob:extra/reshax/Debug/
+glob:extra/reshax/resources.h
+glob:extra/reshax/resources.cpp
+glob:*.obj
+glob:*.o
+glob:*.dirstamp
+glob:*.m4
+glob:*.Po
+glob:*.lo
+glob:*.Plo
+glob:*.dll
+glob:*.user
+glob:*.suo
+glob:*/Release*
+glob:*/Debug*
+glob:*.lib
+glob:*.ncb
+glob:*.exe
+glob:*.bat
+glob:platform/macosx/build
+glob:platform/macosx/Build
+glob:platform/macosx/DerivedData
+glob:platform/macosx/*.xcodeproj/bill*
+glob:platform/macosx/*.xcodeproj/xcuserdata
+glob:platform/macosx/*.xcodeproj/project.xcworkspace
+glob:*.DS_Store
+glob:*.dylib
+glob:*.dmg*
+glob:demos
+glob:*.orig
+relre:platform/msvc2010/include/
+glob:platform/msvc2010/lib/
+relre:platform/msvc2010/(.*)txt
+relre:platform/msvc2010/(.*)suo
+relre:platform/msvc2010/(.*)sdf
+relre:platform/msvc2010/(.*)ipch
+glob:.*.swp
+glob:autom4te.cache/
+glob:src/.libs/
+glob:*~

+ 9 - 0
jni/love/.hgtags

@@ -0,0 +1,9 @@
+301312c82b00b1b70ceba066e1fab523be38b60a 0.6.0
+1c05df814086e1c3486423381b4bf52a3b5d4f87 0.6.1
+db7cd0682883ed357adef013a326bbb26de28c98 0.6.2
+9240be0fe0ea1070bc604954ab2e81320e278ad9 0.7.0
+18d79c306466d188919c238d23e50ea705b07c03 0.7.1
+bcca82b60d0f5cd724edbe4ed65db18ab95d4691 0.7.2
+e0f98d53debb62347c6433ca0534a0f77f15f76f 0.8.0
+38c00c788bcb03bda2ad40efebcdfe7a6be85b4a 0.9.0
+8b113c345e97e7bb7e963e5d67451abdfb05cfde 0.9.1

+ 73 - 12
jni/love/CMakeLists.txt

@@ -185,6 +185,12 @@ set(LOVE_SRC_MODULE_FILESYSTEM_ROOT
 	src/modules/filesystem/File.h
 	src/modules/filesystem/File.h
 	src/modules/filesystem/FileData.cpp
 	src/modules/filesystem/FileData.cpp
 	src/modules/filesystem/FileData.h
 	src/modules/filesystem/FileData.h
+	src/modules/filesystem/wrap_File.cpp
+	src/modules/filesystem/wrap_File.h
+	src/modules/filesystem/wrap_FileData.cpp
+	src/modules/filesystem/wrap_FileData.h
+	src/modules/filesystem/wrap_Filesystem.cpp
+	src/modules/filesystem/wrap_Filesystem.h
 )
 )
 
 
 set(LOVE_SRC_MODULE_FILESYSTEM_PHYSFS
 set(LOVE_SRC_MODULE_FILESYSTEM_PHYSFS
@@ -192,12 +198,6 @@ set(LOVE_SRC_MODULE_FILESYSTEM_PHYSFS
 	src/modules/filesystem/physfs/File.h
 	src/modules/filesystem/physfs/File.h
 	src/modules/filesystem/physfs/Filesystem.cpp
 	src/modules/filesystem/physfs/Filesystem.cpp
 	src/modules/filesystem/physfs/Filesystem.h
 	src/modules/filesystem/physfs/Filesystem.h
-	src/modules/filesystem/physfs/wrap_File.cpp
-	src/modules/filesystem/physfs/wrap_File.h
-	src/modules/filesystem/physfs/wrap_FileData.cpp
-	src/modules/filesystem/physfs/wrap_FileData.h
-	src/modules/filesystem/physfs/wrap_Filesystem.cpp
-	src/modules/filesystem/physfs/wrap_Filesystem.h
 )
 )
 
 
 set(LOVE_SRC_MODULE_FILESYSTEM
 set(LOVE_SRC_MODULE_FILESYSTEM
@@ -337,15 +337,29 @@ set(LOVE_SRC_MODULE_IMAGE_ROOT
 set(LOVE_SRC_MODULE_IMAGE_MAGPIE
 set(LOVE_SRC_MODULE_IMAGE_MAGPIE
 	src/modules/image/magpie/CompressedData.cpp
 	src/modules/image/magpie/CompressedData.cpp
 	src/modules/image/magpie/CompressedData.h
 	src/modules/image/magpie/CompressedData.h
+	src/modules/image/magpie/CompressedFormatHandler.h
 	src/modules/image/magpie/ddsHandler.cpp
 	src/modules/image/magpie/ddsHandler.cpp
 	src/modules/image/magpie/ddsHandler.h
 	src/modules/image/magpie/ddsHandler.h
 	src/modules/image/magpie/DevilHandler.cpp
 	src/modules/image/magpie/DevilHandler.cpp
 	src/modules/image/magpie/DevilHandler.h
 	src/modules/image/magpie/DevilHandler.h
+	src/modules/image/magpie/FormatHandler.cpp
 	src/modules/image/magpie/FormatHandler.h
 	src/modules/image/magpie/FormatHandler.h
 	src/modules/image/magpie/Image.cpp
 	src/modules/image/magpie/Image.cpp
 	src/modules/image/magpie/Image.h
 	src/modules/image/magpie/Image.h
 	src/modules/image/magpie/ImageData.cpp
 	src/modules/image/magpie/ImageData.cpp
 	src/modules/image/magpie/ImageData.h
 	src/modules/image/magpie/ImageData.h
+	src/modules/image/magpie/JPEGHandler.cpp
+	src/modules/image/magpie/JPEGHandler.h
+	src/modules/image/magpie/KTXHandler.cpp
+	src/modules/image/magpie/KTXHandler.h
+	src/modules/image/magpie/PKMHandler.cpp
+	src/modules/image/magpie/PKMHandler.h
+	src/modules/image/magpie/PVRHandler.cpp
+	src/modules/image/magpie/PVRHandler.h
+	src/modules/image/magpie/PNGHandler.cpp
+	src/modules/image/magpie/PNGHandler.h
+	src/modules/image/magpie/STBHandler.cpp
+	src/modules/image/magpie/STBHandler.h
 )
 )
 
 
 set(LOVE_SRC_MODULE_IMAGE
 set(LOVE_SRC_MODULE_IMAGE
@@ -364,6 +378,10 @@ set(LOVE_SRC_MODULE_JOYSTICK_ROOT
 	src/modules/joystick/Joystick.cpp
 	src/modules/joystick/Joystick.cpp
 	src/modules/joystick/Joystick.h
 	src/modules/joystick/Joystick.h
 	src/modules/joystick/JoystickModule.h
 	src/modules/joystick/JoystickModule.h
+	src/modules/joystick/wrap_Joystick.cpp
+	src/modules/joystick/wrap_Joystick.h
+	src/modules/joystick/wrap_JoystickModule.cpp
+	src/modules/joystick/wrap_JoystickModule.h
 )
 )
 
 
 set(LOVE_SRC_MODULE_JOYSTICK_SDL
 set(LOVE_SRC_MODULE_JOYSTICK_SDL
@@ -371,10 +389,6 @@ set(LOVE_SRC_MODULE_JOYSTICK_SDL
 	src/modules/joystick/sdl/Joystick.h
 	src/modules/joystick/sdl/Joystick.h
 	src/modules/joystick/sdl/JoystickModule.cpp
 	src/modules/joystick/sdl/JoystickModule.cpp
 	src/modules/joystick/sdl/JoystickModule.h
 	src/modules/joystick/sdl/JoystickModule.h
-	src/modules/joystick/sdl/wrap_Joystick.cpp
-	src/modules/joystick/sdl/wrap_Joystick.h
-	src/modules/joystick/sdl/wrap_JoystickModule.cpp
-	src/modules/joystick/sdl/wrap_JoystickModule.h
 )
 )
 
 
 set(LOVE_SRC_MODULE_JOYSTICK
 set(LOVE_SRC_MODULE_JOYSTICK
@@ -711,6 +725,29 @@ set(LOVE_SRC_MODULE_TIMER
 source_group("modules\\timer" FILES ${LOVE_SRC_MODULE_TIMER_ROOT})
 source_group("modules\\timer" FILES ${LOVE_SRC_MODULE_TIMER_ROOT})
 source_group("modules\\timer\\sdl" FILES ${LOVE_SRC_MODULE_TIMER_SDL})
 source_group("modules\\timer\\sdl" FILES ${LOVE_SRC_MODULE_TIMER_SDL})
 
 
+#
+# love.touch
+#
+
+set(LOVE_SRC_MODULE_TOUCH_ROOT
+	src/modules/touch/Touch.h
+	src/modules/touch/wrap_Touch.cpp
+	src/modules/touch/wrap_Touch.h
+)
+
+set(LOVE_SRC_MODULE_TOUCH_SDL
+	src/modules/touch/sdl/Touch.cpp
+	src/modules/touch/sdl/Touch.h
+)
+
+set(LOVE_SRC_MODULE_TOUCH
+	${LOVE_SRC_MODULE_TOUCH_ROOT}
+	${LOVE_SRC_MODULE_TOUCH_SDL}
+)
+
+source_group("modules\\touch" FILES ${LOVE_SRC_MODULE_TOUCH_ROOT})
+source_group("modules\\touch\\sdl" FILES ${LOVE_SRC_MODULE_TOUCH_SDL})
+
 #
 #
 # love.window
 # love.window
 #
 #
@@ -927,6 +964,17 @@ add_library(love_3p_enet ${LOVE_SRC_3P_ENET})
 target_link_libraries(love_3p_enet ${MEGA_LUA})
 target_link_libraries(love_3p_enet ${MEGA_LUA})
 target_include_directories(love_3p_enet PUBLIC src/libraries/enet/libenet/include)
 target_include_directories(love_3p_enet PUBLIC src/libraries/enet/libenet/include)
 
 
+#
+# LodePNG
+#
+
+set(LOVE_SRC_3P_LODEPNG
+	src/libraries/lodepng/lodepng.cpp
+	src/libraries/lodepng/lodepng.h
+)
+
+add_library(love_3p_lodepng ${LOVE_SRC_3P_LODEPNG})
+
 #
 #
 # luasocket
 # luasocket
 #
 #
@@ -1000,6 +1048,16 @@ set(LOVE_SRC_3P_NOISE1234
 
 
 add_library(love_3p_noise1234 ${LOVE_SRC_3P_NOISE1234})
 add_library(love_3p_noise1234 ${LOVE_SRC_3P_NOISE1234})
 
 
+#
+# stb_image
+#
+
+set(LOVE_SRC_3P_STB
+	src/libraries/stb/stb_image.h
+)
+
+add_library(love_3p_stb ${LOVE_SRC_3P_STB})
+
 #
 #
 # utf8
 # utf8
 #
 #
@@ -1041,8 +1099,10 @@ set(LOVE_3P
 	love_3p_box2d
 	love_3p_box2d
 	love_3p_ddsparse
 	love_3p_ddsparse
 	love_3p_enet
 	love_3p_enet
+	love_3p_lodepng
 	love_3p_luasocket
 	love_3p_luasocket
 	love_3p_noise1234
 	love_3p_noise1234
+	love_3p_stb
 	love_3p_wuff
 	love_3p_wuff
 )
 )
 
 
@@ -1070,6 +1130,7 @@ set(LOVE_LIB_SRC
 	${LOVE_SRC_MODULE_SYSTEM}
 	${LOVE_SRC_MODULE_SYSTEM}
 	${LOVE_SRC_MODULE_THREAD}
 	${LOVE_SRC_MODULE_THREAD}
 	${LOVE_SRC_MODULE_TIMER}
 	${LOVE_SRC_MODULE_TIMER}
+	#{LOVE_SRC_MODULE_TOUCH}
 	${LOVE_SRC_MODULE_WINDOW}
 	${LOVE_SRC_MODULE_WINDOW}
 )
 )
 
 
@@ -1118,8 +1179,8 @@ if(MSVC)
 	)
 	)
 
 
 	set(LOVE_RC
 	set(LOVE_RC
-		platform/msvc2010/love.rc
-		platform/msvc2010/love.ico
+		extra/windows/love.rc
+		extra/windows/love.ico
 	)
 	)
 endif()
 endif()
 
 

+ 123 - 20
jni/love/changes.txt

@@ -1,24 +1,127 @@
-LOVE 0.9.1 [Baby Inspector]
+LOVE 0.9.2 [Baby Inspector]
 ---------------------------
 ---------------------------
 
 
   Released: N/A
   Released: N/A
 
 
+  * Added Shader:getExternVariable.
+  * Added several new canvas texture formats.
+  * Added love.graphics.getCanvasFormats.
+  * Added love.graphics.getCompressedImageFormats.
+  * Added ParticleSystem:setQuads.
+  * Added SpriteBatch:flush.
+  * Added love.graphics.getStats.
+  * Added optional duration argument to Joystick:setVibration.
+  * Added love.joystick.loadGamepadMappings and love.joystick.saveGamepadMappings.
+  * Added Joint:setUserData and Joint:getUserData.
+  * Added Contact:getFixtures and Body:getContactList.
+  * Added Body:getWorld.
+  * Added love.window.getDisplayName.
+  * Added love.window.minimize.
+  * Added love.window.showMessageBox.
+  * Added love.filesystem.isSymlink, love.filesystem.setSymlinksEnabled, and love.filesystem.areSymlinksEnabled.
+  * Added 'refreshrate' field to the table returned by love.window.getMode.
+
+  * Deprecated SpriteBatch:bind and SpriteBatch:unbind.
+  * Deprecated all uses of the name 'FSAA' in favor of 'MSAA'.
+  * Deprecated the 'hdrcanvas' graphics feature enum in favor of getCanvasFormats.
+  * Deprecated the 'dxt' and 'bc5' graphics feature enums in favor of getCompressedImageFormats.
+
+  * Fixed love.filesystem.setIdentity breaking in some situations when called multiple times.
+  * Fixed love.system.openURL sometimes blocking indefinitely on Linux.
+  * Fixed shader:getWarnings returning unnecessary information.
+  * Fixed a potential crash when Shader objects are garbage collected.
+  * Fixed love.graphics.newMesh(vertexcount, ...) causing the Mesh to do instanced rendering.
+  * Fixed Mesh:getVertexMap.
+  * Fixed Image:refresh generating mipmaps multiple times if mipmap filtering is enabled.
+  * Fixed Mesh:setDrawRange when the Mesh has a vertex map set.
+  * Fixed internal detection of the 'position' and 'effect' shader functions.
+  * Fixed Texture memory leak when Meshes are garbage collected.
+  * Fixed the default line join mode to be 'miter' instead of an undefined value.
+  * Fixed the default error handler text size when highdpi mode is enabled on a Retina monitor.
+  * Fixed love.window.setMode to fall back to the largest available mode if a width or height greater than the largest supported is specified and fullscreen=true.
+  * Fixed the state of wireframe mode when love.window.setMode is called.
+  * Fixed Canvas:getPixel to error if the coordinates are not within the Canvas' size.
+  * Fixed detection of compressed textures to work regardless of the file's extension.
+
+  * Renamed all cases of FSAA to MSAA. The FSAA names still exist for backward-compatibility.
+
+  * Updated the Lua wrapper code for modules to avoid crashes when the module's instance is created, deleted, and recreated.
+  * Updated internal code for handling garbage collection of love objects to be more efficient.
+  * Updated the paths returned by love.filesystem.getSaveDirectory and friends to strip double-slashes from the string.
+  * Updated the error message when love.filesystem.write or File:open fails because the directory doesn't exist.
+  * Updated the error message when love.math.setRandomseed(0) is attempted.
+  * Updated love.physics.newChainShape to error if the number of arguments is invalid.
+  * Updated love-created threads to use names visible in external debuggers.
+  * Updated SpriteBatch:unbind to use less VRAM if the SpriteBatch has the static usage hint.
+  * Updated love.graphics.newImage, love.image.newImageData, etc. to leave less Lua-owned memory around.
+  * Updated love.graphics.push to accept different stack types to push. Current types are "transform" and "all".
+
+LOVE 0.9.1 [Baby Inspector]
+---------------------------
+
+  Released: 2014-04-01
+
   * Added Source:clone.
   * Added Source:clone.
+  * Added blend mode "screen".
   * Added ParticleSystem:clone.
   * Added ParticleSystem:clone.
-  * Added Mesh:setWireframe and Mesh:isWireframe for debugging.
+  * Added ParticleSystem:moveTo, has smoother emitter movement compared to setPosition.
+  * Added ParticleSystem:setRelativeRotation.
+  * Added love.graphics.setWireframe for debugging.
+  * Added Mesh:setDrawRange and Mesh:getDrawRange.
+  * Added CircleShape:getPoint and CircleShape:setPoint.
+  * Added Mesh/SpriteBatch/ParticleSystem:setTexture, accepts Canvases and Images.
+  * Added high-dpi window support for Retina displays in OS X, via the 'highdpi' window flag.
+  * Added love.window.getPixelScale.
+  * Added love.graphics.getSystemLimit.
+  * Added antialiasing support to Canvases.
+  * Added Canvas:getFSAA.
+  * Added 'love_ScreenSize' built-in variable in shaders.
+  * Added love.getVersion.
+  * Added support for gamma-correct rendering.
+  * Added love.graphics.isSupported("srgb").
+  * Added love.math.gammaToLinear and love.math.linearToGamma.
+  * Added RandomGenerator:getState and RandomGenerator:setState.
+  * Added Body:setUserData and Body:getUserData.
+  * Added some missing obscure key constants.
+  * Added optional callback function argument to love.filesystem.getDirectoryItems.
+  * Added love.system.openURL.
+
+  * Deprecated Mesh/SpriteBatch/ParticleSystem:setImage.
+  * Deprecated love.graphics.getMaxImageSize and love.graphics.getMaxPointSize.
 
 
   * Fixed love.graphics.scale with negative values causing incorrect line widths.
   * Fixed love.graphics.scale with negative values causing incorrect line widths.
   * Fixed Joystick:isDown using 0-based button index arguments.
   * Fixed Joystick:isDown using 0-based button index arguments.
   * Fixed Source:setPitch to error when infinity or NaN is given.
   * Fixed Source:setPitch to error when infinity or NaN is given.
   * Fixed love.graphics.setCanvas() to restore the proper viewport and scissor rectangles.
   * Fixed love.graphics.setCanvas() to restore the proper viewport and scissor rectangles.
   * Fixed TrueType font glyphs which request a monochrome bitmap pixel mode.
   * Fixed TrueType font glyphs which request a monochrome bitmap pixel mode.
-
-  * Updated the error text for LÖVE’s module searchers when require fails.
+  * Fixed love.graphics.reset causing crashes when called in between love.graphics.push/pop.
+  * Fixed tab characters ("\t") to display properly with love.graphics.print.
+  * Fixed love.graphics.isCreated to return false when love.window.setMode fails completely.
+  * Fixed love.window.setMode to not destroy OpenGL resources before checking whether a fullsceren size is supported.
+  * Fixed World:getBodyList and World:getJointList causing hard crashes.
+  * Fixed loading BC4 compressed textures.
+  * Fixed SoundData objects being initialized with garbage values.
+  * Fixed 8-bit SoundData samples when used in love.audio Sources.
+
+  * Updated the error text for love.filesystem’s module searchers when require fails.
+  * Updated the love.filesystem module searchers to be tried after package.preload instead of before.
+  * Updated love.graphics.newParticleSystem, newSpriteBatch, and newMesh to accept Canvases.
+  * Updated Canvas drawing code, texture coordinates are no longer flipped vertically.
+  * Updated Canvas:renderTo to work properly if a Canvas is currently active.
+  * Updated ParticleSystem:setEmissionRate to accept non-integer numbers.
+  * Updated Source:play to return a boolean indicating success.
+  * Updated t.console in conf.lua to create the console before modules are loaded in Windows.
+  * Updated Mesh vertex maps (index buffers) to use less space in VRAM.
+  * Updated love.graphics.newMesh and Mesh:setVertices to default the UV parameters to 0,0.
+  * Updated Fixture:set/getUserData to work in Coroutines.
+  * Updated fullscreen-desktop and resizable window modes in OS X to use Mac OS 10.7's fullscreen Spaces.
+  * Updated love.filesystem's C library loader to look in paths added via love.filesystem.mount, in Fused mode.
+  * Updated the default love.run code to make initial love.math.random calls more random.
 
 
 LOVE 0.9.0 [Baby Inspector]
 LOVE 0.9.0 [Baby Inspector]
 ---------------------------
 ---------------------------
 
 
-	Released: 2013-12-13
+  Released: 2013-12-13
 
 
   * Added better multiplayer networking support via ENet.
   * Added better multiplayer networking support via ENet.
   * Added --fused command line argument, to simulate fusing.
   * Added --fused command line argument, to simulate fusing.
@@ -236,7 +339,7 @@ LOVE 0.9.0 [Baby Inspector]
 LOVE 0.8.0 [Rubber Piggy]
 LOVE 0.8.0 [Rubber Piggy]
 -------------------------
 -------------------------
 
 
-	Released: 2012-04-02
+  Released: 2012-04-02
 
 
   * Added release error screen.
   * Added release error screen.
   * Added alpha to love.graphics.setBackgroundColor.
   * Added alpha to love.graphics.setBackgroundColor.
@@ -327,7 +430,7 @@ LOVE 0.8.0 [Rubber Piggy]
 LOVE 0.7.2 [Game Slave]
 LOVE 0.7.2 [Game Slave]
 -----------------------
 -----------------------
 
 
-	Released: 2011-05-04
+  Released: 2011-05-04
 
 
   * Added Framebuffer:get/setWrap.
   * Added Framebuffer:get/setWrap.
   * Added love.event.clear.
   * Added love.event.clear.
@@ -353,7 +456,7 @@ LOVE 0.7.2 [Game Slave]
 LOVE 0.7.1 [Game Slave]
 LOVE 0.7.1 [Game Slave]
 -----------------------
 -----------------------
 
 
-	Released: 2011-02-14
+  Released: 2011-02-14
 
 
   * Added source:isPaused()
   * Added source:isPaused()
   * Added error when initial window can't be created.
   * Added error when initial window can't be created.
@@ -389,7 +492,7 @@ LOVE 0.7.1 [Game Slave]
 LOVE 0.7.0 [Game Slave]
 LOVE 0.7.0 [Game Slave]
 -----------------------
 -----------------------
 
 
-	Released: 2010-12-05
+  Released: 2010-12-05
 
 
   * Added love.thread.
   * Added love.thread.
   * Added love.font.
   * Added love.font.
@@ -445,7 +548,7 @@ LOVE 0.7.0 [Game Slave]
 LOVE 0.6.2 [Jiggly Juice]
 LOVE 0.6.2 [Jiggly Juice]
 -------------------------
 -------------------------
 
 
-	Released: 2010-03-06
+  Released: 2010-03-06
 
 
   * Fixed a bug causing ImageFonts to cut off some pixels.
   * Fixed a bug causing ImageFonts to cut off some pixels.
   * Fixed a bug where filled rectangles were too small.
   * Fixed a bug where filled rectangles were too small.
@@ -459,7 +562,7 @@ LOVE 0.6.2 [Jiggly Juice]
 LOVE 0.6.1 [Jiggly Juice]
 LOVE 0.6.1 [Jiggly Juice]
 -------------------------
 -------------------------
 
 
-	Released: 2010-02-07
+  Released: 2010-02-07
 
 
   * Added Shape:setGroupIndex and getGroupIndex.
   * Added Shape:setGroupIndex and getGroupIndex.
   * Added Body:setFixedRotation and Body:getFixedRotation.
   * Added Body:setFixedRotation and Body:getFixedRotation.
@@ -484,7 +587,7 @@ LOVE 0.6.1 [Jiggly Juice]
 LOVE 0.6.0 [Jiggly Juice]
 LOVE 0.6.0 [Jiggly Juice]
 -------------------------
 -------------------------
 
 
-	Released: 2009-12-24
+  Released: 2009-12-24
 
 
   * Lost track of 0.6.0 changes a long while ago. Don't trust the list below.
   * Lost track of 0.6.0 changes a long while ago. Don't trust the list below.
 
 
@@ -521,7 +624,7 @@ LOVE 0.6.0 [Jiggly Juice]
 LOVE 0.5.0 [Salted Nuts]
 LOVE 0.5.0 [Salted Nuts]
 ------------------------
 ------------------------
 
 
-	Released: 2009-01-02
+  Released: 2009-01-02
 
 
   * Added love.joystick.
   * Added love.joystick.
   * Added network support via LuaSocket.
   * Added network support via LuaSocket.
@@ -558,7 +661,7 @@ LOVE 0.5.0 [Salted Nuts]
 LOVE 0.4.0 [Taco Beam]
 LOVE 0.4.0 [Taco Beam]
 ----------------------
 ----------------------
 
 
-	Released: 2008-08-29
+  Released: 2008-08-29
 
 
   * Added love.physics. (YES!)
   * Added love.physics. (YES!)
   * Added love.audio.setMode().
   * Added love.audio.setMode().
@@ -572,7 +675,7 @@ LOVE 0.4.0 [Taco Beam]
 LOVE 0.3.2 [Lemony Fresh]
 LOVE 0.3.2 [Lemony Fresh]
 -------------------------
 -------------------------
 
 
-	Released: 2008-07-04
+  Released: 2008-07-04
 
 
   * Added love.graphics.rectangle()
   * Added love.graphics.rectangle()
   * Added love.graphics.setLineWidth()
   * Added love.graphics.setLineWidth()
@@ -591,7 +694,7 @@ LOVE 0.3.2 [Lemony Fresh]
 LOVE 0.3.1 [Space Meat]
 LOVE 0.3.1 [Space Meat]
 -----------------------
 -----------------------
 
 
-	Released: 2008-06-21
+  Released: 2008-06-21
 
 
   * Fixed segfault related to graphics.
   * Fixed segfault related to graphics.
   * Fixed wait-forever bug related to audio.
   * Fixed wait-forever bug related to audio.
@@ -602,7 +705,7 @@ LOVE 0.3.1 [Space Meat]
 LOVE 0.3.0 [Mutant Vermin]
 LOVE 0.3.0 [Mutant Vermin]
 --------------------------
 --------------------------
 
 
-	Released: 2008-06-17
+  Released: 2008-06-17
 
 
   * Added ParticleSystem.
   * Added ParticleSystem.
   * Added visual error reporting.
   * Added visual error reporting.
@@ -622,7 +725,7 @@ LOVE 0.3.0 [Mutant Vermin]
 LOVE 0.2.1 [Impending Doom]
 LOVE 0.2.1 [Impending Doom]
 ---------------------------
 ---------------------------
 
 
-	Released: 2008-03-29
+  Released: 2008-03-29
 
 
   * Added many functions in love.filesystem.
   * Added many functions in love.filesystem.
   * Added a dedicated save-folder for each game.
   * Added a dedicated save-folder for each game.
@@ -658,7 +761,7 @@ LOVE 0.2.1 [Impending Doom]
 LOVE 0.2.0 [Mini-Moose]
 LOVE 0.2.0 [Mini-Moose]
 -----------------------
 -----------------------
 
 
-	Released: 2008-02-06
+  Released: 2008-02-06
 
 
   * Added ImageFont
   * Added ImageFont
   * Added Animation
   * Added Animation
@@ -679,7 +782,7 @@ LOVE 0.1.1 [Santa-Power]
 ------------------------
 ------------------------
 
 
 	Initial release!
 	Initial release!
-	Released: 2008-01-13
+  Released: 2008-01-13
 
 
  * Image loading and rendering.
  * Image loading and rendering.
  * Sound loading and playing.
  * Sound loading and playing.

+ 4 - 4
jni/love/license.txt

@@ -23,14 +23,14 @@ distribution.
 
 
 -------
 -------
 
 
-LÖVE also uses the following LGPL libraries:
+LÖVE uses the following LGPL libraries on most platforms:
 
 
  - libmpg123
  - libmpg123
      Website: http://www.mpg123.de/
      Website: http://www.mpg123.de/
      Source download: http://sourceforge.net/projects/mpg123/files/latest/download
      Source download: http://sourceforge.net/projects/mpg123/files/latest/download
- - OpenAL
-     Website: http://connect.creativelabs.com/openal/default.aspx
-     Source download: http://connect.creativelabs.com/openal/Downloads/openal-soft-1.13.tbz2
+ - OpenAL Soft
+     Website: http://kcat.strangesoft.net/openal.html
+     Source download: http://kcat.strangesoft.net/openal.html#download
  - DevIL
  - DevIL
      Website: http://openil.sourceforge.net/
      Website: http://openil.sourceforge.net/
      Source download: http://downloads.sourceforge.net/openil/DevIL-1.7.8.tar.gz
      Source download: http://downloads.sourceforge.net/openil/DevIL-1.7.8.tar.gz

+ 2 - 2
jni/love/platform/macosx/Info-Framework.plist

@@ -17,11 +17,11 @@
 	<key>CFBundlePackageType</key>
 	<key>CFBundlePackageType</key>
 	<string>FMWK</string>
 	<string>FMWK</string>
 	<key>CFBundleShortVersionString</key>
 	<key>CFBundleShortVersionString</key>
-	<string>0.9.0</string>
+	<string>0.9.2</string>
 	<key>CFBundleSignature</key>
 	<key>CFBundleSignature</key>
 	<string>LoVe</string>
 	<string>LoVe</string>
 	<key>CFBundleVersion</key>
 	<key>CFBundleVersion</key>
-	<string>0.9.0</string>
+	<string>0.9.2</string>
 	<key>NSPrincipalClass</key>
 	<key>NSPrincipalClass</key>
 	<string></string>
 	<string></string>
 </dict>
 </dict>

+ 1 - 1
jni/love/platform/macosx/love-Info.plist

@@ -46,7 +46,7 @@
 	<key>CFBundlePackageType</key>
 	<key>CFBundlePackageType</key>
 	<string>APPL</string>
 	<string>APPL</string>
 	<key>CFBundleShortVersionString</key>
 	<key>CFBundleShortVersionString</key>
-	<string>0.9.0</string>
+	<string>0.9.2</string>
 	<key>CFBundleSignature</key>
 	<key>CFBundleSignature</key>
 	<string>LoVe</string>
 	<string>LoVe</string>
 	<key>LSApplicationCategoryType</key>
 	<key>LSApplicationCategoryType</key>

+ 217 - 12
jni/love/platform/macosx/love-framework.xcodeproj/project.pbxproj

@@ -227,6 +227,23 @@
 		FA3D9E1616E6D41100CA6630 /* wrap_Cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = FA3D9E1416E6D41000CA6630 /* wrap_Cursor.h */; };
 		FA3D9E1616E6D41100CA6630 /* wrap_Cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = FA3D9E1416E6D41000CA6630 /* wrap_Cursor.h */; };
 		FA435EA317B36E9C004C3F22 /* Polyline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA435EA117B36E9C004C3F22 /* Polyline.cpp */; };
 		FA435EA317B36E9C004C3F22 /* Polyline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA435EA117B36E9C004C3F22 /* Polyline.cpp */; };
 		FA435EA417B36E9C004C3F22 /* Polyline.h in Headers */ = {isa = PBXBuildFile; fileRef = FA435EA217B36E9C004C3F22 /* Polyline.h */; };
 		FA435EA417B36E9C004C3F22 /* Polyline.h in Headers */ = {isa = PBXBuildFile; fileRef = FA435EA217B36E9C004C3F22 /* Polyline.h */; };
+		FA45F775187A0F3600D99ED8 /* Touch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA45F770187A0F3600D99ED8 /* Touch.cpp */; };
+		FA45F776187A0F3600D99ED8 /* Touch.h in Headers */ = {isa = PBXBuildFile; fileRef = FA45F771187A0F3600D99ED8 /* Touch.h */; };
+		FA45F777187A0F3600D99ED8 /* Touch.h in Headers */ = {isa = PBXBuildFile; fileRef = FA45F772187A0F3600D99ED8 /* Touch.h */; };
+		FA45F778187A0F3600D99ED8 /* wrap_Touch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA45F773187A0F3600D99ED8 /* wrap_Touch.cpp */; };
+		FA45F779187A0F3600D99ED8 /* wrap_Touch.h in Headers */ = {isa = PBXBuildFile; fileRef = FA45F774187A0F3600D99ED8 /* wrap_Touch.h */; };
+		FA4DAE691941410D009F0A3E /* PNGHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA4DAE651941410D009F0A3E /* PNGHandler.cpp */; };
+		FA4DAE6A1941410D009F0A3E /* PNGHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FA4DAE661941410D009F0A3E /* PNGHandler.h */; };
+		FA4DAE6B1941410D009F0A3E /* STBHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA4DAE671941410D009F0A3E /* STBHandler.cpp */; };
+		FA4DAE6C1941410D009F0A3E /* STBHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FA4DAE681941410D009F0A3E /* STBHandler.h */; };
+		FA4DAE731941411D009F0A3E /* lodepng.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA4DAE6E1941411D009F0A3E /* lodepng.cpp */; };
+		FA4DAE741941411D009F0A3E /* lodepng.h in Headers */ = {isa = PBXBuildFile; fileRef = FA4DAE6F1941411D009F0A3E /* lodepng.h */; };
+		FA4DAE761941411D009F0A3E /* stb_image.h in Headers */ = {isa = PBXBuildFile; fileRef = FA4DAE721941411D009F0A3E /* stb_image.h */; };
+		FA4DAE791941419A009F0A3E /* JPEGHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA4DAE771941419A009F0A3E /* JPEGHandler.cpp */; };
+		FA4DAE7A1941419A009F0A3E /* JPEGHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FA4DAE781941419A009F0A3E /* JPEGHandler.h */; };
+		FA4DAE7C19414281009F0A3E /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FA4DAE7B19414281009F0A3E /* libz.dylib */; };
+		FA52E446192AAADE0064D2FF /* PKMHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA52E444192AAADE0064D2FF /* PKMHandler.cpp */; };
+		FA52E447192AAADE0064D2FF /* PKMHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FA52E445192AAADE0064D2FF /* PKMHandler.h */; };
 		FA5454C216F1310000D30303 /* MathModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA5454C016F1310000D30303 /* MathModule.cpp */; };
 		FA5454C216F1310000D30303 /* MathModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA5454C016F1310000D30303 /* MathModule.cpp */; };
 		FA5454C316F1310000D30303 /* MathModule.h in Headers */ = {isa = PBXBuildFile; fileRef = FA5454C116F1310000D30303 /* MathModule.h */; };
 		FA5454C316F1310000D30303 /* MathModule.h in Headers */ = {isa = PBXBuildFile; fileRef = FA5454C116F1310000D30303 /* MathModule.h */; };
 		FA577AB016C7507900860150 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A7916C71A1700860150 /* Cocoa.framework */; };
 		FA577AB016C7507900860150 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A7916C71A1700860150 /* Cocoa.framework */; };
@@ -258,6 +275,9 @@
 		FA5FDC8D1788D548002F0ED2 /* unix.c in Sources */ = {isa = PBXBuildFile; fileRef = FA5FDC761788D548002F0ED2 /* unix.c */; };
 		FA5FDC8D1788D548002F0ED2 /* unix.c in Sources */ = {isa = PBXBuildFile; fileRef = FA5FDC761788D548002F0ED2 /* unix.c */; };
 		FA5FDC8E1788D548002F0ED2 /* win32.c in Sources */ = {isa = PBXBuildFile; fileRef = FA5FDC771788D548002F0ED2 /* win32.c */; };
 		FA5FDC8E1788D548002F0ED2 /* win32.c in Sources */ = {isa = PBXBuildFile; fileRef = FA5FDC771788D548002F0ED2 /* win32.c */; };
 		FA5FDC8F1788D548002F0ED2 /* lua-enet.h in Headers */ = {isa = PBXBuildFile; fileRef = FA5FDC781788D548002F0ED2 /* lua-enet.h */; };
 		FA5FDC8F1788D548002F0ED2 /* lua-enet.h in Headers */ = {isa = PBXBuildFile; fileRef = FA5FDC781788D548002F0ED2 /* lua-enet.h */; };
+		FA61FD5E1926CFCE003AE9FB /* CompressedFormatHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FA61FD5B1926CFCE003AE9FB /* CompressedFormatHandler.h */; };
+		FA61FD5F1926CFCE003AE9FB /* PVRHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA61FD5C1926CFCE003AE9FB /* PVRHandler.cpp */; };
+		FA61FD601926CFCE003AE9FB /* PVRHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FA61FD5D1926CFCE003AE9FB /* PVRHandler.h */; };
 		FA636D8A171B70920065623F /* RandomGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA636D88171B70920065623F /* RandomGenerator.cpp */; };
 		FA636D8A171B70920065623F /* RandomGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA636D88171B70920065623F /* RandomGenerator.cpp */; };
 		FA636D8B171B70920065623F /* RandomGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FA636D89171B70920065623F /* RandomGenerator.h */; };
 		FA636D8B171B70920065623F /* RandomGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FA636D89171B70920065623F /* RandomGenerator.h */; };
 		FA636D8E171B72A70065623F /* wrap_RandomGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA636D8C171B72A70065623F /* wrap_RandomGenerator.cpp */; };
 		FA636D8E171B72A70065623F /* wrap_RandomGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA636D8C171B72A70065623F /* wrap_RandomGenerator.cpp */; };
@@ -274,6 +294,7 @@
 		FA9B4A0816E1578300074F42 /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA9B4A0716E1578300074F42 /* SDL2.framework */; };
 		FA9B4A0816E1578300074F42 /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA9B4A0716E1578300074F42 /* SDL2.framework */; };
 		FA9FC0B0173D6E3E005027FF /* wrap_Window.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA9FC0AE173D6E3E005027FF /* wrap_Window.cpp */; };
 		FA9FC0B0173D6E3E005027FF /* wrap_Window.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA9FC0AE173D6E3E005027FF /* wrap_Window.cpp */; };
 		FA9FC0B1173D6E3E005027FF /* wrap_Window.h in Headers */ = {isa = PBXBuildFile; fileRef = FA9FC0AF173D6E3E005027FF /* wrap_Window.h */; };
 		FA9FC0B1173D6E3E005027FF /* wrap_Window.h in Headers */ = {isa = PBXBuildFile; fileRef = FA9FC0AF173D6E3E005027FF /* wrap_Window.h */; };
+		FAA627CE18E7E1560080752D /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAA627CD18E7E1560080752D /* CoreServices.framework */; };
 		FAAC6B02170A373B008A61C5 /* CompressedData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAAC6B00170A373A008A61C5 /* CompressedData.cpp */; };
 		FAAC6B02170A373B008A61C5 /* CompressedData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAAC6B00170A373A008A61C5 /* CompressedData.cpp */; };
 		FAAC6B03170A373B008A61C5 /* CompressedData.h in Headers */ = {isa = PBXBuildFile; fileRef = FAAC6B01170A373A008A61C5 /* CompressedData.h */; };
 		FAAC6B03170A373B008A61C5 /* CompressedData.h in Headers */ = {isa = PBXBuildFile; fileRef = FAAC6B01170A373A008A61C5 /* CompressedData.h */; };
 		FAAFF04416CB11C700CCDE45 /* OpenAL-Soft.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAAFF04316CB11C700CCDE45 /* OpenAL-Soft.framework */; };
 		FAAFF04416CB11C700CCDE45 /* OpenAL-Soft.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAAFF04316CB11C700CCDE45 /* OpenAL-Soft.framework */; };
@@ -291,6 +312,7 @@
 		FAC86E641724552C00EED715 /* wrap_Quad.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC86E621724552C00EED715 /* wrap_Quad.h */; };
 		FAC86E641724552C00EED715 /* wrap_Quad.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC86E621724552C00EED715 /* wrap_Quad.h */; };
 		FAC86E6B1724555D00EED715 /* Quad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC86E671724555D00EED715 /* Quad.cpp */; };
 		FAC86E6B1724555D00EED715 /* Quad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC86E671724555D00EED715 /* Quad.cpp */; };
 		FAC86E6C1724555D00EED715 /* Quad.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC86E681724555D00EED715 /* Quad.h */; };
 		FAC86E6C1724555D00EED715 /* Quad.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC86E681724555D00EED715 /* Quad.h */; };
+		FADD58DD18C30367005FC3BF /* FormatHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADD58DC18C30367005FC3BF /* FormatHandler.cpp */; };
 		FAE010DB170DDE99006F29D0 /* ddsinfo.h in Headers */ = {isa = PBXBuildFile; fileRef = FAE010D8170DDE99006F29D0 /* ddsinfo.h */; };
 		FAE010DB170DDE99006F29D0 /* ddsinfo.h in Headers */ = {isa = PBXBuildFile; fileRef = FAE010D8170DDE99006F29D0 /* ddsinfo.h */; };
 		FAE010DC170DDE99006F29D0 /* ddsparse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAE010D9170DDE99006F29D0 /* ddsparse.cpp */; };
 		FAE010DC170DDE99006F29D0 /* ddsparse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAE010D9170DDE99006F29D0 /* ddsparse.cpp */; };
 		FAE010DD170DDE99006F29D0 /* ddsparse.h in Headers */ = {isa = PBXBuildFile; fileRef = FAE010DA170DDE99006F29D0 /* ddsparse.h */; };
 		FAE010DD170DDE99006F29D0 /* ddsparse.h in Headers */ = {isa = PBXBuildFile; fileRef = FAE010DA170DDE99006F29D0 /* ddsparse.h */; };
@@ -298,6 +320,8 @@
 		FAE010E1170DE25E006F29D0 /* ddsHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FAE010DF170DE25E006F29D0 /* ddsHandler.h */; };
 		FAE010E1170DE25E006F29D0 /* ddsHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FAE010DF170DE25E006F29D0 /* ddsHandler.h */; };
 		FAE010E4170DF75C006F29D0 /* wrap_CompressedData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAE010E2170DF75B006F29D0 /* wrap_CompressedData.cpp */; };
 		FAE010E4170DF75C006F29D0 /* wrap_CompressedData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAE010E2170DF75B006F29D0 /* wrap_CompressedData.cpp */; };
 		FAE010E5170DF75C006F29D0 /* wrap_CompressedData.h in Headers */ = {isa = PBXBuildFile; fileRef = FAE010E3170DF75C006F29D0 /* wrap_CompressedData.h */; };
 		FAE010E5170DF75C006F29D0 /* wrap_CompressedData.h in Headers */ = {isa = PBXBuildFile; fileRef = FAE010E3170DF75C006F29D0 /* wrap_CompressedData.h */; };
+		FAE404401927F22C00814481 /* KTXHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAE4043E1927F22C00814481 /* KTXHandler.cpp */; };
+		FAE404411927F22C00814481 /* KTXHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FAE4043F1927F22C00814481 /* KTXHandler.h */; };
 		FAEC808A1710FEA60057279A /* ImageData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAEC80881710FEA60057279A /* ImageData.cpp */; };
 		FAEC808A1710FEA60057279A /* ImageData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAEC80881710FEA60057279A /* ImageData.cpp */; };
 		FAEC808B1710FEA60057279A /* ImageData.h in Headers */ = {isa = PBXBuildFile; fileRef = FAEC80891710FEA60057279A /* ImageData.h */; };
 		FAEC808B1710FEA60057279A /* ImageData.h in Headers */ = {isa = PBXBuildFile; fileRef = FAEC80891710FEA60057279A /* ImageData.h */; };
 		FAEC808E1711E76C0057279A /* CompressedData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAEC808C1711E76C0057279A /* CompressedData.cpp */; };
 		FAEC808E1711E76C0057279A /* CompressedData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAEC808C1711E76C0057279A /* CompressedData.cpp */; };
@@ -777,6 +801,23 @@
 		FA3D9E1416E6D41000CA6630 /* wrap_Cursor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Cursor.h; sourceTree = "<group>"; };
 		FA3D9E1416E6D41000CA6630 /* wrap_Cursor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Cursor.h; sourceTree = "<group>"; };
 		FA435EA117B36E9C004C3F22 /* Polyline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Polyline.cpp; sourceTree = "<group>"; };
 		FA435EA117B36E9C004C3F22 /* Polyline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Polyline.cpp; sourceTree = "<group>"; };
 		FA435EA217B36E9C004C3F22 /* Polyline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Polyline.h; sourceTree = "<group>"; };
 		FA435EA217B36E9C004C3F22 /* Polyline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Polyline.h; sourceTree = "<group>"; };
+		FA45F770187A0F3600D99ED8 /* Touch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Touch.cpp; sourceTree = "<group>"; };
+		FA45F771187A0F3600D99ED8 /* Touch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Touch.h; sourceTree = "<group>"; };
+		FA45F772187A0F3600D99ED8 /* Touch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Touch.h; sourceTree = "<group>"; };
+		FA45F773187A0F3600D99ED8 /* wrap_Touch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Touch.cpp; sourceTree = "<group>"; };
+		FA45F774187A0F3600D99ED8 /* wrap_Touch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Touch.h; sourceTree = "<group>"; };
+		FA4DAE651941410D009F0A3E /* PNGHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PNGHandler.cpp; sourceTree = "<group>"; };
+		FA4DAE661941410D009F0A3E /* PNGHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PNGHandler.h; sourceTree = "<group>"; };
+		FA4DAE671941410D009F0A3E /* STBHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = STBHandler.cpp; sourceTree = "<group>"; };
+		FA4DAE681941410D009F0A3E /* STBHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STBHandler.h; sourceTree = "<group>"; };
+		FA4DAE6E1941411D009F0A3E /* lodepng.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lodepng.cpp; sourceTree = "<group>"; };
+		FA4DAE6F1941411D009F0A3E /* lodepng.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lodepng.h; sourceTree = "<group>"; };
+		FA4DAE721941411D009F0A3E /* stb_image.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stb_image.h; sourceTree = "<group>"; };
+		FA4DAE771941419A009F0A3E /* JPEGHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JPEGHandler.cpp; sourceTree = "<group>"; };
+		FA4DAE781941419A009F0A3E /* JPEGHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JPEGHandler.h; sourceTree = "<group>"; };
+		FA4DAE7B19414281009F0A3E /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
+		FA52E444192AAADE0064D2FF /* PKMHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PKMHandler.cpp; sourceTree = "<group>"; };
+		FA52E445192AAADE0064D2FF /* PKMHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PKMHandler.h; sourceTree = "<group>"; };
 		FA5454C016F1310000D30303 /* MathModule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MathModule.cpp; sourceTree = "<group>"; };
 		FA5454C016F1310000D30303 /* MathModule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MathModule.cpp; sourceTree = "<group>"; };
 		FA5454C116F1310000D30303 /* MathModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MathModule.h; sourceTree = "<group>"; };
 		FA5454C116F1310000D30303 /* MathModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MathModule.h; sourceTree = "<group>"; };
 		FA577A6716C719D900860150 /* FreeType.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FreeType.framework; path = /Library/Frameworks/FreeType.framework; sourceTree = "<absolute>"; };
 		FA577A6716C719D900860150 /* FreeType.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FreeType.framework; path = /Library/Frameworks/FreeType.framework; sourceTree = "<absolute>"; };
@@ -817,6 +858,9 @@
 		FA5FDC761788D548002F0ED2 /* unix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = unix.c; sourceTree = "<group>"; };
 		FA5FDC761788D548002F0ED2 /* unix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = unix.c; sourceTree = "<group>"; };
 		FA5FDC771788D548002F0ED2 /* win32.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = win32.c; sourceTree = "<group>"; };
 		FA5FDC771788D548002F0ED2 /* win32.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = win32.c; sourceTree = "<group>"; };
 		FA5FDC781788D548002F0ED2 /* lua-enet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "lua-enet.h"; sourceTree = "<group>"; };
 		FA5FDC781788D548002F0ED2 /* lua-enet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "lua-enet.h"; sourceTree = "<group>"; };
+		FA61FD5B1926CFCE003AE9FB /* CompressedFormatHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CompressedFormatHandler.h; sourceTree = "<group>"; };
+		FA61FD5C1926CFCE003AE9FB /* PVRHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PVRHandler.cpp; sourceTree = "<group>"; };
+		FA61FD5D1926CFCE003AE9FB /* PVRHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PVRHandler.h; sourceTree = "<group>"; };
 		FA636D88171B70920065623F /* RandomGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RandomGenerator.cpp; sourceTree = "<group>"; };
 		FA636D88171B70920065623F /* RandomGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RandomGenerator.cpp; sourceTree = "<group>"; };
 		FA636D89171B70920065623F /* RandomGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RandomGenerator.h; sourceTree = "<group>"; };
 		FA636D89171B70920065623F /* RandomGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RandomGenerator.h; sourceTree = "<group>"; };
 		FA636D8C171B72A70065623F /* wrap_RandomGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_RandomGenerator.cpp; sourceTree = "<group>"; };
 		FA636D8C171B72A70065623F /* wrap_RandomGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_RandomGenerator.cpp; sourceTree = "<group>"; };
@@ -833,6 +877,7 @@
 		FA9B4A0716E1578300074F42 /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = /Library/Frameworks/SDL2.framework; sourceTree = "<absolute>"; };
 		FA9B4A0716E1578300074F42 /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = /Library/Frameworks/SDL2.framework; sourceTree = "<absolute>"; };
 		FA9FC0AE173D6E3E005027FF /* wrap_Window.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Window.cpp; sourceTree = "<group>"; };
 		FA9FC0AE173D6E3E005027FF /* wrap_Window.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Window.cpp; sourceTree = "<group>"; };
 		FA9FC0AF173D6E3E005027FF /* wrap_Window.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Window.h; sourceTree = "<group>"; };
 		FA9FC0AF173D6E3E005027FF /* wrap_Window.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Window.h; sourceTree = "<group>"; };
+		FAA627CD18E7E1560080752D /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; };
 		FAAC6B00170A373A008A61C5 /* CompressedData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CompressedData.cpp; sourceTree = "<group>"; };
 		FAAC6B00170A373A008A61C5 /* CompressedData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CompressedData.cpp; sourceTree = "<group>"; };
 		FAAC6B01170A373A008A61C5 /* CompressedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CompressedData.h; sourceTree = "<group>"; };
 		FAAC6B01170A373A008A61C5 /* CompressedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CompressedData.h; sourceTree = "<group>"; };
 		FAAFF04316CB11C700CCDE45 /* OpenAL-Soft.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = "OpenAL-Soft.framework"; path = "/Library/Frameworks/OpenAL-Soft.framework"; sourceTree = "<absolute>"; };
 		FAAFF04316CB11C700CCDE45 /* OpenAL-Soft.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = "OpenAL-Soft.framework"; path = "/Library/Frameworks/OpenAL-Soft.framework"; sourceTree = "<absolute>"; };
@@ -850,6 +895,7 @@
 		FAC86E621724552C00EED715 /* wrap_Quad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Quad.h; sourceTree = "<group>"; };
 		FAC86E621724552C00EED715 /* wrap_Quad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Quad.h; sourceTree = "<group>"; };
 		FAC86E671724555D00EED715 /* Quad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Quad.cpp; sourceTree = "<group>"; };
 		FAC86E671724555D00EED715 /* Quad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Quad.cpp; sourceTree = "<group>"; };
 		FAC86E681724555D00EED715 /* Quad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Quad.h; sourceTree = "<group>"; };
 		FAC86E681724555D00EED715 /* Quad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Quad.h; sourceTree = "<group>"; };
+		FADD58DC18C30367005FC3BF /* FormatHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FormatHandler.cpp; sourceTree = "<group>"; };
 		FAE010D8170DDE99006F29D0 /* ddsinfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ddsinfo.h; sourceTree = "<group>"; };
 		FAE010D8170DDE99006F29D0 /* ddsinfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ddsinfo.h; sourceTree = "<group>"; };
 		FAE010D9170DDE99006F29D0 /* ddsparse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ddsparse.cpp; sourceTree = "<group>"; };
 		FAE010D9170DDE99006F29D0 /* ddsparse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ddsparse.cpp; sourceTree = "<group>"; };
 		FAE010DA170DDE99006F29D0 /* ddsparse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ddsparse.h; sourceTree = "<group>"; };
 		FAE010DA170DDE99006F29D0 /* ddsparse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ddsparse.h; sourceTree = "<group>"; };
@@ -857,6 +903,8 @@
 		FAE010DF170DE25E006F29D0 /* ddsHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ddsHandler.h; sourceTree = "<group>"; };
 		FAE010DF170DE25E006F29D0 /* ddsHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ddsHandler.h; sourceTree = "<group>"; };
 		FAE010E2170DF75B006F29D0 /* wrap_CompressedData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_CompressedData.cpp; sourceTree = "<group>"; };
 		FAE010E2170DF75B006F29D0 /* wrap_CompressedData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_CompressedData.cpp; sourceTree = "<group>"; };
 		FAE010E3170DF75C006F29D0 /* wrap_CompressedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_CompressedData.h; sourceTree = "<group>"; };
 		FAE010E3170DF75C006F29D0 /* wrap_CompressedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_CompressedData.h; sourceTree = "<group>"; };
+		FAE4043E1927F22C00814481 /* KTXHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KTXHandler.cpp; sourceTree = "<group>"; };
+		FAE4043F1927F22C00814481 /* KTXHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KTXHandler.h; sourceTree = "<group>"; };
 		FAEC80881710FEA60057279A /* ImageData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageData.cpp; sourceTree = "<group>"; };
 		FAEC80881710FEA60057279A /* ImageData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageData.cpp; sourceTree = "<group>"; };
 		FAEC80891710FEA60057279A /* ImageData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageData.h; sourceTree = "<group>"; };
 		FAEC80891710FEA60057279A /* ImageData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageData.h; sourceTree = "<group>"; };
 		FAEC808C1711E76C0057279A /* CompressedData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CompressedData.cpp; sourceTree = "<group>"; };
 		FAEC808C1711E76C0057279A /* CompressedData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CompressedData.cpp; sourceTree = "<group>"; };
@@ -896,6 +944,8 @@
 			isa = PBXFrameworksBuildPhase;
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			buildActionMask = 2147483647;
 			files = (
 			files = (
+				FA4DAE7C19414281009F0A3E /* libz.dylib in Frameworks */,
+				FAA627CE18E7E1560080752D /* CoreServices.framework in Frameworks */,
 				FA9B4A0816E1578300074F42 /* SDL2.framework in Frameworks */,
 				FA9B4A0816E1578300074F42 /* SDL2.framework in Frameworks */,
 				FAAFF04416CB11C700CCDE45 /* OpenAL-Soft.framework in Frameworks */,
 				FAAFF04416CB11C700CCDE45 /* OpenAL-Soft.framework in Frameworks */,
 				FA577AB016C7507900860150 /* Cocoa.framework in Frameworks */,
 				FA577AB016C7507900860150 /* Cocoa.framework in Frameworks */,
@@ -1087,15 +1137,29 @@
 			children = (
 			children = (
 				FAEC808C1711E76C0057279A /* CompressedData.cpp */,
 				FAEC808C1711E76C0057279A /* CompressedData.cpp */,
 				FAEC808D1711E76C0057279A /* CompressedData.h */,
 				FAEC808D1711E76C0057279A /* CompressedData.h */,
+				FA61FD5B1926CFCE003AE9FB /* CompressedFormatHandler.h */,
 				FAE010DE170DE25E006F29D0 /* ddsHandler.cpp */,
 				FAE010DE170DE25E006F29D0 /* ddsHandler.cpp */,
 				FAE010DF170DE25E006F29D0 /* ddsHandler.h */,
 				FAE010DF170DE25E006F29D0 /* ddsHandler.h */,
 				1AA7781A230065F346E2313A /* DevilHandler.cpp */,
 				1AA7781A230065F346E2313A /* DevilHandler.cpp */,
 				283342E174613897621A43F1 /* DevilHandler.h */,
 				283342E174613897621A43F1 /* DevilHandler.h */,
+				FADD58DC18C30367005FC3BF /* FormatHandler.cpp */,
 				FA0CDE3B1710F9A50056E8D7 /* FormatHandler.h */,
 				FA0CDE3B1710F9A50056E8D7 /* FormatHandler.h */,
 				505F23A73BFE250833D650E4 /* Image.cpp */,
 				505F23A73BFE250833D650E4 /* Image.cpp */,
 				68616BD516DB124312B47EB3 /* Image.h */,
 				68616BD516DB124312B47EB3 /* Image.h */,
 				FAEC80881710FEA60057279A /* ImageData.cpp */,
 				FAEC80881710FEA60057279A /* ImageData.cpp */,
 				FAEC80891710FEA60057279A /* ImageData.h */,
 				FAEC80891710FEA60057279A /* ImageData.h */,
+				FA4DAE771941419A009F0A3E /* JPEGHandler.cpp */,
+				FA4DAE781941419A009F0A3E /* JPEGHandler.h */,
+				FAE4043E1927F22C00814481 /* KTXHandler.cpp */,
+				FAE4043F1927F22C00814481 /* KTXHandler.h */,
+				FA52E444192AAADE0064D2FF /* PKMHandler.cpp */,
+				FA52E445192AAADE0064D2FF /* PKMHandler.h */,
+				FA4DAE651941410D009F0A3E /* PNGHandler.cpp */,
+				FA4DAE661941410D009F0A3E /* PNGHandler.h */,
+				FA61FD5C1926CFCE003AE9FB /* PVRHandler.cpp */,
+				FA61FD5D1926CFCE003AE9FB /* PVRHandler.h */,
+				FA4DAE671941410D009F0A3E /* STBHandler.cpp */,
+				FA4DAE681941410D009F0A3E /* STBHandler.h */,
 			);
 			);
 			path = magpie;
 			path = magpie;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
@@ -1389,8 +1453,10 @@
 				FAE010D7170DDE99006F29D0 /* ddsparse */,
 				FAE010D7170DDE99006F29D0 /* ddsparse */,
 				FA5FDC5E1788D548002F0ED2 /* enet */,
 				FA5FDC5E1788D548002F0ED2 /* enet */,
 				FA9A1008182A0D5200106F9F /* glad */,
 				FA9A1008182A0D5200106F9F /* glad */,
+				FA4DAE6D1941411D009F0A3E /* lodepng */,
 				3AED1DE005A53DDB07902760 /* luasocket */,
 				3AED1DE005A53DDB07902760 /* luasocket */,
 				FA0354691731F3A700284828 /* noise1234 */,
 				FA0354691731F3A700284828 /* noise1234 */,
+				FA4DAE701941411D009F0A3E /* stb */,
 				36C14C81334735EC54E33637 /* utf8 */,
 				36C14C81334735EC54E33637 /* utf8 */,
 				FAF6704318184FF800DBDEEA /* Wuff */,
 				FAF6704318184FF800DBDEEA /* Wuff */,
 			);
 			);
@@ -1434,6 +1500,10 @@
 				FAB0078E1740C12D00A9664D /* Joystick.h */,
 				FAB0078E1740C12D00A9664D /* Joystick.h */,
 				4C606AEC342457600C3F0741 /* JoystickModule.h */,
 				4C606AEC342457600C3F0741 /* JoystickModule.h */,
 				687216AD6FA406C838284B91 /* sdl */,
 				687216AD6FA406C838284B91 /* sdl */,
+				FAB007951740C87D00A9664D /* wrap_Joystick.cpp */,
+				FAB007961740C87D00A9664D /* wrap_Joystick.h */,
+				139411436818381E493F00F5 /* wrap_JoystickModule.cpp */,
+				2D7B7DEC4FC87878332E41B3 /* wrap_JoystickModule.h */,
 			);
 			);
 			path = joystick;
 			path = joystick;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
@@ -1472,6 +1542,7 @@
 				FA34E7CA174B512200E04D3F /* system */,
 				FA34E7CA174B512200E04D3F /* system */,
 				02E0744773D13AD65E7C49DC /* thread */,
 				02E0744773D13AD65E7C49DC /* thread */,
 				6D590DDD41E72A60262E4A4F /* timer */,
 				6D590DDD41E72A60262E4A4F /* timer */,
+				FA45F76E187A0F3600D99ED8 /* touch */,
 				153D76205F7A4ACD12FB4C0E /* window */,
 				153D76205F7A4ACD12FB4C0E /* window */,
 			);
 			);
 			name = modules;
 			name = modules;
@@ -1552,12 +1623,6 @@
 				47D46915001F342A3CD23E86 /* File.h */,
 				47D46915001F342A3CD23E86 /* File.h */,
 				6DE3129F3A0B2D9C178118F3 /* Filesystem.cpp */,
 				6DE3129F3A0B2D9C178118F3 /* Filesystem.cpp */,
 				219636CF6780074F7871463D /* Filesystem.h */,
 				219636CF6780074F7871463D /* Filesystem.h */,
-				6C367AE309C453C412D91363 /* wrap_File.cpp */,
-				52E15B702C40593D3BF431DF /* wrap_File.h */,
-				597478A255B82B56488B4717 /* wrap_FileData.cpp */,
-				3512460642B046876D687B22 /* wrap_FileData.h */,
-				1E827AE8548C52493ED95629 /* wrap_Filesystem.cpp */,
-				5DC271240F0119AE16FA1B8E /* wrap_Filesystem.h */,
 			);
 			);
 			path = physfs;
 			path = physfs;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
@@ -1614,10 +1679,6 @@
 				FAB007921740C28900A9664D /* Joystick.h */,
 				FAB007921740C28900A9664D /* Joystick.h */,
 				55B425307C0C1C4B3EFC3A5F /* JoystickModule.cpp */,
 				55B425307C0C1C4B3EFC3A5F /* JoystickModule.cpp */,
 				439E46D768A266780E894800 /* JoystickModule.h */,
 				439E46D768A266780E894800 /* JoystickModule.h */,
-				FAB007951740C87D00A9664D /* wrap_Joystick.cpp */,
-				FAB007961740C87D00A9664D /* wrap_Joystick.h */,
-				139411436818381E493F00F5 /* wrap_JoystickModule.cpp */,
-				2D7B7DEC4FC87878332E41B3 /* wrap_JoystickModule.h */,
 			);
 			);
 			path = sdl;
 			path = sdl;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
@@ -1732,6 +1793,12 @@
 				62370A494F9D6E2D570065EB /* FileData.cpp */,
 				62370A494F9D6E2D570065EB /* FileData.cpp */,
 				54A13C2209F945671BC27974 /* FileData.h */,
 				54A13C2209F945671BC27974 /* FileData.h */,
 				64DD03B45BF6265723662DAF /* physfs */,
 				64DD03B45BF6265723662DAF /* physfs */,
+				6C367AE309C453C412D91363 /* wrap_File.cpp */,
+				52E15B702C40593D3BF431DF /* wrap_File.h */,
+				597478A255B82B56488B4717 /* wrap_FileData.cpp */,
+				3512460642B046876D687B22 /* wrap_FileData.h */,
+				1E827AE8548C52493ED95629 /* wrap_Filesystem.cpp */,
+				5DC271240F0119AE16FA1B8E /* wrap_Filesystem.h */,
 			);
 			);
 			path = filesystem;
 			path = filesystem;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
@@ -1826,11 +1893,49 @@
 			path = sdl;
 			path = sdl;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
 		};
 		};
+		FA45F76E187A0F3600D99ED8 /* touch */ = {
+			isa = PBXGroup;
+			children = (
+				FA45F76F187A0F3600D99ED8 /* sdl */,
+				FA45F772187A0F3600D99ED8 /* Touch.h */,
+				FA45F773187A0F3600D99ED8 /* wrap_Touch.cpp */,
+				FA45F774187A0F3600D99ED8 /* wrap_Touch.h */,
+			);
+			path = touch;
+			sourceTree = "<group>";
+		};
+		FA45F76F187A0F3600D99ED8 /* sdl */ = {
+			isa = PBXGroup;
+			children = (
+				FA45F770187A0F3600D99ED8 /* Touch.cpp */,
+				FA45F771187A0F3600D99ED8 /* Touch.h */,
+			);
+			path = sdl;
+			sourceTree = "<group>";
+		};
+		FA4DAE6D1941411D009F0A3E /* lodepng */ = {
+			isa = PBXGroup;
+			children = (
+				FA4DAE6E1941411D009F0A3E /* lodepng.cpp */,
+				FA4DAE6F1941411D009F0A3E /* lodepng.h */,
+			);
+			path = lodepng;
+			sourceTree = "<group>";
+		};
+		FA4DAE701941411D009F0A3E /* stb */ = {
+			isa = PBXGroup;
+			children = (
+				FA4DAE721941411D009F0A3E /* stb_image.h */,
+			);
+			path = stb;
+			sourceTree = "<group>";
+		};
 		FA577A6616C7199700860150 /* Frameworks */ = {
 		FA577A6616C7199700860150 /* Frameworks */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
-				FA9B4A0716E1578300074F42 /* SDL2.framework */,
+				FA4DAE7B19414281009F0A3E /* libz.dylib */,
 				FA577A7916C71A1700860150 /* Cocoa.framework */,
 				FA577A7916C71A1700860150 /* Cocoa.framework */,
+				FAA627CD18E7E1560080752D /* CoreServices.framework */,
 				FA577A6716C719D900860150 /* FreeType.framework */,
 				FA577A6716C719D900860150 /* FreeType.framework */,
 				FA577A6916C719DE00860150 /* IL.framework */,
 				FA577A6916C719DE00860150 /* IL.framework */,
 				FA577A8216C71A5300860150 /* libmodplug.framework */,
 				FA577A8216C71A5300860150 /* libmodplug.framework */,
@@ -1840,6 +1945,7 @@
 				FAAFF04316CB11C700CCDE45 /* OpenAL-Soft.framework */,
 				FAAFF04316CB11C700CCDE45 /* OpenAL-Soft.framework */,
 				FA577A7C16C71A2600860150 /* OpenGL.framework */,
 				FA577A7C16C71A2600860150 /* OpenGL.framework */,
 				FA577A7316C719F900860150 /* physfs.framework */,
 				FA577A7316C719F900860150 /* physfs.framework */,
+				FA9B4A0716E1578300074F42 /* SDL2.framework */,
 				FA577A7716C71A0800860150 /* Vorbis.framework */,
 				FA577A7716C71A0800860150 /* Vorbis.framework */,
 			);
 			);
 			name = Frameworks;
 			name = Frameworks;
@@ -1973,6 +2079,7 @@
 				FAF272A716E3D44400CC193A /* LuaThread.h in Headers */,
 				FAF272A716E3D44400CC193A /* LuaThread.h in Headers */,
 				FAF4377017F4AC530074F9E2 /* Mesh.h in Headers */,
 				FAF4377017F4AC530074F9E2 /* Mesh.h in Headers */,
 				FAF272A916E3D44400CC193A /* ThreadModule.h in Headers */,
 				FAF272A916E3D44400CC193A /* ThreadModule.h in Headers */,
+				FA4DAE6C1941410D009F0A3E /* STBHandler.h in Headers */,
 				FAF6705018184FF800DBDEEA /* wuff_convert.h in Headers */,
 				FAF6705018184FF800DBDEEA /* wuff_convert.h in Headers */,
 				FA9A100D182A0D5200106F9F /* glad.hpp in Headers */,
 				FA9A100D182A0D5200106F9F /* glad.hpp in Headers */,
 				FAF272AB16E3D44400CC193A /* wrap_Channel.h in Headers */,
 				FAF272AB16E3D44400CC193A /* wrap_Channel.h in Headers */,
@@ -1982,15 +2089,20 @@
 				FAF272B616E3D46400CC193A /* Thread.h in Headers */,
 				FAF272B616E3D46400CC193A /* Thread.h in Headers */,
 				FAF272B816E3D46400CC193A /* threads.h in Headers */,
 				FAF272B816E3D46400CC193A /* threads.h in Headers */,
 				FA5454C316F1310000D30303 /* MathModule.h in Headers */,
 				FA5454C316F1310000D30303 /* MathModule.h in Headers */,
+				FA4DAE7A1941419A009F0A3E /* JPEGHandler.h in Headers */,
 				FAAC6B03170A373B008A61C5 /* CompressedData.h in Headers */,
 				FAAC6B03170A373B008A61C5 /* CompressedData.h in Headers */,
 				FAE010DB170DDE99006F29D0 /* ddsinfo.h in Headers */,
 				FAE010DB170DDE99006F29D0 /* ddsinfo.h in Headers */,
 				FAE010DD170DDE99006F29D0 /* ddsparse.h in Headers */,
 				FAE010DD170DDE99006F29D0 /* ddsparse.h in Headers */,
 				FAE010E1170DE25E006F29D0 /* ddsHandler.h in Headers */,
 				FAE010E1170DE25E006F29D0 /* ddsHandler.h in Headers */,
 				FAE010E5170DF75C006F29D0 /* wrap_CompressedData.h in Headers */,
 				FAE010E5170DF75C006F29D0 /* wrap_CompressedData.h in Headers */,
+				FA4DAE761941411D009F0A3E /* stb_image.h in Headers */,
 				FAF6704E18184FF800DBDEEA /* wuff_config.h in Headers */,
 				FAF6704E18184FF800DBDEEA /* wuff_config.h in Headers */,
 				FA0CDE3D1710F9A50056E8D7 /* FormatHandler.h in Headers */,
 				FA0CDE3D1710F9A50056E8D7 /* FormatHandler.h in Headers */,
 				FA7AA59317F6AC1F00704BE2 /* wrap_Mesh.h in Headers */,
 				FA7AA59317F6AC1F00704BE2 /* wrap_Mesh.h in Headers */,
+				FA45F777187A0F3600D99ED8 /* Touch.h in Headers */,
+				FA45F779187A0F3600D99ED8 /* wrap_Touch.h in Headers */,
 				FA01BE1F1878E35B00640047 /* wrap_Texture.h in Headers */,
 				FA01BE1F1878E35B00640047 /* wrap_Texture.h in Headers */,
+				FAE404411927F22C00814481 /* KTXHandler.h in Headers */,
 				FAEC808B1710FEA60057279A /* ImageData.h in Headers */,
 				FAEC808B1710FEA60057279A /* ImageData.h in Headers */,
 				FAEC808F1711E76C0057279A /* CompressedData.h in Headers */,
 				FAEC808F1711E76C0057279A /* CompressedData.h in Headers */,
 				FA636D8B171B70920065623F /* RandomGenerator.h in Headers */,
 				FA636D8B171B70920065623F /* RandomGenerator.h in Headers */,
@@ -2003,10 +2115,13 @@
 				FA3D9E1616E6D41100CA6630 /* wrap_Cursor.h in Headers */,
 				FA3D9E1616E6D41100CA6630 /* wrap_Cursor.h in Headers */,
 				FA9A100E182A0D5200106F9F /* gladfuncs.hpp in Headers */,
 				FA9A100E182A0D5200106F9F /* gladfuncs.hpp in Headers */,
 				FA9FC0B1173D6E3E005027FF /* wrap_Window.h in Headers */,
 				FA9FC0B1173D6E3E005027FF /* wrap_Window.h in Headers */,
+				FA61FD5E1926CFCE003AE9FB /* CompressedFormatHandler.h in Headers */,
 				FAB007901740C12D00A9664D /* Joystick.h in Headers */,
 				FAB007901740C12D00A9664D /* Joystick.h in Headers */,
 				FAF6705218184FF800DBDEEA /* wuff_internal.h in Headers */,
 				FAF6705218184FF800DBDEEA /* wuff_internal.h in Headers */,
 				FAB007941740C28900A9664D /* Joystick.h in Headers */,
 				FAB007941740C28900A9664D /* Joystick.h in Headers */,
+				FA45F776187A0F3600D99ED8 /* Touch.h in Headers */,
 				FAB007981740C87D00A9664D /* wrap_Joystick.h in Headers */,
 				FAB007981740C87D00A9664D /* wrap_Joystick.h in Headers */,
+				FA52E447192AAADE0064D2FF /* PKMHandler.h in Headers */,
 				FA9B492A1875EFB900201DA9 /* Texture.h in Headers */,
 				FA9B492A1875EFB900201DA9 /* Texture.h in Headers */,
 				FAC5710117402D1100D147E4 /* BezierCurve.h in Headers */,
 				FAC5710117402D1100D147E4 /* BezierCurve.h in Headers */,
 				FAC5710317402D1100D147E4 /* wrap_BezierCurve.h in Headers */,
 				FAC5710317402D1100D147E4 /* wrap_BezierCurve.h in Headers */,
@@ -2021,13 +2136,16 @@
 				FA0A4BF1182E0C2800E1E4D2 /* b2MotorJoint.h in Headers */,
 				FA0A4BF1182E0C2800E1E4D2 /* b2MotorJoint.h in Headers */,
 				FA5FDC851788D548002F0ED2 /* utility.h in Headers */,
 				FA5FDC851788D548002F0ED2 /* utility.h in Headers */,
 				FAF6704D18184FF800DBDEEA /* wuff.h in Headers */,
 				FAF6704D18184FF800DBDEEA /* wuff.h in Headers */,
+				FA4DAE6A1941410D009F0A3E /* PNGHandler.h in Headers */,
 				FA5FDC861788D548002F0ED2 /* win32.h in Headers */,
 				FA5FDC861788D548002F0ED2 /* win32.h in Headers */,
 				FA5FDC8F1788D548002F0ED2 /* lua-enet.h in Headers */,
 				FA5FDC8F1788D548002F0ED2 /* lua-enet.h in Headers */,
+				FA4DAE741941411D009F0A3E /* lodepng.h in Headers */,
 				FA7175AA178E8418001FE7FE /* lua.h in Headers */,
 				FA7175AA178E8418001FE7FE /* lua.h in Headers */,
 				FA34E7CE174B513F00E04D3F /* System.h in Headers */,
 				FA34E7CE174B513F00E04D3F /* System.h in Headers */,
 				FA34E7D3174B515D00E04D3F /* System.h in Headers */,
 				FA34E7D3174B515D00E04D3F /* System.h in Headers */,
 				FAF670571818501300DBDEEA /* WaveDecoder.h in Headers */,
 				FAF670571818501300DBDEEA /* WaveDecoder.h in Headers */,
 				FA1EF7C51799FEB200FF380C /* wrap_System.h in Headers */,
 				FA1EF7C51799FEB200FF380C /* wrap_System.h in Headers */,
+				FA61FD601926CFCE003AE9FB /* PVRHandler.h in Headers */,
 				FA435EA417B36E9C004C3F22 /* Polyline.h in Headers */,
 				FA435EA417B36E9C004C3F22 /* Polyline.h in Headers */,
 			);
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			runOnlyForDeploymentPostprocessing = 0;
@@ -2059,7 +2177,7 @@
 		08FB7793FE84155DC02AAC07 /* Project object */ = {
 		08FB7793FE84155DC02AAC07 /* Project object */ = {
 			isa = PBXProject;
 			isa = PBXProject;
 			attributes = {
 			attributes = {
-				LastUpgradeCheck = 0500;
+				LastUpgradeCheck = 0510;
 			};
 			};
 			buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "love-framework" */;
 			buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "love-framework" */;
 			compatibilityVersion = "Xcode 3.2";
 			compatibilityVersion = "Xcode 3.2";
@@ -2100,6 +2218,7 @@
 				FA08F5B516C7530100F007B5 /* Source.cpp in Sources */,
 				FA08F5B516C7530100F007B5 /* Source.cpp in Sources */,
 				FAF6705118184FF800DBDEEA /* wuff_internal.c in Sources */,
 				FAF6705118184FF800DBDEEA /* wuff_internal.c in Sources */,
 				FA08F5B616C7530A00F007B5 /* Audio.cpp in Sources */,
 				FA08F5B616C7530A00F007B5 /* Audio.cpp in Sources */,
+				FA4DAE791941419A009F0A3E /* JPEGHandler.cpp in Sources */,
 				FA08F5B716C7530A00F007B5 /* Pool.cpp in Sources */,
 				FA08F5B716C7530A00F007B5 /* Pool.cpp in Sources */,
 				FA08F5B816C7530A00F007B5 /* Source.cpp in Sources */,
 				FA08F5B816C7530A00F007B5 /* Source.cpp in Sources */,
 				FA08F5B916C7532A00F007B5 /* b64.cpp in Sources */,
 				FA08F5B916C7532A00F007B5 /* b64.cpp in Sources */,
@@ -2124,6 +2243,7 @@
 				FA08F5CC16C7533C00F007B5 /* b2Distance.cpp in Sources */,
 				FA08F5CC16C7533C00F007B5 /* b2Distance.cpp in Sources */,
 				FA08F5CD16C7533C00F007B5 /* b2DynamicTree.cpp in Sources */,
 				FA08F5CD16C7533C00F007B5 /* b2DynamicTree.cpp in Sources */,
 				FA08F5CE16C7533C00F007B5 /* b2TimeOfImpact.cpp in Sources */,
 				FA08F5CE16C7533C00F007B5 /* b2TimeOfImpact.cpp in Sources */,
+				FA61FD5F1926CFCE003AE9FB /* PVRHandler.cpp in Sources */,
 				FA08F5CF16C7534400F007B5 /* b2ChainShape.cpp in Sources */,
 				FA08F5CF16C7534400F007B5 /* b2ChainShape.cpp in Sources */,
 				FA08F5D016C7534400F007B5 /* b2CircleShape.cpp in Sources */,
 				FA08F5D016C7534400F007B5 /* b2CircleShape.cpp in Sources */,
 				FA08F5D116C7534400F007B5 /* b2EdgeShape.cpp in Sources */,
 				FA08F5D116C7534400F007B5 /* b2EdgeShape.cpp in Sources */,
@@ -2161,6 +2281,7 @@
 				FA08F5EF16C7538F00F007B5 /* b2RevoluteJoint.cpp in Sources */,
 				FA08F5EF16C7538F00F007B5 /* b2RevoluteJoint.cpp in Sources */,
 				FA08F5F016C7538F00F007B5 /* b2RopeJoint.cpp in Sources */,
 				FA08F5F016C7538F00F007B5 /* b2RopeJoint.cpp in Sources */,
 				FA08F5F116C7538F00F007B5 /* b2WeldJoint.cpp in Sources */,
 				FA08F5F116C7538F00F007B5 /* b2WeldJoint.cpp in Sources */,
+				FA45F775187A0F3600D99ED8 /* Touch.cpp in Sources */,
 				FA08F5F216C7538F00F007B5 /* b2WheelJoint.cpp in Sources */,
 				FA08F5F216C7538F00F007B5 /* b2WheelJoint.cpp in Sources */,
 				FA08F5F316C7539B00F007B5 /* b2Rope.cpp in Sources */,
 				FA08F5F316C7539B00F007B5 /* b2Rope.cpp in Sources */,
 				FA08F5F416C753A400F007B5 /* luasocket.cpp in Sources */,
 				FA08F5F416C753A400F007B5 /* luasocket.cpp in Sources */,
@@ -2198,6 +2319,7 @@
 				FA08F61316C753E700F007B5 /* wrap_GlyphData.cpp in Sources */,
 				FA08F61316C753E700F007B5 /* wrap_GlyphData.cpp in Sources */,
 				FA08F61416C753E700F007B5 /* wrap_Rasterizer.cpp in Sources */,
 				FA08F61416C753E700F007B5 /* wrap_Rasterizer.cpp in Sources */,
 				FA08F61716C753F600F007B5 /* Graphics.cpp in Sources */,
 				FA08F61716C753F600F007B5 /* Graphics.cpp in Sources */,
+				FA45F778187A0F3600D99ED8 /* wrap_Touch.cpp in Sources */,
 				FA08F61816C753F600F007B5 /* Texture.cpp in Sources */,
 				FA08F61816C753F600F007B5 /* Texture.cpp in Sources */,
 				FA08F61A16C753F600F007B5 /* Volatile.cpp in Sources */,
 				FA08F61A16C753F600F007B5 /* Volatile.cpp in Sources */,
 				FA08F61B16C7541400F007B5 /* Canvas.cpp in Sources */,
 				FA08F61B16C7541400F007B5 /* Canvas.cpp in Sources */,
@@ -2211,6 +2333,7 @@
 				FA08F62416C7541400F007B5 /* SpriteBatch.cpp in Sources */,
 				FA08F62416C7541400F007B5 /* SpriteBatch.cpp in Sources */,
 				FA08F62516C7541400F007B5 /* VertexBuffer.cpp in Sources */,
 				FA08F62516C7541400F007B5 /* VertexBuffer.cpp in Sources */,
 				FA08F62616C7541400F007B5 /* wrap_Canvas.cpp in Sources */,
 				FA08F62616C7541400F007B5 /* wrap_Canvas.cpp in Sources */,
+				FAE404401927F22C00814481 /* KTXHandler.cpp in Sources */,
 				FA08F62716C7541400F007B5 /* wrap_Font.cpp in Sources */,
 				FA08F62716C7541400F007B5 /* wrap_Font.cpp in Sources */,
 				FA08F62816C7541400F007B5 /* wrap_Graphics.cpp in Sources */,
 				FA08F62816C7541400F007B5 /* wrap_Graphics.cpp in Sources */,
 				FA08F62916C7541400F007B5 /* wrap_Image.cpp in Sources */,
 				FA08F62916C7541400F007B5 /* wrap_Image.cpp in Sources */,
@@ -2280,6 +2403,7 @@
 				FA08F66816C7548200F007B5 /* wrap_WheelJoint.cpp in Sources */,
 				FA08F66816C7548200F007B5 /* wrap_WheelJoint.cpp in Sources */,
 				FA08F66916C7548200F007B5 /* wrap_World.cpp in Sources */,
 				FA08F66916C7548200F007B5 /* wrap_World.cpp in Sources */,
 				FA08F66A16C7549200F007B5 /* Sound.cpp in Sources */,
 				FA08F66A16C7549200F007B5 /* Sound.cpp in Sources */,
+				FADD58DD18C30367005FC3BF /* FormatHandler.cpp in Sources */,
 				FA08F66B16C7549200F007B5 /* SoundData.cpp in Sources */,
 				FA08F66B16C7549200F007B5 /* SoundData.cpp in Sources */,
 				FA08F66C16C7549200F007B5 /* wrap_Decoder.cpp in Sources */,
 				FA08F66C16C7549200F007B5 /* wrap_Decoder.cpp in Sources */,
 				FA08F66D16C7549200F007B5 /* wrap_Sound.cpp in Sources */,
 				FA08F66D16C7549200F007B5 /* wrap_Sound.cpp in Sources */,
@@ -2291,6 +2415,7 @@
 				FA08F67316C754A100F007B5 /* Mpg123Decoder.cpp in Sources */,
 				FA08F67316C754A100F007B5 /* Mpg123Decoder.cpp in Sources */,
 				FA08F67416C754A100F007B5 /* Sound.cpp in Sources */,
 				FA08F67416C754A100F007B5 /* Sound.cpp in Sources */,
 				FA08F67516C754A100F007B5 /* VorbisDecoder.cpp in Sources */,
 				FA08F67516C754A100F007B5 /* VorbisDecoder.cpp in Sources */,
+				FA4DAE691941410D009F0A3E /* PNGHandler.cpp in Sources */,
 				FA08F67716C754A900F007B5 /* threads.cpp in Sources */,
 				FA08F67716C754A900F007B5 /* threads.cpp in Sources */,
 				FA08F67916C754B100F007B5 /* Timer.cpp in Sources */,
 				FA08F67916C754B100F007B5 /* Timer.cpp in Sources */,
 				FA08F67A16C754B100F007B5 /* wrap_Timer.cpp in Sources */,
 				FA08F67A16C754B100F007B5 /* wrap_Timer.cpp in Sources */,
@@ -2300,7 +2425,10 @@
 				FAF272A416E3D44400CC193A /* Channel.cpp in Sources */,
 				FAF272A416E3D44400CC193A /* Channel.cpp in Sources */,
 				FAF272A616E3D44400CC193A /* LuaThread.cpp in Sources */,
 				FAF272A616E3D44400CC193A /* LuaThread.cpp in Sources */,
 				FA0A4BF0182E0C2800E1E4D2 /* b2MotorJoint.cpp in Sources */,
 				FA0A4BF0182E0C2800E1E4D2 /* b2MotorJoint.cpp in Sources */,
+				FA4DAE6B1941410D009F0A3E /* STBHandler.cpp in Sources */,
 				FAF272A816E3D44400CC193A /* ThreadModule.cpp in Sources */,
 				FAF272A816E3D44400CC193A /* ThreadModule.cpp in Sources */,
+				FA52E446192AAADE0064D2FF /* PKMHandler.cpp in Sources */,
+				FA4DAE731941411D009F0A3E /* lodepng.cpp in Sources */,
 				FA01BE1E1878E35B00640047 /* wrap_Texture.cpp in Sources */,
 				FA01BE1E1878E35B00640047 /* wrap_Texture.cpp in Sources */,
 				FAF272AA16E3D44400CC193A /* wrap_Channel.cpp in Sources */,
 				FAF272AA16E3D44400CC193A /* wrap_Channel.cpp in Sources */,
 				FAF272AC16E3D44400CC193A /* wrap_LuaThread.cpp in Sources */,
 				FAF272AC16E3D44400CC193A /* wrap_LuaThread.cpp in Sources */,
@@ -2355,11 +2483,16 @@
 				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
 				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
 				CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
 				CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
 				CLANG_ENABLE_MODULES = YES;
 				CLANG_ENABLE_MODULES = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
 				DEAD_CODE_STRIPPING = YES;
 				DEAD_CODE_STRIPPING = YES;
 				FRAMEWORK_SEARCH_PATHS = /Library/Frameworks;
 				FRAMEWORK_SEARCH_PATHS = /Library/Frameworks;
 				GCC_OPTIMIZATION_LEVEL = 3;
 				GCC_OPTIMIZATION_LEVEL = 3;
 				GCC_PREPROCESSOR_DEFINITIONS = LOVE_MACOSX_USE_FRAMEWORKS;
 				GCC_PREPROCESSOR_DEFINITIONS = LOVE_MACOSX_USE_FRAMEWORKS;
 				GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
 				GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
+				GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
 				GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
 				GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
 				GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES;
 				GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES;
@@ -2391,11 +2524,16 @@
 				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
 				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
 				CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
 				CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
 				CLANG_ENABLE_MODULES = YES;
 				CLANG_ENABLE_MODULES = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
 				COPY_PHASE_STRIP = NO;
 				COPY_PHASE_STRIP = NO;
 				FRAMEWORK_SEARCH_PATHS = /Library/Frameworks;
 				FRAMEWORK_SEARCH_PATHS = /Library/Frameworks;
 				GCC_OPTIMIZATION_LEVEL = 0;
 				GCC_OPTIMIZATION_LEVEL = 0;
 				GCC_PREPROCESSOR_DEFINITIONS = LOVE_MACOSX_USE_FRAMEWORKS;
 				GCC_PREPROCESSOR_DEFINITIONS = LOVE_MACOSX_USE_FRAMEWORKS;
 				GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
 				GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
+				GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
 				GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
 				GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
 				GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES;
 				GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES;
@@ -2421,6 +2559,71 @@
 			};
 			};
 			name = Debug;
 			name = Debug;
 		};
 		};
+		FA5326C4189719C700F7BBF4 /* Distribution */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
+				CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				DEAD_CODE_STRIPPING = YES;
+				FRAMEWORK_SEARCH_PATHS = /Library/Frameworks;
+				GCC_OPTIMIZATION_LEVEL = 3;
+				GCC_PREPROCESSOR_DEFINITIONS = LOVE_MACOSX_USE_FRAMEWORKS;
+				GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
+				GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
+				GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES;
+				GCC_WARN_SIGN_COMPARE = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES;
+				GCC_WARN_UNUSED_PARAMETER = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				HEADER_SEARCH_PATHS = (
+					"\"$(SRCROOT)/../../src\"",
+					"\"$(SRCROOT)/../../src/libraries\"",
+					"\"$(SRCROOT)/../../src/modules\"",
+					"\"$(SRCROOT)/../../src/libraries/enet/libenet/include\"",
+					/Library/Frameworks/FreeType.framework/Headers,
+					/Library/Frameworks/Lua.framework/Headers,
+					/Library/Frameworks/SDL2.framework/Headers,
+				);
+				LD_RUNPATH_SEARCH_PATHS = "@rpath";
+				LIBRARY_SEARCH_PATHS = "";
+				LLVM_LTO = YES;
+				MACOSX_DEPLOYMENT_TARGET = 10.6;
+				ONLY_ACTIVE_ARCH = NO;
+				USE_HEADERMAP = NO;
+				WARNING_CFLAGS = "-Wall";
+			};
+			name = Distribution;
+		};
+		FA5326C5189719C700F7BBF4 /* Distribution */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_ENABLE_MODULES = NO;
+				COMBINE_HIDPI_IMAGES = YES;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				DYLIB_COMPATIBILITY_VERSION = 9.0;
+				DYLIB_CURRENT_VERSION = 9.0;
+				FRAMEWORK_VERSION = A;
+				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+				INFOPLIST_FILE = "Info-Framework.plist";
+				LD_DYLIB_INSTALL_NAME = "@rpath/$(EXECUTABLE_PATH)";
+				OTHER_LDFLAGS = (
+					"-undefined",
+					dynamic_lookup,
+				);
+				PRODUCT_NAME = love;
+				SKIP_INSTALL = YES;
+				WRAPPER_EXTENSION = framework;
+			};
+			name = Distribution;
+		};
 		FA577AC016C7507900860150 /* Debug */ = {
 		FA577AC016C7507900860150 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			isa = XCBuildConfiguration;
 			buildSettings = {
 			buildSettings = {
@@ -2478,6 +2681,7 @@
 			buildConfigurations = (
 			buildConfigurations = (
 				64274E785071353E1A1D0D4B /* Debug */,
 				64274E785071353E1A1D0D4B /* Debug */,
 				10D5479E63C26BB35EB5482E /* Release */,
 				10D5479E63C26BB35EB5482E /* Release */,
+				FA5326C4189719C700F7BBF4 /* Distribution */,
 			);
 			);
 			defaultConfigurationIsVisible = 0;
 			defaultConfigurationIsVisible = 0;
 			defaultConfigurationName = Debug;
 			defaultConfigurationName = Debug;
@@ -2487,6 +2691,7 @@
 			buildConfigurations = (
 			buildConfigurations = (
 				FA577AC016C7507900860150 /* Debug */,
 				FA577AC016C7507900860150 /* Debug */,
 				FA577AC116C7507900860150 /* Release */,
 				FA577AC116C7507900860150 /* Release */,
+				FA5326C5189719C700F7BBF4 /* Distribution */,
 			);
 			);
 			defaultConfigurationIsVisible = 0;
 			defaultConfigurationIsVisible = 0;
 			defaultConfigurationName = Debug;
 			defaultConfigurationName = Debug;

+ 80 - 1
jni/love/platform/macosx/love.xcodeproj/project.pbxproj

@@ -25,6 +25,7 @@
 		FA9B4A0A16E1579F00074F42 /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA9B4A0916E1579F00074F42 /* SDL2.framework */; };
 		FA9B4A0A16E1579F00074F42 /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA9B4A0916E1579F00074F42 /* SDL2.framework */; };
 		FA9B4A0B16E157B500074F42 /* SDL2.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = FA9B4A0916E1579F00074F42 /* SDL2.framework */; };
 		FA9B4A0B16E157B500074F42 /* SDL2.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = FA9B4A0916E1579F00074F42 /* SDL2.framework */; };
 		FAAFF04716CB120000CCDE45 /* OpenAL-Soft.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = FAAFF04616CB120000CCDE45 /* OpenAL-Soft.framework */; };
 		FAAFF04716CB120000CCDE45 /* OpenAL-Soft.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = FAAFF04616CB120000CCDE45 /* OpenAL-Soft.framework */; };
+		FAC1A449196F5DC600125284 /* license.txt in Resources */ = {isa = PBXBuildFile; fileRef = FAC1A448196F5DC600125284 /* license.txt */; };
 		FAC8E8D416F3C468004DADF3 /* OSX.mm in Sources */ = {isa = PBXBuildFile; fileRef = FAC8E8D316F3C468004DADF3 /* OSX.mm */; };
 		FAC8E8D416F3C468004DADF3 /* OSX.mm in Sources */ = {isa = PBXBuildFile; fileRef = FAC8E8D316F3C468004DADF3 /* OSX.mm */; };
 /* End PBXBuildFile section */
 /* End PBXBuildFile section */
 
 
@@ -82,6 +83,7 @@
 		FA577A9316C7217800860150 /* love-framework.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = "love-framework.xcodeproj"; sourceTree = "<group>"; };
 		FA577A9316C7217800860150 /* love-framework.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = "love-framework.xcodeproj"; sourceTree = "<group>"; };
 		FA9B4A0916E1579F00074F42 /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = /Library/Frameworks/SDL2.framework; sourceTree = "<absolute>"; };
 		FA9B4A0916E1579F00074F42 /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = /Library/Frameworks/SDL2.framework; sourceTree = "<absolute>"; };
 		FAAFF04616CB120000CCDE45 /* OpenAL-Soft.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = "OpenAL-Soft.framework"; path = "/Library/Frameworks/OpenAL-Soft.framework"; sourceTree = "<absolute>"; };
 		FAAFF04616CB120000CCDE45 /* OpenAL-Soft.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = "OpenAL-Soft.framework"; path = "/Library/Frameworks/OpenAL-Soft.framework"; sourceTree = "<absolute>"; };
+		FAC1A448196F5DC600125284 /* license.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = license.txt; path = ../../license.txt; sourceTree = "<group>"; };
 		FAC8E8D316F3C468004DADF3 /* OSX.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OSX.mm; sourceTree = "<group>"; };
 		FAC8E8D316F3C468004DADF3 /* OSX.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OSX.mm; sourceTree = "<group>"; };
 		FAC8E8D616F3C46E004DADF3 /* OSX.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OSX.h; sourceTree = "<group>"; };
 		FAC8E8D616F3C46E004DADF3 /* OSX.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OSX.h; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 /* End PBXFileReference section */
@@ -145,6 +147,7 @@
 		29B97317FDCFA39411CA2CEA /* Resources */ = {
 		29B97317FDCFA39411CA2CEA /* Resources */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
+				FAC1A448196F5DC600125284 /* license.txt */,
 				A97E3842132A9EDE00198A2F /* love-Info.plist */,
 				A97E3842132A9EDE00198A2F /* love-Info.plist */,
 				A9DEC1BF1046EFA60049C70C /* Love.icns */,
 				A9DEC1BF1046EFA60049C70C /* Love.icns */,
 				A9DEC1C01046EFA70049C70C /* LoveDocument.icns */,
 				A9DEC1C01046EFA70049C70C /* LoveDocument.icns */,
@@ -198,7 +201,7 @@
 		29B97313FDCFA39411CA2CEA /* Project object */ = {
 		29B97313FDCFA39411CA2CEA /* Project object */ = {
 			isa = PBXProject;
 			isa = PBXProject;
 			attributes = {
 			attributes = {
-				LastUpgradeCheck = 0500;
+				LastUpgradeCheck = 0510;
 			};
 			};
 			buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "love" */;
 			buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "love" */;
 			compatibilityVersion = "Xcode 3.2";
 			compatibilityVersion = "Xcode 3.2";
@@ -240,6 +243,7 @@
 			isa = PBXResourcesBuildPhase;
 			isa = PBXResourcesBuildPhase;
 			buildActionMask = 2147483647;
 			buildActionMask = 2147483647;
 			files = (
 			files = (
+				FAC1A449196F5DC600125284 /* license.txt in Resources */,
 				A9DEC1C11046EFA70049C70C /* Love.icns in Resources */,
 				A9DEC1C11046EFA70049C70C /* Love.icns in Resources */,
 				A9DEC1C21046EFA70049C70C /* LoveDocument.icns in Resources */,
 				A9DEC1C21046EFA70049C70C /* LoveDocument.icns in Resources */,
 			);
 			);
@@ -402,6 +406,79 @@
 			};
 			};
 			name = Release;
 			name = Release;
 		};
 		};
+		FA5326C618971A0900F7BBF4 /* Distribution */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
+				CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
+				CLANG_ENABLE_MODULES = YES;
+				DEPLOYMENT_POSTPROCESSING = NO;
+				FRAMEWORK_SEARCH_PATHS = /Library/Frameworks;
+				GCC_INPUT_FILETYPE = automatic;
+				GCC_OPTIMIZATION_LEVEL = 3;
+				GCC_PREPROCESSOR_DEFINITIONS = LOVE_MACOSX_USE_FRAMEWORKS;
+				GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = NO;
+				GCC_WARN_ABOUT_MISSING_NEWLINE = NO;
+				GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
+				GCC_WARN_ABOUT_POINTER_SIGNEDNESS = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = NO;
+				GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
+				GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO;
+				GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = NO;
+				GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = NO;
+				GCC_WARN_MISSING_PARENTHESES = NO;
+				GCC_WARN_NON_VIRTUAL_DESTRUCTOR = NO;
+				GCC_WARN_PEDANTIC = NO;
+				GCC_WARN_SHADOW = NO;
+				GCC_WARN_SIGN_COMPARE = YES;
+				GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO;
+				GCC_WARN_UNUSED_PARAMETER = NO;
+				GCC_WARN_UNUSED_VALUE = NO;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				HEADER_SEARCH_PATHS = (
+					"\"$(SRCROOT)/../../src\"",
+					"\"$(SRCROOT)/../../src/libraries\"",
+					"\"$(SRCROOT)/../../src/modules\"",
+					/Library/Frameworks/Lua.framework/Headers,
+					/Library/Frameworks/SDL2.framework/Headers,
+				);
+				INFOPLIST_FILE = "love-Info.plist";
+				LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks";
+				LLVM_LTO = YES;
+				MACOSX_DEPLOYMENT_TARGET = 10.6;
+				ONLY_ACTIVE_ARCH = NO;
+				OTHER_LDFLAGS = "";
+				"OTHER_LDFLAGS[arch=x86_64]" = (
+					"-pagezero_size",
+					10000,
+					"-image_base",
+					100000000,
+				);
+				PRODUCT_NAME = love;
+				SCAN_ALL_SOURCE_FILES_FOR_INCLUDES = YES;
+				WARNING_CFLAGS = (
+					"-Wall",
+					"-W",
+				);
+			};
+			name = Distribution;
+		};
+		FA5326C718971A0900F7BBF4 /* Distribution */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				COMBINE_HIDPI_IMAGES = YES;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"\"$(SRCROOT)/build/Release\"",
+					"\"$(SRCROOT)/build/Debug\"",
+				);
+				INSTALL_PATH = /Applications;
+				PRODUCT_NAME = love;
+			};
+			name = Distribution;
+		};
 /* End XCBuildConfiguration section */
 /* End XCBuildConfiguration section */
 
 
 /* Begin XCConfigurationList section */
 /* Begin XCConfigurationList section */
@@ -410,6 +487,7 @@
 			buildConfigurations = (
 			buildConfigurations = (
 				C01FCF4B08A954540054247B /* Debug */,
 				C01FCF4B08A954540054247B /* Debug */,
 				C01FCF4C08A954540054247B /* Release */,
 				C01FCF4C08A954540054247B /* Release */,
+				FA5326C718971A0900F7BBF4 /* Distribution */,
 			);
 			);
 			defaultConfigurationIsVisible = 0;
 			defaultConfigurationIsVisible = 0;
 			defaultConfigurationName = Release;
 			defaultConfigurationName = Release;
@@ -419,6 +497,7 @@
 			buildConfigurations = (
 			buildConfigurations = (
 				C01FCF4F08A954540054247B /* Debug */,
 				C01FCF4F08A954540054247B /* Debug */,
 				C01FCF5008A954540054247B /* Release */,
 				C01FCF5008A954540054247B /* Release */,
+				FA5326C618971A0900F7BBF4 /* Distribution */,
 			);
 			);
 			defaultConfigurationIsVisible = 0;
 			defaultConfigurationIsVisible = 0;
 			defaultConfigurationName = Release;
 			defaultConfigurationName = Release;

+ 2 - 2
jni/love/platform/unix/configure.ac

@@ -63,7 +63,7 @@ PKG_CHECK_MODULES([vorbisfile], [vorbisfile], [], [LOVE_MSG_ERROR([libvorbis and
 # Other libraries
 # Other libraries
 AC_SEARCH_LIBS([sqrt], [m], [], [LOVE_MSG_ERROR([the C math library])])
 AC_SEARCH_LIBS([sqrt], [m], [], [LOVE_MSG_ERROR([the C math library])])
 AC_SEARCH_LIBS([PHYSFS_init], [physfs], [], [LOVE_MSG_ERROR([PhysicsFS])])
 AC_SEARCH_LIBS([PHYSFS_init], [physfs], [], [LOVE_MSG_ERROR([PhysicsFS])])
-AC_SEARCH_LIBS([glLoadIdentity], [GL], [], [LOVE_MSG_ERROR([OpenGL])])
+AC_SEARCH_LIBS([glViewport], [GLESv2], [], [LOVE_MSG_ERROR([OpenGL])])
 
 
 # Lua, treated seperately because of --with-lua
 # Lua, treated seperately because of --with-lua
 AS_VAR_IF([with_luaversion], [5.2], [luatest=lua_version], [luatest=lua_pcall]) # use lua_version for 5.2
 AS_VAR_IF([with_luaversion], [5.2], [luatest=lua_version], [luatest=lua_pcall]) # use lua_version for 5.2
@@ -118,7 +118,7 @@ AS_VAR_IF([enable_exe], [no], [], #else
 	  AC_DEFINE([LOVE_BUILD_EXE], [], [Skip building launcher]))
 	  AC_DEFINE([LOVE_BUILD_EXE], [], [Skip building launcher]))
 
 
 AM_CONDITIONAL([LOVE_BUILD_EXE], [test "x$enable_exe" != xno])
 AM_CONDITIONAL([LOVE_BUILD_EXE], [test "x$enable_exe" != xno])
-AM_CONDITIONAL([LOVE_NOMPG123], [test "x$enable_mpg123" == xno])
+AM_CONDITIONAL([LOVE_NOMPG123], [test "x$enable_mpg123" = xno])
 AM_CONDITIONAL([LOVE_TARGET_OSX], [test "x$enable_osx" != xno])
 AM_CONDITIONAL([LOVE_TARGET_OSX], [test "x$enable_osx" != xno])
 
 
 # Automatic script file rebuilding
 # Automatic script file rebuilding

+ 1 - 1
jni/love/platform/unix/debian/control.in

@@ -33,7 +33,7 @@ Depends: ${misc:Depends},
          libgl1-mesa-glx,
          libgl1-mesa-glx,
          libluajit-5.1-2,
          libluajit-5.1-2,
          libphysfs-1.0-0,
          libphysfs-1.0-0,
-         libsdl2 (>= 2.0.0),
+         libsdl2-2.0-0 (>= 2.0.0),
          libopenal1,
          libopenal1,
          libogg0,
          libogg0,
          libvorbis0a,
          libvorbis0a,

+ 5 - 0
jni/love/platform/unix/debian/love.install

@@ -1 +1,6 @@
 usr/bin/love
 usr/bin/love
+usr/share/man/man1/love.1
+usr/share/pixmaps/love.svg
+usr/share/mime/packages/love.xml
+usr/share/icons/hicolor/scalable/mimetypes/application-x-love-game.svg
+usr/share/applications/love.desktop

+ 9 - 7
jni/love/platform/unix/genmodules

@@ -16,7 +16,7 @@ implfind()
 
 
 sourcefind()
 sourcefind()
 {
 {
-	find "$1" $2 -type f \( -iname "*.c" -o -iname "*.cpp" -o -iname "*.h" -o -iname "*.lch" \) | awk "{print \"./$prefix\"\$0\" \\\\\"}" | grep -v -f"$LOVEROOT/platform/unix/exclude"
+	find "$1" $2 -type f \( -iname "*.c" -o -iname "*.cpp" -o -iname "*.h" -o -iname "*.hpp" -o -iname "*.lch" \) | awk "{print \"./$prefix\"\$0\" \\\\\"}" | grep -v -f"$LOVEROOT/platform/unix/exclude"
 }
 }
 
 
 handlemodule()
 handlemodule()
@@ -78,11 +78,13 @@ genmodules()
 	for library in *; do
 	for library in *; do
 		NAME="LOVE_LIBRARY_$(upper "$library")"
 		NAME="LOVE_LIBRARY_$(upper "$library")"
 		flags="$flags library-$library"
 		flags="$flags library-$library"
-
-		printf "if $NAME\n"
-		printf "liblove${love_amsuffix}_la_SOURCES += \\\\\n"
 		FILES="$(sourcefind "$library" | sed "s/^/    /")"
 		FILES="$(sourcefind "$library" | sed "s/^/    /")"
-		printf "${FILES:0:${#FILES}-2}\nendif\n\n"
+
+		if [[ ${#FILES} -gt 2 ]]; then
+			printf "if $NAME\n"
+			printf "liblove${love_amsuffix}_la_SOURCES += \\\\\n"
+			printf "${FILES:0:${#FILES}-2}\nendif\n\n"
+		fi
 	done
 	done
 	cd ../..
 	cd ../..
 }
 }
@@ -96,10 +98,10 @@ genflags()
 		amflag="$(upper $(echo love-$flag | sed 's/-/_/g'))"
 		amflag="$(upper $(echo love-$flag | sed 's/-/_/g'))"
 		printf "AC_ARG_ENABLE([$flag], [  --disable-$flag    Turn off $prettyflag], [], [$varflag=true])\n"
 		printf "AC_ARG_ENABLE([$flag], [  --disable-$flag    Turn off $prettyflag], [], [$varflag=true])\n"
 		printf "AH_TEMPLATE([$defineflag], [])\n"
 		printf "AH_TEMPLATE([$defineflag], [])\n"
-		printf "if test x\"\$$varflag\" == xtrue; then\n"
+		printf "if test x\"\$$varflag\" = xtrue; then\n"
 		printf "    AC_DEFINE([$defineflag], [])\n"
 		printf "    AC_DEFINE([$defineflag], [])\n"
 		printf "fi\n"
 		printf "fi\n"
-		printf "AM_CONDITIONAL([$amflag], [test x\$$varflag == xtrue])\n\n"
+		printf "AM_CONDITIONAL([$amflag], [test x\$$varflag = xtrue])\n\n"
 	done
 	done
 }
 }
 
 

+ 12 - 2
jni/love/platform/unix/love.1

@@ -1,4 +1,5 @@
 .\" (c) 2008-2011 Miriam Ruiz <[email protected]>
 .\" (c) 2008-2011 Miriam Ruiz <[email protected]>
+.\" (c) 2013 Bart van Strien <[email protected]>
 .\"
 .\"
 .\" This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damagesarising from the use of this software.
 .\" This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damagesarising from the use of this software.
 .\"
 .\"
@@ -11,16 +12,25 @@
 .\" 3. This notice may not be removed or altered from any source distribution.
 .\" 3. This notice may not be removed or altered from any source distribution.
 .\"
 .\"
 .\" Modifications:
 .\" Modifications:
-.\" - Update version to 0.9 and remove reference to doc dir - Bart van Strien, 2013
+.\" - Update version to 0.9 and remove reference to doc dir
+.\" - Add fused and version flags
+
 .TH "LÖVE" "1" "0.9" "" ""
 .TH "LÖVE" "1" "0.9" "" ""
 .SH "NAME"
 .SH "NAME"
 love \- 2D game development framework
 love \- 2D game development framework
+
 .SH "SYNOPSIS"
 .SH "SYNOPSIS"
 .B love
 .B love
-<\fIgame.love\fR>
+[--fused] <\fIgame.love\fR>
+.PP
+.B love
+--version
+.PP
+
 .SH "DESCRIPTION"
 .SH "DESCRIPTION"
 LÖVE was created to be a user\-friendly engine in which simple (or complicated) games could be made without having extensive knowledge of system or graphics functions and without having to dedicate time towards developing the same engine features time and time again.
 LÖVE was created to be a user\-friendly engine in which simple (or complicated) games could be made without having extensive knowledge of system or graphics functions and without having to dedicate time towards developing the same engine features time and time again.
 .P
 .P
 Developed with cross\-platform implementation in mind, it utilizes the latest open source libraries to deliver a similar game experience, independent of operating system. By relying on the Lua scripting language for game\-specific programming, it allows even the novice game creator to quickly and efficiently develop an idea into a fully working game.
 Developed with cross\-platform implementation in mind, it utilizes the latest open source libraries to deliver a similar game experience, independent of operating system. By relying on the Lua scripting language for game\-specific programming, it allows even the novice game creator to quickly and efficiently develop an idea into a fully working game.
+
 .SH "SEE ALSO"
 .SH "SEE ALSO"
 You can find more information at \fIhttp://love2d.org/\fR
 You can find more information at \fIhttp://love2d.org/\fR

+ 1 - 1
jni/love/platform/unix/love.desktop.in

@@ -2,7 +2,7 @@
 Name=LÖVE
 Name=LÖVE
 Comment=The unquestionably awesome 2D game engine
 Comment=The unquestionably awesome 2D game engine
 MimeType=application/x-love-game;
 MimeType=application/x-love-game;
-Exec=@bindir@/love
+Exec=@bindir@/love %f
 Type=Application
 Type=Application
 Categories=Development;Game;
 Categories=Development;Game;
 Terminal=false
 Terminal=false

+ 4 - 1
jni/love/readme.md

@@ -29,10 +29,12 @@ Repository information
 
 
 We use the 'default' branch for development, and therefore it should not be considered stable.
 We use the 'default' branch for development, and therefore it should not be considered stable.
 Also used is the 'minor' branch, which is used for features in the next minor version and it is
 Also used is the 'minor' branch, which is used for features in the next minor version and it is
-not our development target (which would be the next revision). (Version numbers formatted major.minor.revision.)
+not our development target (which would be the next revision - version numbers are formatted major.minor.revision.)
 
 
 We tag all our releases (since we started using mercurial), and have binary downloads available for them.
 We tag all our releases (since we started using mercurial), and have binary downloads available for them.
 
 
+Experimental changes are developed in the separate [love-experiments][love-experiments] repository.
+
 Builds
 Builds
 ------
 ------
 
 
@@ -69,3 +71,4 @@ Dependencies
 [stableppa]: https://launchpad.net/~bartbes/+archive/love-stable
 [stableppa]: https://launchpad.net/~bartbes/+archive/love-stable
 [unstableppa]: https://launchpad.net/~bartbes/+archive/love-unstable
 [unstableppa]: https://launchpad.net/~bartbes/+archive/love-unstable
 [aur]: http://aur.archlinux.org/packages.php?ID=35279
 [aur]: http://aur.archlinux.org/packages.php?ID=35279
+[love-experiments]: https://bitbucket.org/bartbes/love-experiments

+ 11 - 15
jni/love/src/modules/audio/openal/Pool.cpp

@@ -98,11 +98,7 @@ bool Pool::isPlaying(Source *s)
 	bool p = false;
 	bool p = false;
 	{
 	{
 		thread::Lock lock(mutex);
 		thread::Lock lock(mutex);
-		for (auto i = playing.begin(); i != playing.end(); i++)
-		{
-			if (i->first == s)
-				p = true;
-		}
+		p = (playing.find(s) != playing.end());
 	}
 	}
 	return p;
 	return p;
 }
 }
@@ -181,11 +177,11 @@ bool Pool::play(Source *source, ALuint &out)
 void Pool::stop()
 void Pool::stop()
 {
 {
 	thread::Lock lock(mutex);
 	thread::Lock lock(mutex);
-	for (auto i = playing.begin(); i != playing.end(); i++)
+	for (const auto &i : playing)
 	{
 	{
-		i->first->stopAtomic();
-		i->first->release();
-		available.push(i->second);
+		i.first->stopAtomic();
+		i.first->release();
+		available.push(i.second);
 	}
 	}
 
 
 	playing.clear();
 	playing.clear();
@@ -200,8 +196,8 @@ void Pool::stop(Source *source)
 void Pool::pause()
 void Pool::pause()
 {
 {
 	thread::Lock lock(mutex);
 	thread::Lock lock(mutex);
-	for (auto i = playing.begin(); i != playing.end(); i++)
-		i->first->pauseAtomic();
+	for (const auto &i : playing)
+		i.first->pauseAtomic();
 }
 }
 
 
 void Pool::pause(Source *source)
 void Pool::pause(Source *source)
@@ -215,8 +211,8 @@ void Pool::pause(Source *source)
 void Pool::resume()
 void Pool::resume()
 {
 {
 	thread::Lock lock(mutex);
 	thread::Lock lock(mutex);
-	for (auto i = playing.begin(); i != playing.end(); i++)
-		i->first->resumeAtomic();
+	for (const auto &i : playing)
+		i.first->resumeAtomic();
 }
 }
 
 
 void Pool::resume(Source *source)
 void Pool::resume(Source *source)
@@ -230,8 +226,8 @@ void Pool::resume(Source *source)
 void Pool::rewind()
 void Pool::rewind()
 {
 {
 	thread::Lock lock(mutex);
 	thread::Lock lock(mutex);
-	for (auto i = playing.begin(); i != playing.end(); i++)
-		i->first->rewindAtomic();
+	for (const auto &i : playing)
+		i.first->rewindAtomic();
 }
 }
 
 
 // For those times we don't need it backed.
 // For those times we don't need it backed.

+ 4 - 1
jni/love/src/modules/audio/openal/Source.cpp

@@ -62,6 +62,7 @@ Source::Source(Pool *pool, love::sound::SoundData *soundData)
 	, cone()
 	, cone()
 	, offsetSamples(0)
 	, offsetSamples(0)
 	, offsetSeconds(0)
 	, offsetSeconds(0)
+	, sampleRate(soundData->getSampleRate())
 	, channels(soundData->getChannels())
 	, channels(soundData->getChannels())
 	, decoder(nullptr)
 	, decoder(nullptr)
 	, toLoop(0)
 	, toLoop(0)
@@ -94,6 +95,7 @@ Source::Source(Pool *pool, love::sound::Decoder *decoder)
 	, cone()
 	, cone()
 	, offsetSamples(0)
 	, offsetSamples(0)
 	, offsetSeconds(0)
 	, offsetSeconds(0)
+	, sampleRate(decoder->getSampleRate())
 	, channels(decoder->getChannels())
 	, channels(decoder->getChannels())
 	, decoder(decoder)
 	, decoder(decoder)
 	, toLoop(0)
 	, toLoop(0)
@@ -125,6 +127,7 @@ Source::Source(const Source &s)
 	, cone(s.cone)
 	, cone(s.cone)
 	, offsetSamples(0)
 	, offsetSamples(0)
 	, offsetSeconds(0)
 	, offsetSeconds(0)
+	, sampleRate(s.sampleRate)
 	, channels(s.channels)
 	, channels(s.channels)
 	, decoder(nullptr)
 	, decoder(nullptr)
 	, toLoop(0)
 	, toLoop(0)
@@ -383,7 +386,7 @@ float Source::tellAtomic(void *unit) const
 		default:
 		default:
 			{
 			{
 				alGetSourcef(source, AL_SAMPLE_OFFSET, &offset);
 				alGetSourcef(source, AL_SAMPLE_OFFSET, &offset);
-				offset /= decoder->getSampleRate();
+				offset /= sampleRate;
 				if (type == TYPE_STREAM) offset += offsetSeconds;
 				if (type == TYPE_STREAM) offset += offsetSeconds;
 			}
 			}
 			break;
 			break;

+ 1 - 0
jni/love/src/modules/audio/openal/Source.h

@@ -180,6 +180,7 @@ private:
 	float offsetSamples;
 	float offsetSamples;
 	float offsetSeconds;
 	float offsetSeconds;
 
 
+	int sampleRate;
 	int channels;
 	int channels;
 
 
 	Object::StrongRef<love::sound::Decoder> decoder;
 	Object::StrongRef<love::sound::Decoder> decoder;

+ 22 - 0
jni/love/src/modules/graphics/Graphics.cpp

@@ -119,6 +119,16 @@ bool Graphics::getConstant(StackType in, const char *&out)
 	return stackTypes.find(in, out);
 	return stackTypes.find(in, out);
 }
 }
 
 
+bool Graphics::getConstant(const char *in, StatType &out)
+{
+	return statTypes.find(in, out);
+}
+
+bool Graphics::getConstant(StatType in, const char *&out)
+{
+	return statTypes.find(in, out);
+}
+
 StringMap<Graphics::DrawMode, Graphics::DRAW_MAX_ENUM>::Entry Graphics::drawModeEntries[] =
 StringMap<Graphics::DrawMode, Graphics::DRAW_MAX_ENUM>::Entry Graphics::drawModeEntries[] =
 {
 {
 	{ "line", Graphics::DRAW_LINE },
 	{ "line", Graphics::DRAW_LINE },
@@ -212,5 +222,17 @@ StringMap<Graphics::StackType, Graphics::STACK_MAX_ENUM>::Entry Graphics::stackT
 
 
 StringMap<Graphics::StackType, Graphics::STACK_MAX_ENUM> Graphics::stackTypes(Graphics::stackTypeEntries, sizeof(Graphics::stackTypeEntries));
 StringMap<Graphics::StackType, Graphics::STACK_MAX_ENUM> Graphics::stackTypes(Graphics::stackTypeEntries, sizeof(Graphics::stackTypeEntries));
 
 
+StringMap<Graphics::StatType, Graphics::STAT_MAX_ENUM>::Entry Graphics::statTypeEntries[] =
+{
+	{"drawcalls", Graphics::STAT_DRAW_CALLS},
+	{"canvasswitches", Graphics::STAT_CANVAS_SWITCHES},
+	{"canvases", Graphics::STAT_CANVASES},
+	{"images", Graphics::STAT_IMAGES},
+	{"fonts", Graphics::STAT_FONTS},
+	{"texturememory", Graphics::STAT_TEXTURE_MEMORY},
+};
+
+StringMap<Graphics::StatType, Graphics::STAT_MAX_ENUM> Graphics::statTypes(Graphics::statTypeEntries, sizeof(Graphics::statTypeEntries));
+
 } // graphics
 } // graphics
 } // love
 } // love

+ 27 - 0
jni/love/src/modules/graphics/Graphics.h

@@ -128,6 +128,17 @@ public:
 		STACK_MAX_ENUM
 		STACK_MAX_ENUM
 	};
 	};
 
 
+	enum StatType
+	{
+		STAT_DRAW_CALLS,
+		STAT_CANVAS_SWITCHES,
+		STAT_CANVASES,
+		STAT_IMAGES,
+		STAT_FONTS,
+		STAT_TEXTURE_MEMORY,
+		STAT_MAX_ENUM
+	};
+
 	struct RendererInfo
 	struct RendererInfo
 	{
 	{
 		std::string name;
 		std::string name;
@@ -136,6 +147,16 @@ public:
 		std::string device;
 		std::string device;
 	};
 	};
 
 
+	struct Stats
+	{
+		int drawCalls;
+		int canvasSwitches;
+		int canvases;
+		int images;
+		int fonts;
+		size_t textureMemory;
+	};
+
 	virtual ~Graphics();
 	virtual ~Graphics();
 
 
 	// Implements Module.
 	// Implements Module.
@@ -200,6 +221,9 @@ public:
 	static bool getConstant(const char *in, StackType &out);
 	static bool getConstant(const char *in, StackType &out);
 	static bool getConstant(StackType in, const char *&out);
 	static bool getConstant(StackType in, const char *&out);
 
 
+	static bool getConstant(const char *in, StatType &out);
+	static bool getConstant(StatType in, const char *&out);
+
 private:
 private:
 
 
 	static StringMap<DrawMode, DRAW_MAX_ENUM>::Entry drawModeEntries[];
 	static StringMap<DrawMode, DRAW_MAX_ENUM>::Entry drawModeEntries[];
@@ -229,6 +253,9 @@ private:
 	static StringMap<StackType, STACK_MAX_ENUM>::Entry stackTypeEntries[];
 	static StringMap<StackType, STACK_MAX_ENUM>::Entry stackTypeEntries[];
 	static StringMap<StackType, STACK_MAX_ENUM> stackTypes;
 	static StringMap<StackType, STACK_MAX_ENUM> stackTypes;
 
 
+	static StringMap<StatType, STAT_MAX_ENUM>::Entry statTypeEntries[];
+	static StringMap<StatType, STAT_MAX_ENUM> statTypes;
+
 }; // Graphics
 }; // Graphics
 
 
 } // graphics
 } // graphics

+ 4 - 13
jni/love/src/modules/graphics/Volatile.cpp

@@ -43,26 +43,17 @@ Volatile::~Volatile()
 bool Volatile::loadAll()
 bool Volatile::loadAll()
 {
 {
 	bool success = true;
 	bool success = true;
-	std::list<Volatile *>::iterator i = all.begin();
 
 
-	while (i != all.end())
-	{
-		success = success && (*i)->loadVolatile();
-		i++;
-	}
+	for (Volatile *v : all)
+		success = success && v->loadVolatile();
 
 
 	return success;
 	return success;
 }
 }
 
 
 void Volatile::unloadAll()
 void Volatile::unloadAll()
 {
 {
-	std::list<Volatile *>::iterator i = all.begin();
-
-	while (i != all.end())
-	{
-		(*i)->unloadVolatile();
-		i++;
-	}
+	for (Volatile *v : all)
+		v->unloadVolatile();
 }
 }
 
 
 } // graphics
 } // graphics

+ 42 - 1
jni/love/src/modules/graphics/opengl/Canvas.cpp

@@ -185,6 +185,7 @@ struct FramebufferStrategyCore : public FramebufferStrategy
 	virtual void bindFBO(GLuint framebuffer)
 	virtual void bindFBO(GLuint framebuffer)
 	{
 	{
 		glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
 		glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+		++Canvas::switchCount;
 	}
 	}
 
 
 	virtual void setAttachments()
 	virtual void setAttachments()
@@ -338,6 +339,7 @@ struct FramebufferStrategyPackedEXT : public FramebufferStrategy
 	virtual void bindFBO(GLuint framebuffer)
 	virtual void bindFBO(GLuint framebuffer)
 	{
 	{
 		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer);
 		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer);
+		++Canvas::switchCount;
 	}
 	}
 
 
 	virtual void setAttachments()
 	virtual void setAttachments()
@@ -433,6 +435,8 @@ FramebufferStrategyEXT strategyEXT;
 Canvas *Canvas::current = nullptr;
 Canvas *Canvas::current = nullptr;
 OpenGL::Viewport Canvas::systemViewport = OpenGL::Viewport();
 OpenGL::Viewport Canvas::systemViewport = OpenGL::Viewport();
 bool Canvas::screenHasSRGB = false;
 bool Canvas::screenHasSRGB = false;
+int Canvas::switchCount = 0;
+int Canvas::canvasCount = 0;
 
 
 static void getStrategy()
 static void getStrategy()
 {
 {
@@ -460,6 +464,7 @@ Canvas::Canvas(int width, int height, Format format, int msaa)
 	, format(format)
 	, format(format)
     , msaa_samples(msaa)
     , msaa_samples(msaa)
 	, msaa_dirty(false)
 	, msaa_dirty(false)
+	, texture_memory(0)
 {
 {
 	this->width = width;
 	this->width = width;
 	this->height = height;
 	this->height = height;
@@ -490,10 +495,14 @@ Canvas::Canvas(int width, int height, Format format, int msaa)
 	getStrategy();
 	getStrategy();
 
 
 	loadVolatile();
 	loadVolatile();
+
+	++canvasCount;
 }
 }
 
 
 Canvas::~Canvas()
 Canvas::~Canvas()
 {
 {
+	--canvasCount;
+
 	// reset framebuffer if still using this one
 	// reset framebuffer if still using this one
 	if (current == this)
 	if (current == this)
 		stopGrab();
 		stopGrab();
@@ -616,6 +625,14 @@ bool Canvas::loadVolatile()
 
 
 	msaa_dirty = (msaa_buffer != 0);
 	msaa_dirty = (msaa_buffer != 0);
 
 
+	size_t prevmemsize = texture_memory;
+
+	texture_memory = (getFormatBitsPerPixel(format) * width * height) / 8;
+	if (msaa_buffer != 0)
+		texture_memory += (texture_memory * msaa_samples);
+
+	gl.updateTextureMemorySize(prevmemsize, texture_memory);
+
 	return true;
 	return true;
 }
 }
 
 
@@ -630,6 +647,9 @@ void Canvas::unloadVolatile()
 	resolve_fbo = msaa_buffer = 0;
 	resolve_fbo = msaa_buffer = 0;
 
 
 	attachedCanvases.clear();
 	attachedCanvases.clear();
+
+	gl.updateTextureMemorySize(texture_memory, 0);
+	texture_memory = 0;
 }
 }
 
 
 void Canvas::drawv(const Matrix &t, const Vertex *v)
 void Canvas::drawv(const Matrix &t, const Vertex *v)
@@ -647,7 +667,7 @@ void Canvas::drawv(const Matrix &t, const Vertex *v)
 	gl.setVertexAttribArray(OpenGL::ATTRIB_POS, 2, GL_FLOAT, sizeof(Vertex), (GLvoid *) &v[0].x);
 	gl.setVertexAttribArray(OpenGL::ATTRIB_POS, 2, GL_FLOAT, sizeof(Vertex), (GLvoid *) &v[0].x);
 	gl.setVertexAttribArray(OpenGL::ATTRIB_TEXCOORD, 2, GL_FLOAT, sizeof(Vertex), (GLvoid *) &v[0].s);
 	gl.setVertexAttribArray(OpenGL::ATTRIB_TEXCOORD, 2, GL_FLOAT, sizeof(Vertex), (GLvoid *) &v[0].s);
 
 
-	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+	gl.drawArrays(GL_TRIANGLE_FAN, 0, 4);
 
 
 	gl.disableVertexAttribArray(OpenGL::ATTRIB_POS);
 	gl.disableVertexAttribArray(OpenGL::ATTRIB_POS);
 	gl.disableVertexAttribArray(OpenGL::ATTRIB_TEXCOORD);
 	gl.disableVertexAttribArray(OpenGL::ATTRIB_TEXCOORD);
@@ -1088,6 +1108,27 @@ void Canvas::convertFormat(Canvas::Format format, GLenum &internalformat, GLenum
 	}
 	}
 }
 }
 
 
+size_t Canvas::getFormatBitsPerPixel(Format format)
+{
+	switch (getSizedFormat(format))
+	{
+	case FORMAT_RGBA8:
+	case FORMAT_RGB10A2:
+	case FORMAT_RG11B10F:
+	case FORMAT_SRGB:
+	default:
+		return 32;
+	case FORMAT_RGBA4:
+	case FORMAT_RGB5A1:
+	case FORMAT_RGB565:
+		return 16;
+	case FORMAT_RGBA16F:
+		return 64;
+	case FORMAT_RGBA32F:
+		return 128;
+	}
+}
+
 bool Canvas::isSupported()
 bool Canvas::isSupported()
 {
 {
 	getStrategy();
 	getStrategy();

+ 7 - 0
jni/love/src/modules/graphics/opengl/Canvas.h

@@ -26,6 +26,7 @@
 #include "image/ImageData.h"
 #include "image/ImageData.h"
 #include "common/Matrix.h"
 #include "common/Matrix.h"
 #include "common/StringMap.h"
 #include "common/StringMap.h"
+#include "common/int.h"
 #include "Texture.h"
 #include "Texture.h"
 #include "OpenGL.h"
 #include "OpenGL.h"
 
 
@@ -127,6 +128,9 @@ public:
 	// Whether the main screen should have linear -> sRGB conversions enabled.
 	// Whether the main screen should have linear -> sRGB conversions enabled.
 	static bool screenHasSRGB;
 	static bool screenHasSRGB;
 
 
+	static int switchCount;
+	static int canvasCount;
+
 	static bool getConstant(const char *in, Format &out);
 	static bool getConstant(const char *in, Format &out);
 	static bool getConstant(Format in, const char *&out);
 	static bool getConstant(Format in, const char *&out);
 
 
@@ -136,6 +140,7 @@ private:
 
 
 	static Format getSizedFormat(Format format);
 	static Format getSizedFormat(Format format);
 	static void convertFormat(Format format, GLenum &internalformat, GLenum &externalformat, GLenum &type);
 	static void convertFormat(Format format, GLenum &internalformat, GLenum &externalformat, GLenum &type);
+	static size_t getFormatBitsPerPixel(Format format);
 
 
 	GLuint fbo;
 	GLuint fbo;
 	GLuint resolve_fbo;
 	GLuint resolve_fbo;
@@ -153,6 +158,8 @@ private:
 	int msaa_samples;
 	int msaa_samples;
 	bool msaa_dirty;
 	bool msaa_dirty;
 
 
+	size_t texture_memory;
+
 	void setupGrab();
 	void setupGrab();
 	void drawv(const Matrix &t, const Vertex *v);
 	void drawv(const Matrix &t, const Vertex *v);
 
 

+ 17 - 2
jni/love/src/modules/graphics/opengl/Font.cpp

@@ -37,6 +37,8 @@ namespace graphics
 namespace opengl
 namespace opengl
 {
 {
 
 
+int Font::fontCount = 0;
+
 const int Font::TEXTURE_WIDTHS[]  = {128, 256, 256, 512, 512, 1024, 1024};
 const int Font::TEXTURE_WIDTHS[]  = {128, 256, 256, 512, 512, 1024, 1024};
 const int Font::TEXTURE_HEIGHTS[] = {128, 128, 256, 256, 512, 512,  1024};
 const int Font::TEXTURE_HEIGHTS[] = {128, 128, 256, 256, 512, 512,  1024};
 
 
@@ -48,6 +50,7 @@ Font::Font(love::font::Rasterizer *r, const Texture::Filter &filter)
 	, mSpacing(1)
 	, mSpacing(1)
 	, filter(filter)
 	, filter(filter)
 	, useSpacesAsTab(false)
 	, useSpacesAsTab(false)
+	, textureMemorySize(0)
 {
 {
 	this->filter.mipmap = Texture::FILTER_NONE;
 	this->filter.mipmap = Texture::FILTER_NONE;
 
 
@@ -90,12 +93,16 @@ Font::Font(love::font::Rasterizer *r, const Texture::Filter &filter)
 	}
 	}
 
 
 	delete gd;
 	delete gd;
+
+	++fontCount;
 }
 }
 
 
 Font::~Font()
 Font::~Font()
 {
 {
 	delete indexBuffer;
 	delete indexBuffer;
 	unloadVolatile();
 	unloadVolatile();
+
+	--fontCount;
 }
 }
 
 
 bool Font::initializeTexture(GLenum format)
 bool Font::initializeTexture(GLenum format)
@@ -173,6 +180,11 @@ void Font::createTexture()
 					&emptyData[0]);
 					&emptyData[0]);
 
 
 	setFilter(filter);
 	setFilter(filter);
+
+	size_t prevmemsize = textureMemorySize;
+
+	textureMemorySize += emptyData.size();
+	gl.updateTextureMemorySize(prevmemsize, textureMemorySize);
 }
 }
 
 
 Font::Glyph *Font::addGlyph(uint32 glyph)
 Font::Glyph *Font::addGlyph(uint32 glyph)
@@ -414,14 +426,14 @@ void Font::print(const std::string &text, float x, float y, float extra_spacing,
 		{
 		{
 			// Optimization: setting a base vertex is faster than redoing the
 			// Optimization: setting a base vertex is faster than redoing the
 			// setVertexAttribArray calls before each draw.
 			// setVertexAttribArray calls before each draw.
-			glDrawElementsBaseVertex(GL_TRIANGLES, (it->vertexcount / 4) * 6, elemtype, elemoffset, it->startvertex);
+			gl.drawElementsBaseVertex(GL_TRIANGLES, (it->vertexcount / 4) * 6, elemtype, elemoffset, it->startvertex);
 		}
 		}
 		else
 		else
 		{
 		{
 			gl.setVertexAttribArray(OpenGL::ATTRIB_POS, 2, GL_FLOAT, sizeof(GlyphVertex), &glyphverts[it->startvertex].x);
 			gl.setVertexAttribArray(OpenGL::ATTRIB_POS, 2, GL_FLOAT, sizeof(GlyphVertex), &glyphverts[it->startvertex].x);
 			gl.setVertexAttribArray(OpenGL::ATTRIB_TEXCOORD, 2, GL_FLOAT, sizeof(GlyphVertex), &glyphverts[it->startvertex].s);
 			gl.setVertexAttribArray(OpenGL::ATTRIB_TEXCOORD, 2, GL_FLOAT, sizeof(GlyphVertex), &glyphverts[it->startvertex].s);
 
 
-			glDrawElements(GL_TRIANGLES, (it->vertexcount / 4) * 6, elemtype, elemoffset);
+			gl.drawElements(GL_TRIANGLES, (it->vertexcount / 4) * 6, elemtype, elemoffset);
 		}
 		}
 	}
 	}
 
 
@@ -598,6 +610,9 @@ void Font::unloadVolatile()
 		iter++;
 		iter++;
 	}
 	}
 	textures.clear();
 	textures.clear();
+
+	gl.updateTextureMemorySize(textureMemorySize, 0);
+	textureMemorySize = 0;
 }
 }
 
 
 int Font::getAscent() const
 int Font::getAscent() const

+ 4 - 0
jni/love/src/modules/graphics/opengl/Font.h

@@ -139,6 +139,8 @@ public:
 	bool hasGlyph(uint32 glyph) const;
 	bool hasGlyph(uint32 glyph) const;
 	bool hasGlyphs(const std::string &text) const;
 	bool hasGlyphs(const std::string &text) const;
 
 
+	static int fontCount;
+
 private:
 private:
 
 
 	enum FontType
 	enum FontType
@@ -210,6 +212,8 @@ private:
 
 
 	bool useSpacesAsTab;
 	bool useSpacesAsTab;
 
 
+	size_t textureMemorySize;
+
 	static const int NUM_TEXTURE_SIZES = 7;
 	static const int NUM_TEXTURE_SIZES = 7;
 	static const int TEXTURE_WIDTHS[NUM_TEXTURE_SIZES];
 	static const int TEXTURE_WIDTHS[NUM_TEXTURE_SIZES];
 	static const int TEXTURE_HEIGHTS[NUM_TEXTURE_SIZES];
 	static const int TEXTURE_HEIGHTS[NUM_TEXTURE_SIZES];

+ 21 - 3
jni/love/src/modules/graphics/opengl/Graphics.cpp

@@ -442,6 +442,10 @@ void Graphics::present()
 
 
 	// Restore the currently active canvas, if there is one.
 	// Restore the currently active canvas, if there is one.
 	setCanvas(canvases);
 	setCanvas(canvases);
+
+	// Reset the per-frame stat counts.
+	gl.stats.drawCalls = 0;
+	Canvas::switchCount = 0;
 }
 }
 
 
 int Graphics::getWidth() const
 int Graphics::getWidth() const
@@ -1049,7 +1053,7 @@ void Graphics::point(float x, float y)
 	gl.enableVertexAttribArray(OpenGL::ATTRIB_POS);
 	gl.enableVertexAttribArray(OpenGL::ATTRIB_POS);
 	gl.setVertexAttribArray(OpenGL::ATTRIB_POS, 2, GL_FLOAT, 0, coord);
 	gl.setVertexAttribArray(OpenGL::ATTRIB_POS, 2, GL_FLOAT, 0, coord);
 
 
-	glDrawArrays(GL_POINTS, 0, 1);
+	gl.drawArrays(GL_POINTS, 0, 1);
 
 
 	gl.disableVertexAttribArray(OpenGL::ATTRIB_POS);
 	gl.disableVertexAttribArray(OpenGL::ATTRIB_POS);
 }
 }
@@ -1170,7 +1174,7 @@ void Graphics::arc(DrawMode mode, float x, float y, float radius, float angle1,
 		gl.enableVertexAttribArray(OpenGL::ATTRIB_POS);
 		gl.enableVertexAttribArray(OpenGL::ATTRIB_POS);
 		gl.setVertexAttribArray(OpenGL::ATTRIB_POS, 2, GL_FLOAT, 0, (GLvoid *) coords);
 		gl.setVertexAttribArray(OpenGL::ATTRIB_POS, 2, GL_FLOAT, 0, (GLvoid *) coords);
 
 
-		glDrawArrays(GL_TRIANGLE_FAN, 0, points + 2);
+		gl.drawArrays(GL_TRIANGLE_FAN, 0, points + 2);
 
 
 		gl.disableVertexAttribArray(OpenGL::ATTRIB_POS);
 		gl.disableVertexAttribArray(OpenGL::ATTRIB_POS);
 	}
 	}
@@ -1198,7 +1202,7 @@ void Graphics::polygon(DrawMode mode, const float *coords, size_t count)
 		gl.enableVertexAttribArray(OpenGL::ATTRIB_POS);
 		gl.enableVertexAttribArray(OpenGL::ATTRIB_POS);
 		gl.setVertexAttribArray(OpenGL::ATTRIB_POS, 2, GL_FLOAT, 0, (GLvoid *) coords);
 		gl.setVertexAttribArray(OpenGL::ATTRIB_POS, 2, GL_FLOAT, 0, (GLvoid *) coords);
 
 
-		glDrawArrays(GL_TRIANGLE_FAN, 0, count / 2);
+		gl.drawArrays(GL_TRIANGLE_FAN, 0, count / 2);
 
 
 		gl.disableVertexAttribArray(OpenGL::ATTRIB_POS);
 		gl.disableVertexAttribArray(OpenGL::ATTRIB_POS);
 	}
 	}
@@ -1302,6 +1306,20 @@ Graphics::RendererInfo Graphics::getRendererInfo() const
 	return info;
 	return info;
 }
 }
 
 
+Graphics::Stats Graphics::getStats() const
+{
+	Stats stats;
+
+	stats.drawCalls = gl.stats.drawCalls;
+	stats.canvasSwitches = Canvas::switchCount;
+	stats.canvases = Canvas::canvasCount;
+	stats.images = Image::imageCount;
+	stats.fonts = Font::fontCount;
+	stats.textureMemory = gl.stats.textureMemory;
+
+	return stats;
+}
+
 double Graphics::getSystemLimit(SystemLimit limittype) const
 double Graphics::getSystemLimit(SystemLimit limittype) const
 {
 {
 	double limit = 0.0;
 	double limit = 0.0;

+ 6 - 1
jni/love/src/modules/graphics/opengl/Graphics.h

@@ -415,11 +415,16 @@ public:
 
 
 	/**
 	/**
 	 * Returns system-dependent renderer information.
 	 * Returns system-dependent renderer information.
-	 * Returned string s can vary greatly between systems! Do not rely on it for
+	 * Returned strings can vary greatly between systems! Do not rely on it for
 	 * anything!
 	 * anything!
 	 **/
 	 **/
 	RendererInfo getRendererInfo() const;
 	RendererInfo getRendererInfo() const;
 
 
+	/**
+	 * Returns performance-related statistics.
+	 **/
+	Stats getStats() const;
+
 	/**
 	/**
 	 * Gets the system-dependent numeric limit for the specified parameter.
 	 * Gets the system-dependent numeric limit for the specified parameter.
 	 **/
 	 **/

+ 32 - 1
jni/love/src/modules/graphics/opengl/Image.cpp

@@ -31,6 +31,8 @@ namespace graphics
 namespace opengl
 namespace opengl
 {
 {
 
 
+int Image::imageCount = 0;
+
 float Image::maxMipmapSharpness = 0.0f;
 float Image::maxMipmapSharpness = 0.0f;
 
 
 Texture::FilterMode Image::defaultMipmapFilter = Texture::FILTER_NONE;
 Texture::FilterMode Image::defaultMipmapFilter = Texture::FILTER_NONE;
@@ -47,10 +49,13 @@ Image::Image(love::image::ImageData *data, Format format)
 	, compressed(false)
 	, compressed(false)
 	, format(format)
 	, format(format)
 	, usingDefaultTexture(false)
 	, usingDefaultTexture(false)
+	, textureMemorySize(0)
 {
 {
 	width = data->getWidth();
 	width = data->getWidth();
 	height = data->getHeight();
 	height = data->getHeight();
 	preload();
 	preload();
+
+	++imageCount;
 }
 }
 
 
 Image::Image(love::image::CompressedData *cdata, Format format)
 Image::Image(love::image::CompressedData *cdata, Format format)
@@ -64,15 +69,20 @@ Image::Image(love::image::CompressedData *cdata, Format format)
 	, compressed(true)
 	, compressed(true)
 	, format(format)
 	, format(format)
 	, usingDefaultTexture(false)
 	, usingDefaultTexture(false)
+	, textureMemorySize(0)
 {
 {
 	width = cdata->getWidth(0);
 	width = cdata->getWidth(0);
 	height = cdata->getHeight(0);
 	height = cdata->getHeight(0);
 	preload();
 	preload();
+
+	++imageCount;
 }
 }
 
 
 Image::~Image()
 Image::~Image()
 {
 {
 	unload();
 	unload();
+
+	--imageCount;
 }
 }
 
 
 love::image::ImageData *Image::getImageData() const
 love::image::ImageData *Image::getImageData() const
@@ -155,8 +165,11 @@ void Image::uploadCompressedMipmaps()
 		      "compressed image does not have all required levels.");
 		      "compressed image does not have all required levels.");
 	}
 	}
 
 
+	size_t totalsize = cdata->getSize(0);
+
 	for (int i = 1; i < count; i++)
 	for (int i = 1; i < count; i++)
 	{
 	{
+		totalsize += cdata->getSize(i);
 		glCompressedTexImage2D(GL_TEXTURE_2D,
 		glCompressedTexImage2D(GL_TEXTURE_2D,
 		                       i,
 		                       i,
 		                       getCompressedFormat(cdata->getFormat()),
 		                       getCompressedFormat(cdata->getFormat()),
@@ -166,6 +179,10 @@ void Image::uploadCompressedMipmaps()
 		                       GLsizei(cdata->getSize(i)),
 		                       GLsizei(cdata->getSize(i)),
 		                       cdata->getData(i));
 		                       cdata->getData(i));
 	}
 	}
+
+	size_t prevmemsize = textureMemorySize;
+	textureMemorySize = totalsize;
+	gl.updateTextureMemorySize(prevmemsize, textureMemorySize);
 }
 }
 
 
 void Image::createMipmaps()
 void Image::createMipmaps()
@@ -220,6 +237,10 @@ void Image::createMipmaps()
 		                data->getData());
 		                data->getData());
 		glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE);
 		glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE);
 	}
 	}
+
+	size_t prevmemsize = textureMemorySize;
+	textureMemorySize = paddedWidth * paddedHeight * 4 * 1.3333;
+	gl.updateTextureMemorySize(prevmemsize, textureMemorySize);
 }
 }
 
 
 void Image::checkMipmapsCreated()
 void Image::checkMipmapsCreated()
@@ -403,6 +424,13 @@ bool Image::loadVolatile()
 	if (glerr != GL_NO_ERROR)
 	if (glerr != GL_NO_ERROR)
 		throw love::Exception("Cannot create image (error code 0x%x)", glerr);
 		throw love::Exception("Cannot create image (error code 0x%x)", glerr);
 
 
+	if (isCompressed())
+		textureMemorySize = cdata->getSize(0);
+	else
+		textureMemorySize = paddedWidth * paddedHeight * 4;
+
+	gl.updateTextureMemorySize(0, textureMemorySize);
+
 	usingDefaultTexture = false;
 	usingDefaultTexture = false;
 	mipmapsCreated = false;
 	mipmapsCreated = false;
 	checkMipmapsCreated();
 	checkMipmapsCreated();
@@ -478,6 +506,9 @@ void Image::unloadVolatile()
 	{
 	{
 		gl.deleteTexture(texture);
 		gl.deleteTexture(texture);
 		texture = 0;
 		texture = 0;
+
+		gl.updateTextureMemorySize(textureMemorySize, 0);
+		textureMemorySize = 0;
 	}
 	}
 }
 }
 
 
@@ -553,7 +584,7 @@ void Image::drawv(const Matrix &t, const Vertex *v)
 	gl.setVertexAttribArray(OpenGL::ATTRIB_POS, 2, GL_FLOAT, sizeof(Vertex), (GLvoid *)&v[0].x);
 	gl.setVertexAttribArray(OpenGL::ATTRIB_POS, 2, GL_FLOAT, sizeof(Vertex), (GLvoid *)&v[0].x);
 	gl.setVertexAttribArray(OpenGL::ATTRIB_TEXCOORD, 2, GL_FLOAT, sizeof(Vertex), (GLvoid *)&v[0].s);
 	gl.setVertexAttribArray(OpenGL::ATTRIB_TEXCOORD, 2, GL_FLOAT, sizeof(Vertex), (GLvoid *)&v[0].s);
 
 
-	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+	gl.drawArrays(GL_TRIANGLE_FAN, 0, 4);
 
 
 	gl.disableVertexAttribArray(OpenGL::ATTRIB_POS);
 	gl.disableVertexAttribArray(OpenGL::ATTRIB_POS);
 	gl.disableVertexAttribArray(OpenGL::ATTRIB_TEXCOORD);
 	gl.disableVertexAttribArray(OpenGL::ATTRIB_TEXCOORD);

+ 4 - 0
jni/love/src/modules/graphics/opengl/Image.h

@@ -147,6 +147,8 @@ public:
 	static bool getConstant(const char *in, Format &out);
 	static bool getConstant(const char *in, Format &out);
 	static bool getConstant(Format in, const char *&out);
 	static bool getConstant(Format in, const char *&out);
 
 
+	static int imageCount;
+
 private:
 private:
 
 
 	void uploadDefaultTexture();
 	void uploadDefaultTexture();
@@ -183,6 +185,8 @@ private:
 	// back to a default texture.
 	// back to a default texture.
 	bool usingDefaultTexture;
 	bool usingDefaultTexture;
 
 
+	size_t textureMemorySize;
+
 	void preload();
 	void preload();
 
 
 	void uploadTexturePadded();
 	void uploadTexturePadded();

+ 2 - 2
jni/love/src/modules/graphics/opengl/Mesh.cpp

@@ -375,7 +375,7 @@ void Mesh::draw(float x, float y, float angle, float sx, float sy, float ox, flo
 		GLenum type = element_data_type;
 		GLenum type = element_data_type;
 		const void *indices = ibo->getPointer(min * getGLDataTypeSize(type));
 		const void *indices = ibo->getPointer(min * getGLDataTypeSize(type));
 
 
-		glDrawElements(mode, max - min + 1, type, indices);
+		gl.drawElements(mode, max - min + 1, type, indices);
 	}
 	}
 	else
 	else
 	{
 	{
@@ -388,7 +388,7 @@ void Mesh::draw(float x, float y, float angle, float sx, float sy, float ox, flo
 			min = std::min(range_min, max);
 			min = std::min(range_min, max);
 
 
 		// Normal non-indexed drawing (no custom vertex map.)
 		// Normal non-indexed drawing (no custom vertex map.)
-		glDrawArrays(mode, min, max - min + 1);
+		gl.drawArrays(mode, min, max - min + 1);
 	}
 	}
 
 
 	gl.disableVertexAttribArray(OpenGL::ATTRIB_POS);
 	gl.disableVertexAttribArray(OpenGL::ATTRIB_POS);

+ 33 - 39
jni/love/src/modules/graphics/opengl/OpenGL.cpp

@@ -41,7 +41,8 @@ namespace opengl
 {
 {
 
 
 OpenGL::OpenGL()
 OpenGL::OpenGL()
-	: contextInitialized(false)
+	: stats()
+	, contextInitialized(false)
 	, maxAnisotropy(1.0f)
 	, maxAnisotropy(1.0f)
 	, maxTextureSize(0)
 	, maxTextureSize(0)
 	, maxRenderTargets(0)
 	, maxRenderTargets(0)
@@ -360,6 +361,24 @@ void OpenGL::prepareDraw()
 	}
 	}
 }
 }
 
 
+void OpenGL::drawArrays(GLenum mode, GLint first, GLsizei count)
+{
+	glDrawArrays(mode, first, count);
+	++stats.drawCalls;
+}
+
+void OpenGL::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
+{
+	glDrawElements(mode, count, type, indices);
+	++stats.drawCalls;
+}
+
+void OpenGL::drawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex)
+{
+	glDrawElementsBaseVertex(mode, count, type, indices, basevertex);
+	++stats.drawCalls;
+}
+
 void OpenGL::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
 void OpenGL::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
 {
 {
 	Shader *shader = Shader::current;
 	Shader *shader = Shader::current;
@@ -384,6 +403,8 @@ void OpenGL::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsize
 		if (shaderHasID)
 		if (shaderHasID)
 			state.lastPseudoInstanceID = primcount - 1;
 			state.lastPseudoInstanceID = primcount - 1;
 	}
 	}
+
+	++stats.drawCalls;
 }
 }
 
 
 void OpenGL::drawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount)
 void OpenGL::drawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount)
@@ -410,6 +431,8 @@ void OpenGL::drawElementsInstanced(GLenum mode, GLsizei count, GLenum type, cons
 		if (shaderHasID)
 		if (shaderHasID)
 			state.lastPseudoInstanceID = primcount - 1;
 			state.lastPseudoInstanceID = primcount - 1;
 	}
 	}
+
+	++stats.drawCalls;
 }
 }
 
 
 void OpenGL::setColor(const Color &c)
 void OpenGL::setColor(const Color &c)
@@ -648,11 +671,10 @@ void OpenGL::deleteTexture(GLuint texture)
 {
 {
 	// glDeleteTextures binds texture 0 to all texture units the deleted texture
 	// glDeleteTextures binds texture 0 to all texture units the deleted texture
 	// was bound to before deletion.
 	// was bound to before deletion.
-	std::vector<GLuint>::iterator it;
-	for (it = state.textureUnits.begin(); it != state.textureUnits.end(); ++it)
+	for (GLuint &texid : state.textureUnits)
 	{
 	{
-		if (*it == texture)
-			*it = 0;
+		if (texid == texture)
+			texid = 0;
 	}
 	}
 
 
 	glDeleteTextures(1, &texture);
 	glDeleteTextures(1, &texture);
@@ -789,40 +811,6 @@ void OpenGL::setTextureWrap(const graphics::Texture::Wrap &w)
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gt);
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gt);
 }
 }
 
 
-Texture::Wrap OpenGL::getTextureWrap()
-{
-	GLint gs, gt;
-
-	glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, &gs);
-	glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, &gt);
-
-	Texture::Wrap w;
-
-	switch (gs)
-	{
-	case GL_CLAMP_TO_EDGE:
-		w.s = Texture::WRAP_CLAMP;
-		break;
-	case GL_REPEAT:
-	default:
-		w.s = Texture::WRAP_REPEAT;
-		break;
-	}
-
-	switch (gt)
-	{
-	case GL_CLAMP_TO_EDGE:
-		w.t = Texture::WRAP_CLAMP;
-		break;
-	case GL_REPEAT:
-	default:
-		w.t = Texture::WRAP_REPEAT;
-		break;
-	}
-
-	return w;
-}
-
 int OpenGL::getMaxTextureSize() const
 int OpenGL::getMaxTextureSize() const
 {
 {
 	return maxTextureSize;
 	return maxTextureSize;
@@ -833,6 +821,12 @@ int OpenGL::getMaxRenderTargets() const
 	return maxRenderTargets;
 	return maxRenderTargets;
 }
 }
 
 
+void OpenGL::updateTextureMemorySize(size_t oldsize, size_t newsize)
+{
+	int64 memsize = (int64) stats.textureMemory + ((int64 )newsize -  (int64) oldsize);
+	stats.textureMemory = (size_t) std::max(memsize, (int64) 0);
+}
+
 OpenGL::Vendor OpenGL::getVendor() const
 OpenGL::Vendor OpenGL::getVendor() const
 {
 {
 	return vendor;
 	return vendor;

+ 15 - 8
jni/love/src/modules/graphics/opengl/OpenGL.h

@@ -147,6 +147,12 @@ public:
 		OpenGL &gl;
 		OpenGL &gl;
 	};
 	};
 
 
+	struct Stats
+	{
+		size_t textureMemory;
+		int    drawCalls;
+	} stats;
+
 	OpenGL();
 	OpenGL();
 	virtual ~OpenGL() {}
 	virtual ~OpenGL() {}
 
 
@@ -174,13 +180,17 @@ public:
 	void prepareDraw();
 	void prepareDraw();
 
 
 	/**
 	/**
-	 * glDrawArraysInstanced with a pseudo-instancing fallback.
+	 * glDraw* functions which increment the draw-call counter by themselves.
 	 **/
 	 **/
-	void drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+	void drawArrays(GLenum mode, GLint first, GLsizei count);
+	void drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices);
+	void drawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, const void* indices, GLint basevertex);
 
 
 	/**
 	/**
-	 * glDrawElementsInstanced with a pseudo-instancing fallback.
+	 * glDrawArraysInstanced and glDrawElementsInstanced with pseudo-instancing
+	 * fallbacks. They also increment the draw-call counter (once per call).
 	 **/
 	 **/
+	void drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount);
 	void drawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);
 	void drawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);
 
 
 	/**
 	/**
@@ -318,11 +328,6 @@ public:
 	 **/
 	 **/
 	void setTextureWrap(const graphics::Texture::Wrap &w);
 	void setTextureWrap(const graphics::Texture::Wrap &w);
 
 
-	/**
-	 * Returns the texture wrap mode for the currently bound texture.
-	 **/
-	graphics::Texture::Wrap getTextureWrap();
-
 	/**
 	/**
 	 * Returns the maximum supported width or height of a texture.
 	 * Returns the maximum supported width or height of a texture.
 	 **/
 	 **/
@@ -333,6 +338,8 @@ public:
 	 **/
 	 **/
 	int getMaxRenderTargets() const;
 	int getMaxRenderTargets() const;
 
 
+	void updateTextureMemorySize(size_t oldsize, size_t newsize);
+
 	/**
 	/**
 	 * Get the GPU vendor of this OpenGL context.
 	 * Get the GPU vendor of this OpenGL context.
 	 **/
 	 **/

+ 1 - 1
jni/love/src/modules/graphics/opengl/ParticleSystem.cpp

@@ -890,7 +890,7 @@ void ParticleSystem::draw(float x, float y, float angle, float sx, float sy, flo
 
 
 	{
 	{
 		VertexBuffer::Bind ibo_bind(*ibo->getVertexBuffer());
 		VertexBuffer::Bind ibo_bind(*ibo->getVertexBuffer());
-		glDrawElements(GL_TRIANGLES, ibo->getIndexCount(pCount), ibo->getType(), ibo->getPointer(0));
+		gl.drawElements(GL_TRIANGLES, ibo->getIndexCount(pCount), ibo->getType(), ibo->getPointer(0));
 	}
 	}
 
 
 	gl.disableVertexAttribArray(OpenGL::ATTRIB_POS);
 	gl.disableVertexAttribArray(OpenGL::ATTRIB_POS);

+ 4 - 4
jni/love/src/modules/graphics/opengl/Polyline.cpp

@@ -371,9 +371,9 @@ void Polyline::draw()
 	gl.setVertexAttribArray(OpenGL::ATTRIB_POS, 2, GL_FLOAT, 0, vertices);
 	gl.setVertexAttribArray(OpenGL::ATTRIB_POS, 2, GL_FLOAT, 0, vertices);
 
 
 	if (use_quad_indices)
 	if (use_quad_indices)
-		glDrawElements(draw_mode, (vertex_count / 4) * 6, GL_UNSIGNED_SHORT, indices);
+		gl.drawElements(draw_mode, (vertex_count / 4) * 6, GL_UNSIGNED_SHORT, indices);
 	else
 	else
-		glDrawArrays(draw_mode, 0, vertex_count);
+		gl.drawArrays(draw_mode, 0, vertex_count);
 
 
 	if (overdraw)
 	if (overdraw)
 	{
 	{
@@ -388,9 +388,9 @@ void Polyline::draw()
 		gl.setVertexAttribArray(OpenGL::ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, 0, colors);
 		gl.setVertexAttribArray(OpenGL::ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, 0, colors);
 
 
 		if (use_quad_indices)
 		if (use_quad_indices)
-			glDrawElements(draw_mode, (overdraw_vertex_count / 4) * 6, GL_UNSIGNED_SHORT, indices);
+			gl.drawElements(draw_mode, (overdraw_vertex_count / 4) * 6, GL_UNSIGNED_SHORT, indices);
 		else
 		else
-			glDrawArrays(draw_mode, 0, overdraw_vertex_count);
+			gl.drawArrays(draw_mode, 0, overdraw_vertex_count);
 
 
 		gl.disableVertexAttribArray(OpenGL::ATTRIB_COLOR);
 		gl.disableVertexAttribArray(OpenGL::ATTRIB_COLOR);
 		gl.setColor(c);
 		gl.setColor(c);

+ 1 - 1
jni/love/src/modules/graphics/opengl/SpriteBatch.cpp

@@ -294,7 +294,7 @@ void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float
 	gl.setVertexAttribArray(OpenGL::ATTRIB_TEXCOORD, 2, GL_FLOAT, sizeof(Vertex), array_buf->getPointer(texel_offset));
 	gl.setVertexAttribArray(OpenGL::ATTRIB_TEXCOORD, 2, GL_FLOAT, sizeof(Vertex), array_buf->getPointer(texel_offset));
 
 
 	gl.prepareDraw();
 	gl.prepareDraw();
-	glDrawElements(GL_TRIANGLES, element_buf->getIndexCount(next), element_buf->getType(), element_buf->getPointer(0));
+	gl.drawElements(GL_TRIANGLES, element_buf->getIndexCount(next), element_buf->getType(), element_buf->getPointer(0));
 
 
 	gl.disableVertexAttribArray(OpenGL::ATTRIB_POS);
 	gl.disableVertexAttribArray(OpenGL::ATTRIB_POS);
 	gl.disableVertexAttribArray(OpenGL::ATTRIB_TEXCOORD);
 	gl.disableVertexAttribArray(OpenGL::ATTRIB_TEXCOORD);

+ 36 - 0
jni/love/src/modules/graphics/opengl/wrap_Graphics.cpp

@@ -1090,6 +1090,41 @@ int w_getRendererInfo(lua_State *L)
 	return 4;
 	return 4;
 }
 }
 
 
+int w_getStats(lua_State *L)
+{
+	Graphics::Stats stats = instance()->getStats();
+
+	lua_createtable(L, 0, (int) Graphics::STAT_MAX_ENUM);
+
+	const char *sname = nullptr;
+
+	Graphics::getConstant(Graphics::STAT_DRAW_CALLS, sname);
+	lua_pushinteger(L, stats.drawCalls);
+	lua_setfield(L, -2, sname);
+
+	Graphics::getConstant(Graphics::STAT_CANVAS_SWITCHES, sname);
+	lua_pushinteger(L, stats.canvasSwitches);
+	lua_setfield(L, -2, sname);
+
+	Graphics::getConstant(Graphics::STAT_CANVASES, sname);
+	lua_pushinteger(L, stats.canvases);
+	lua_setfield(L, -2, sname);
+
+	Graphics::getConstant(Graphics::STAT_IMAGES, sname);
+	lua_pushinteger(L, stats.images);
+	lua_setfield(L, -2, sname);
+
+	Graphics::getConstant(Graphics::STAT_FONTS, sname);
+	lua_pushinteger(L, stats.fonts);
+	lua_setfield(L, -2, sname);
+
+	Graphics::getConstant(Graphics::STAT_TEXTURE_MEMORY, sname);
+	lua_pushnumber(L, (lua_Number) stats.textureMemory);
+	lua_setfield(L, -2, sname);
+
+	return 1;
+}
+
 int w_getSystemLimit(lua_State *L)
 int w_getSystemLimit(lua_State *L)
 {
 {
 	const char *limitstr = luaL_checkstring(L, 1);
 	const char *limitstr = luaL_checkstring(L, 1);
@@ -1462,6 +1497,7 @@ static const luaL_Reg functions[] =
 	{ "getCanvasFormats", w_getCanvasFormats },
 	{ "getCanvasFormats", w_getCanvasFormats },
 	{ "getCompressedImageFormats", w_getCompressedImageFormats },
 	{ "getCompressedImageFormats", w_getCompressedImageFormats },
 	{ "getRendererInfo", w_getRendererInfo },
 	{ "getRendererInfo", w_getRendererInfo },
+	{ "getStats", w_getStats },
 	{ "getSystemLimit", w_getSystemLimit },
 	{ "getSystemLimit", w_getSystemLimit },
 
 
 	{ "draw", w_draw },
 	{ "draw", w_draw },

+ 1 - 0
jni/love/src/modules/graphics/opengl/wrap_Graphics.h

@@ -98,6 +98,7 @@ int w_isSupported(lua_State *L);
 int w_getCanvasFormats(lua_State *L);
 int w_getCanvasFormats(lua_State *L);
 int w_getCompressedImageFormats(lua_State *L);
 int w_getCompressedImageFormats(lua_State *L);
 int w_getRendererInfo(lua_State *L);
 int w_getRendererInfo(lua_State *L);
+int w_getStats(lua_State *L);
 int w_getSystemLimit(lua_State *L);
 int w_getSystemLimit(lua_State *L);
 int w_draw(lua_State *L);
 int w_draw(lua_State *L);
 int w_print(lua_State *L);
 int w_print(lua_State *L);

+ 24 - 28
jni/love/src/modules/image/magpie/PNGHandler.cpp

@@ -33,6 +33,9 @@
 // C++
 // C++
 #include <algorithm>
 #include <algorithm>
 
 
+// C
+#include <cstdlib>
+
 namespace love
 namespace love
 {
 {
 namespace image
 namespace image
@@ -46,39 +49,36 @@ static unsigned zlibDecompress(unsigned char **out, size_t *outsize, const unsig
 {
 {
 	int status = Z_OK;
 	int status = Z_OK;
 
 
-	uLongf outdataSize = insize;
-	size_t sizeMultiplier = 0;
+	uLongf outdatasize = insize;
+	size_t sizemultiplier = 0;
 	unsigned char *outdata = nullptr;
 	unsigned char *outdata = nullptr;
 
 
 	while (true)
 	while (true)
 	{
 	{
 		// Enough size to hold the decompressed data, hopefully.
 		// Enough size to hold the decompressed data, hopefully.
-		outdataSize = insize << (++sizeMultiplier);
-
-		try
-		{
-			outdata = new unsigned char[outdataSize];
-		}
-		catch (std::bad_alloc &)
-		{
+		outdatasize = insize << (++sizemultiplier);
+
+		// LodePNG uses malloc, realloc, and free.
+		outdata = (unsigned char *) malloc(outdatasize);
+
+		if (!outdata)
 			return 83; // "Memory allocation failed" error code for LodePNG.
 			return 83; // "Memory allocation failed" error code for LodePNG.
-		}
 
 
 		// Use zlib to decompress the PNG data.
 		// Use zlib to decompress the PNG data.
-		status = uncompress(outdata, &outdataSize, in, insize);
+		status = uncompress(outdata, &outdatasize, in, insize);
 
 
 		// If the out buffer was big enough, break out of the loop.
 		// If the out buffer was big enough, break out of the loop.
 		if (status != Z_BUF_ERROR)
 		if (status != Z_BUF_ERROR)
 			break;
 			break;
 
 
 		// Otherwise delete the out buffer and try again with a larger size...
 		// Otherwise delete the out buffer and try again with a larger size...
-		delete[] outdata;
+		free(outdata);
 		outdata = nullptr;
 		outdata = nullptr;
 	}
 	}
 
 
 	if (status != Z_OK)
 	if (status != Z_OK)
 	{
 	{
-		delete[] outdata;
+		free(outdata);
 		return 10000; // "Unknown error code" for LodePNG.
 		return 10000; // "Unknown error code" for LodePNG.
 	}
 	}
 
 
@@ -86,34 +86,30 @@ static unsigned zlibDecompress(unsigned char **out, size_t *outsize, const unsig
 		*out = outdata;
 		*out = outdata;
 
 
 	if (outsize != nullptr)
 	if (outsize != nullptr)
-		*outsize = outdataSize;
+		*outsize = outdatasize;
 
 
 	return 0; // Success.
 	return 0; // Success.
 }
 }
 
 
 // Custom PNG compression function for LodePNG, using zlib.
 // Custom PNG compression function for LodePNG, using zlib.
 static unsigned zlibCompress(unsigned char **out, size_t *outsize, const unsigned char *in,
 static unsigned zlibCompress(unsigned char **out, size_t *outsize, const unsigned char *in,
-							 size_t insize, const LodePNGCompressSettings* /*settings*/)
+                             size_t insize, const LodePNGCompressSettings* /*settings*/)
 {
 {
 	// Get the maximum compressed size of the data.
 	// Get the maximum compressed size of the data.
-	uLongf outdataSize = compressBound(insize);
-	unsigned char *outdata = nullptr;
+	uLongf outdatasize = compressBound(insize);
 
 
-	try
-	{
-		outdata = new unsigned char[outdataSize];
-	}
-	catch (std::bad_alloc &)
-	{
+	// LodePNG uses malloc, realloc, and free.
+	unsigned char *outdata = (unsigned char *) malloc(outdatasize);
+
+	if (!outdata)
 		return 83; // "Memory allocation failed" error code for LodePNG.
 		return 83; // "Memory allocation failed" error code for LodePNG.
-	}
 
 
 	// Use zlib to compress the PNG data.
 	// Use zlib to compress the PNG data.
-	int status = compress(outdata, &outdataSize, in, insize);
+	int status = compress(outdata, &outdatasize, in, insize);
 
 
 	if (status != Z_OK)
 	if (status != Z_OK)
 	{
 	{
-		delete[] outdata;
+		free(outdata);
 		return 10000; // "Unknown error code" for LodePNG.
 		return 10000; // "Unknown error code" for LodePNG.
 	}
 	}
 
 
@@ -121,7 +117,7 @@ static unsigned zlibCompress(unsigned char **out, size_t *outsize, const unsigne
 		*out = outdata;
 		*out = outdata;
 
 
 	if (outsize != nullptr)
 	if (outsize != nullptr)
-		*outsize = (size_t) outdataSize;
+		*outsize = (size_t) outdatasize;
 
 
 	return 0; // Success.
 	return 0; // Success.
 }
 }

+ 0 - 9
jni/love/src/modules/image/magpie/ddsHandler.cpp

@@ -21,9 +21,6 @@
 // LOVE
 // LOVE
 #include "ddsHandler.h"
 #include "ddsHandler.h"
 
 
-// C++
-#include <algorithm>
-
 namespace love
 namespace love
 {
 {
 namespace image
 namespace image
@@ -33,12 +30,6 @@ namespace magpie
 
 
 bool DDSHandler::canParse(const filesystem::FileData *data)
 bool DDSHandler::canParse(const filesystem::FileData *data)
 {
 {
-	std::string ext = data->getExtension();
-	std::transform(ext.begin(), ext.end(), ext.begin(), tolower);
-
-	if (ext.compare("dds") != 0)
-		return false;
-
 	return dds::isCompressedDDS(data->getData(), data->getSize());
 	return dds::isCompressedDDS(data->getData(), data->getSize());
 }
 }
 
 

+ 12 - 8
jni/love/src/modules/joystick/sdl/JoystickModule.cpp

@@ -218,8 +218,8 @@ bool JoystickModule::setGamepadMapping(const std::string &guid, Joystick::Gamepa
 			joyinputstream << "b" << joyinput.button;
 			joyinputstream << "b" << joyinput.button;
 		break;
 		break;
 	case Joystick::INPUT_TYPE_HAT:
 	case Joystick::INPUT_TYPE_HAT:
-		if (joyinput.hat.value >= 0 && Joystick::getConstant(joyinput.hat.value, sdlhat))
-			joyinputstream << "h" << joyinput.hat.value << "." << int(sdlhat);
+		if (joyinput.hat.index >= 0 && Joystick::getConstant(joyinput.hat.value, sdlhat))
+			joyinputstream << "h" << joyinput.hat.index << "." << int(sdlhat);
 		break;
 		break;
 	default:
 	default:
 		break;
 		break;
@@ -297,7 +297,7 @@ Joystick::JoystickInput JoystickModule::getGamepadMapping(const std::string &gui
 	if (findpos == std::string::npos)
 	if (findpos == std::string::npos)
 		return jinput;
 		return jinput;
 
 
-	size_t endpos = mapstr.find_first_of(',', findpos);
+	size_t endpos = mapstr.find_first_of(',', findpos + 1);
 	if (endpos == std::string::npos)
 	if (endpos == std::string::npos)
 	{
 	{
 		// Assume end-of-string if we can't find the next comma.
 		// Assume end-of-string if we can't find the next comma.
@@ -364,19 +364,19 @@ Joystick::JoystickInput JoystickModule::JoystickInputFromString(const std::strin
 	{
 	{
 	case 'a':
 	case 'a':
 		jinput.type = Joystick::INPUT_TYPE_AXIS;
 		jinput.type = Joystick::INPUT_TYPE_AXIS;
-		jinput.axis = atoi(bindvalues.c_str());
+		jinput.axis = (int) strtol(bindvalues.c_str(), nullptr, 10);
 		break;
 		break;
 	case 'b':
 	case 'b':
 		jinput.type = Joystick::INPUT_TYPE_BUTTON;
 		jinput.type = Joystick::INPUT_TYPE_BUTTON;
-		jinput.button = atoi(bindvalues.c_str());
+		jinput.button = (int) strtol(bindvalues.c_str(), nullptr, 10);
 		break;
 		break;
 	case 'h':
 	case 'h':
 		// Hat string syntax is "index.value".
 		// Hat string syntax is "index.value".
 		if (bindvalues.length() < 3)
 		if (bindvalues.length() < 3)
 			break;
 			break;
 		jinput.type = Joystick::INPUT_TYPE_HAT;
 		jinput.type = Joystick::INPUT_TYPE_HAT;
-		jinput.hat.index = atoi(bindvalues.substr(0, 1).c_str());
-		sdlhat = (Uint8) atoi(bindvalues.substr(2, 1).c_str());
+		jinput.hat.index = (int) strtol(bindvalues.substr(0, 1).c_str(), nullptr, 10);
+		sdlhat = (Uint8) strtol(bindvalues.substr(2).c_str(), nullptr, 10);
 		if (!Joystick::getConstant(sdlhat, jinput.hat.value))
 		if (!Joystick::getConstant(sdlhat, jinput.hat.value))
 		{
 		{
 			// Return an invalid value if we can't find the hat constant.
 			// Return an invalid value if we can't find the hat constant.
@@ -405,10 +405,14 @@ void JoystickModule::removeBindFromMapString(std::string &mapstr, const std::str
 	if (joybindpos == std::string::npos)
 	if (joybindpos == std::string::npos)
 		return;
 		return;
 
 
-	// Find the start of the entire bind.
+	// Find the start of the entire bind by looking for the separator between
+	// the end of one section of the map string and the start of this section.
 	size_t bindstart = mapstr.rfind(',', joybindpos);
 	size_t bindstart = mapstr.rfind(',', joybindpos);
 	if (bindstart != std::string::npos && bindstart < mapstr.length() - 1)
 	if (bindstart != std::string::npos && bindstart < mapstr.length() - 1)
 	{
 	{
+		// The start of the bind is directly after the separator.
+		bindstart++;
+
 		size_t bindend = mapstr.find(',', bindstart + 1);
 		size_t bindend = mapstr.find(',', bindstart + 1);
 		if (bindend == std::string::npos)
 		if (bindend == std::string::npos)
 			bindend = mapstr.length() - 1;
 			bindend = mapstr.length() - 1;

+ 2 - 0
jni/love/src/modules/window/Window.cpp

@@ -51,6 +51,7 @@ WindowSettings::WindowSettings()
 	, display(0)
 	, display(0)
 	, highdpi(false)
 	, highdpi(false)
 	, sRGB(false)
 	, sRGB(false)
+	, refreshrate(0.0)
 {
 {
 }
 }
 
 
@@ -99,6 +100,7 @@ StringMap<Window::Setting, Window::SETTING_MAX_ENUM>::Entry Window::settingEntri
 	{"display", SETTING_DISPLAY},
 	{"display", SETTING_DISPLAY},
 	{"highdpi", SETTING_HIGHDPI},
 	{"highdpi", SETTING_HIGHDPI},
 	{"srgb", SETTING_SRGB},
 	{"srgb", SETTING_SRGB},
+	{"refreshrate", SETTING_REFRESHRATE},
 };
 };
 
 
 StringMap<Window::Setting, Window::SETTING_MAX_ENUM> Window::settings(Window::settingEntries, sizeof(Window::settingEntries));
 StringMap<Window::Setting, Window::SETTING_MAX_ENUM> Window::settings(Window::settingEntries, sizeof(Window::settingEntries));

+ 2 - 0
jni/love/src/modules/window/Window.h

@@ -59,6 +59,7 @@ public:
 		SETTING_DISPLAY,
 		SETTING_DISPLAY,
 		SETTING_HIGHDPI,
 		SETTING_HIGHDPI,
 		SETTING_SRGB,
 		SETTING_SRGB,
+		SETTING_REFRESHRATE,
 		SETTING_MAX_ENUM
 		SETTING_MAX_ENUM
 	};
 	};
 
 
@@ -200,6 +201,7 @@ struct WindowSettings
 	int display; // = 0
 	int display; // = 0
 	bool highdpi; // false
 	bool highdpi; // false
 	bool sRGB; // false
 	bool sRGB; // false
+	double refreshrate; // 0.0
 
 
 }; // WindowSettings
 }; // WindowSettings
 
 

+ 6 - 0
jni/love/src/modules/window/sdl/Window.cpp

@@ -440,6 +440,12 @@ void Window::updateSettings(const WindowSettings &newsettings)
 		SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
 		SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
 
 
 	curMode.settings.sRGB = newsettings.sRGB;
 	curMode.settings.sRGB = newsettings.sRGB;
+
+	SDL_DisplayMode dmode = {};
+	SDL_GetCurrentDisplayMode(curMode.settings.display, &dmode);
+
+	// May be 0 if the refresh rate can't be determined.
+	curMode.settings.refreshrate = (double) dmode.refresh_rate;
 }
 }
 
 
 void Window::getWindow(int &width, int &height, WindowSettings &settings)
 void Window::getWindow(int &width, int &height, WindowSettings &settings)

+ 6 - 4
jni/love/src/modules/window/wrap_Window.cpp

@@ -105,17 +105,16 @@ int w_setMode(lua_State *L)
 	settings.minheight = luax_intflag(L, 3, settingName(Window::SETTING_MIN_HEIGHT), 1);
 	settings.minheight = luax_intflag(L, 3, settingName(Window::SETTING_MIN_HEIGHT), 1);
 	settings.borderless = luax_boolflag(L, 3, settingName(Window::SETTING_BORDERLESS), false);
 	settings.borderless = luax_boolflag(L, 3, settingName(Window::SETTING_BORDERLESS), false);
 	settings.centered = luax_boolflag(L, 3, settingName(Window::SETTING_CENTERED), true);
 	settings.centered = luax_boolflag(L, 3, settingName(Window::SETTING_CENTERED), true);
-	settings.display = luax_intflag(L, 3, settingName(Window::SETTING_DISPLAY), 1);
+	settings.display = luax_intflag(L, 3, settingName(Window::SETTING_DISPLAY), 1) - 1;
 	settings.highdpi = luax_boolflag(L, 3, settingName(Window::SETTING_HIGHDPI), false);
 	settings.highdpi = luax_boolflag(L, 3, settingName(Window::SETTING_HIGHDPI), false);
 	settings.sRGB = luax_boolflag(L, 3, settingName(Window::SETTING_SRGB), false);
 	settings.sRGB = luax_boolflag(L, 3, settingName(Window::SETTING_SRGB), false);
 
 
+	// We don't explicitly set the refresh rate, it's "read-only".
+
 	// For backward-compatibility. TODO: remove!
 	// For backward-compatibility. TODO: remove!
 	int fsaa = luax_intflag(L, 3, settingName(Window::SETTING_FSAA), 0);
 	int fsaa = luax_intflag(L, 3, settingName(Window::SETTING_FSAA), 0);
 	if (fsaa > settings.msaa) settings.msaa = fsaa;
 	if (fsaa > settings.msaa) settings.msaa = fsaa;
 
 
-	// Display index is 1-based in Lua and 0-based internally.
-	settings.display--;
-
 	luax_catchexcept(L,
 	luax_catchexcept(L,
 		[&](){ luax_pushboolean(L, instance()->setWindow(w, h, &settings)); }
 		[&](){ luax_pushboolean(L, instance()->setWindow(w, h, &settings)); }
 	);
 	);
@@ -176,6 +175,9 @@ int w_getMode(lua_State *L)
 	luax_pushboolean(L, settings.sRGB);
 	luax_pushboolean(L, settings.sRGB);
 	lua_setfield(L, -2, settingName(Window::SETTING_SRGB));
 	lua_setfield(L, -2, settingName(Window::SETTING_SRGB));
 
 
+	lua_pushnumber(L, settings.refreshrate);
+	lua_setfield(L, -2, settingName(Window::SETTING_REFRESHRATE));
+
 	return 3;
 	return 3;
 }
 }
 
 

+ 7 - 1
jni/love/src/scripts/boot.lua

@@ -1587,9 +1587,15 @@ function love.errhand(msg)
 	end
 	end
 	if love.audio then love.audio.stop() end
 	if love.audio then love.audio.stop() end
 	love.graphics.reset()
 	love.graphics.reset()
-	love.graphics.setBackgroundColor(89, 157, 220)
 	local font = love.graphics.setNewFont(math.floor(14 * love.window.getPixelScale()))
 	local font = love.graphics.setNewFont(math.floor(14 * love.window.getPixelScale()))
 
 
+	local sRGB = select(3, love.window.getMode()).srgb
+	if sRGB then
+		love.graphics.setBackgroundColor(love.math.gammaToLinear(89, 157, 220))
+	else
+		love.graphics.setBackgroundColor(89, 157, 220)
+	end
+
 	love.graphics.setColor(255, 255, 255, 255)
 	love.graphics.setColor(255, 255, 255, 255)
 
 
 	local trace = debug.traceback()
 	local trace = debug.traceback()

+ 14 - 3
jni/love/src/scripts/boot.lua.h

@@ -5340,14 +5340,25 @@ const unsigned char boot_lua[] =
 	0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a,
 	0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a,
 	0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x72, 0x65, 0x73, 
 	0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x72, 0x65, 0x73, 
 	0x65, 0x74, 0x28, 0x29, 0x0a,
 	0x65, 0x74, 0x28, 0x29, 0x0a,
-	0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, 
-	0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x38, 0x39, 
-	0x2c, 0x20, 0x31, 0x35, 0x37, 0x2c, 0x20, 0x32, 0x32, 0x30, 0x29, 0x0a,
 	0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 
 	0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 
 	0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x4e, 0x65, 0x77, 0x46, 0x6f, 
 	0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x4e, 0x65, 0x77, 0x46, 0x6f, 
 	0x6e, 0x74, 0x28, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x28, 0x31, 0x34, 0x20, 0x2a, 
 	0x6e, 0x74, 0x28, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x28, 0x31, 0x34, 0x20, 0x2a, 
 	0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x69, 
 	0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x69, 
 	0x78, 0x65, 0x6c, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x28, 0x29, 0x29, 0x29, 0x0a,
 	0x78, 0x65, 0x6c, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x28, 0x29, 0x29, 0x29, 0x0a,
+	0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x52, 0x47, 0x42, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x65, 
+	0x63, 0x74, 0x28, 0x33, 0x2c, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 
+	0x67, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x28, 0x29, 0x29, 0x2e, 0x73, 0x72, 0x67, 0x62, 0x0a,
+	0x09, 0x69, 0x66, 0x20, 0x73, 0x52, 0x47, 0x42, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
+	0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 
+	0x74, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x6c, 
+	0x6f, 0x76, 0x65, 0x2e, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x67, 0x61, 0x6d, 0x6d, 0x61, 0x54, 0x6f, 0x4c, 0x69, 
+	0x6e, 0x65, 0x61, 0x72, 0x28, 0x38, 0x39, 0x2c, 0x20, 0x31, 0x35, 0x37, 0x2c, 0x20, 0x32, 0x32, 0x30, 0x29, 
+	0x29, 0x0a,
+	0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a,
+	0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 
+	0x74, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x38, 
+	0x39, 0x2c, 0x20, 0x31, 0x35, 0x37, 0x2c, 0x20, 0x32, 0x32, 0x30, 0x29, 0x0a,
+	0x09, 0x65, 0x6e, 0x64, 0x0a,
 	0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, 
 	0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, 
 	0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x32, 0x35, 
 	0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x32, 0x35, 
 	0x35, 0x2c, 0x20, 0x32, 0x35, 0x35, 0x29, 0x0a,
 	0x35, 0x2c, 0x20, 0x32, 0x35, 0x35, 0x29, 0x0a,

+ 9 - 6
jni/love/src/scripts/graphics.lua

@@ -1299,8 +1299,7 @@ do
 #define number float
 #define number float
 #define Image sampler2D
 #define Image sampler2D
 #define extern uniform
 #define extern uniform
-#define Texel texture2D
-#define love_Canvases gl_FragData]]
+#define Texel texture2D]]
 
 
 	GLSLES.SYNTAX = GLSL.SYNTAX
 	GLSLES.SYNTAX = GLSL.SYNTAX
 
 
@@ -1383,12 +1382,14 @@ void main() {
 #define PIXEL
 #define PIXEL
 
 
 #define VaryingTexCoord gl_TexCoord[0]
 #define VaryingTexCoord gl_TexCoord[0]
-#define VaryingColor gl_Color]],
+#define VaryingColor gl_Color
+
+#define love_Canvases gl_FragData]],
 
 
 		FOOTER = [[
 		FOOTER = [[
 void main() {
 void main() {
 	// fix crashing issue in OSX when _tex0_ is unused within effect()
 	// fix crashing issue in OSX when _tex0_ is unused within effect()
-	float dummy = texture2D(_tex0_, vec2(.5)).r;
+	float dummy = Texel(_tex0_, vec2(.5)).r;
 
 
 	// See Shader::checkSetScreenParams in Shader.cpp.
 	// See Shader::checkSetScreenParams in Shader.cpp.
 	vec2 pixelcoord = vec2(gl_FragCoord.x, (gl_FragCoord.y * love_ScreenSize.z) + love_ScreenSize.w);
 	vec2 pixelcoord = vec2(gl_FragCoord.x, (gl_FragCoord.y * love_ScreenSize.z) + love_ScreenSize.w);
@@ -1399,7 +1400,7 @@ void main() {
 		FOOTER_MULTI_CANVAS = [[
 		FOOTER_MULTI_CANVAS = [[
 void main() {
 void main() {
 	// fix crashing issue in OSX when _tex0_ is unused within effect()
 	// fix crashing issue in OSX when _tex0_ is unused within effect()
-	float dummy = texture2D(_tex0_, vec2(.5)).r;
+	float dummy = Texel(_tex0_, vec2(.5)).r;
 
 
 	// See Shader::checkSetScreenParams in Shader.cpp.
 	// See Shader::checkSetScreenParams in Shader.cpp.
 	vec2 pixelcoord = vec2(gl_FragCoord.x, (gl_FragCoord.y * love_ScreenSize.z) + love_ScreenSize.w);
 	vec2 pixelcoord = vec2(gl_FragCoord.x, (gl_FragCoord.y * love_ScreenSize.z) + love_ScreenSize.w);
@@ -1415,7 +1416,9 @@ void main() {
 precision mediump float;
 precision mediump float;
 
 
 varying mediump vec4 VaryingTexCoord;
 varying mediump vec4 VaryingTexCoord;
-varying lowp vec4 VaryingColor;]],
+varying lowp vec4 VaryingColor;
+
+#define love_Canvases gl_FragData;]],
 
 
 		FOOTER = GLSL.PIXEL.FOOTER,
 		FOOTER = GLSL.PIXEL.FOOTER,
 		FOOTER_MULTI_CANVAS = GLSL.PIXEL.FOOTER_MULTI_CANVAS,
 		FOOTER_MULTI_CANVAS = GLSL.PIXEL.FOOTER_MULTI_CANVAS,

+ 14 - 11
jni/love/src/scripts/graphics.lua.h

@@ -6278,9 +6278,7 @@ const unsigned char graphics_lua[] =
 	0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x75, 0x6e, 0x69, 
 	0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x75, 0x6e, 0x69, 
 	0x66, 0x6f, 0x72, 0x6d, 0x0a,
 	0x66, 0x6f, 0x72, 0x6d, 0x0a,
 	0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x54, 0x65, 0x78, 0x65, 0x6c, 0x20, 0x74, 0x65, 0x78, 0x74, 
 	0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x54, 0x65, 0x78, 0x65, 0x6c, 0x20, 0x74, 0x65, 0x78, 0x74, 
-	0x75, 0x72, 0x65, 0x32, 0x44, 0x0a,
-	0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f, 0x43, 0x61, 0x6e, 0x76, 0x61, 
-	0x73, 0x65, 0x73, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5d, 0x5d, 0x0a,
+	0x75, 0x72, 0x65, 0x32, 0x44, 0x5d, 0x5d, 0x0a,
 	0x09, 0x47, 0x4c, 0x53, 0x4c, 0x45, 0x53, 0x2e, 0x53, 0x59, 0x4e, 0x54, 0x41, 0x58, 0x20, 0x3d, 0x20, 0x47, 
 	0x09, 0x47, 0x4c, 0x53, 0x4c, 0x45, 0x53, 0x2e, 0x53, 0x59, 0x4e, 0x54, 0x41, 0x58, 0x20, 0x3d, 0x20, 0x47, 
 	0x4c, 0x53, 0x4c, 0x2e, 0x53, 0x59, 0x4e, 0x54, 0x41, 0x58, 0x0a,
 	0x4c, 0x53, 0x4c, 0x2e, 0x53, 0x59, 0x4e, 0x54, 0x41, 0x58, 0x0a,
 	0x09, 0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x55, 0x4e, 0x49, 0x46, 0x4f, 0x52, 0x4d, 0x53, 0x20, 0x3d, 0x20, 0x5b, 
 	0x09, 0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x55, 0x4e, 0x49, 0x46, 0x4f, 0x52, 0x4d, 0x53, 0x20, 0x3d, 0x20, 0x5b, 
@@ -6417,16 +6415,18 @@ const unsigned char graphics_lua[] =
 	0x43, 0x6f, 0x6f, 0x72, 0x64, 0x20, 0x67, 0x6c, 0x5f, 0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x5b, 
 	0x43, 0x6f, 0x6f, 0x72, 0x64, 0x20, 0x67, 0x6c, 0x5f, 0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x5b, 
 	0x30, 0x5d, 0x0a,
 	0x30, 0x5d, 0x0a,
 	0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x56, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6c, 
 	0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x56, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6c, 
-	0x6f, 0x72, 0x20, 0x67, 0x6c, 0x5f, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x5d, 0x5d, 0x2c, 0x0a,
+	0x6f, 0x72, 0x20, 0x67, 0x6c, 0x5f, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x0a,
+	0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f, 0x43, 0x61, 0x6e, 0x76, 0x61, 
+	0x73, 0x65, 0x73, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5d, 0x5d, 0x2c, 0x0a,
 	0x09, 0x09, 0x46, 0x4f, 0x4f, 0x54, 0x45, 0x52, 0x20, 0x3d, 0x20, 0x5b, 0x5b, 0x0a,
 	0x09, 0x09, 0x46, 0x4f, 0x4f, 0x54, 0x45, 0x52, 0x20, 0x3d, 0x20, 0x5b, 0x5b, 0x0a,
 	0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a,
 	0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a,
 	0x09, 0x2f, 0x2f, 0x20, 0x66, 0x69, 0x78, 0x20, 0x63, 0x72, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x69, 
 	0x09, 0x2f, 0x2f, 0x20, 0x66, 0x69, 0x78, 0x20, 0x63, 0x72, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x69, 
 	0x73, 0x73, 0x75, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x4f, 0x53, 0x58, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x5f, 
 	0x73, 0x73, 0x75, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x4f, 0x53, 0x58, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x5f, 
 	0x74, 0x65, 0x78, 0x30, 0x5f, 0x20, 0x69, 0x73, 0x20, 0x75, 0x6e, 0x75, 0x73, 0x65, 0x64, 0x20, 0x77, 0x69, 
 	0x74, 0x65, 0x78, 0x30, 0x5f, 0x20, 0x69, 0x73, 0x20, 0x75, 0x6e, 0x75, 0x73, 0x65, 0x64, 0x20, 0x77, 0x69, 
 	0x74, 0x68, 0x69, 0x6e, 0x20, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x28, 0x29, 0x0a,
 	0x74, 0x68, 0x69, 0x6e, 0x20, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x28, 0x29, 0x0a,
-	0x09, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 
-	0x74, 0x75, 0x72, 0x65, 0x32, 0x44, 0x28, 0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x2c, 0x20, 0x76, 0x65, 0x63, 
-	0x32, 0x28, 0x2e, 0x35, 0x29, 0x29, 0x2e, 0x72, 0x3b, 0x0a,
+	0x09, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x20, 0x3d, 0x20, 0x54, 0x65, 0x78, 
+	0x65, 0x6c, 0x28, 0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x32, 0x28, 0x2e, 0x35, 
+	0x29, 0x29, 0x2e, 0x72, 0x3b, 0x0a,
 	0x09, 0x2f, 0x2f, 0x20, 0x53, 0x65, 0x65, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x3a, 0x3a, 0x63, 0x68, 
 	0x09, 0x2f, 0x2f, 0x20, 0x53, 0x65, 0x65, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x3a, 0x3a, 0x63, 0x68, 
 	0x65, 0x63, 0x6b, 0x53, 0x65, 0x74, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 
 	0x65, 0x63, 0x6b, 0x53, 0x65, 0x74, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 
 	0x20, 0x69, 0x6e, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x63, 0x70, 0x70, 0x2e, 0x0a,
 	0x20, 0x69, 0x6e, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x63, 0x70, 0x70, 0x2e, 0x0a,
@@ -6449,9 +6449,9 @@ const unsigned char graphics_lua[] =
 	0x73, 0x73, 0x75, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x4f, 0x53, 0x58, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x5f, 
 	0x73, 0x73, 0x75, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x4f, 0x53, 0x58, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x5f, 
 	0x74, 0x65, 0x78, 0x30, 0x5f, 0x20, 0x69, 0x73, 0x20, 0x75, 0x6e, 0x75, 0x73, 0x65, 0x64, 0x20, 0x77, 0x69, 
 	0x74, 0x65, 0x78, 0x30, 0x5f, 0x20, 0x69, 0x73, 0x20, 0x75, 0x6e, 0x75, 0x73, 0x65, 0x64, 0x20, 0x77, 0x69, 
 	0x74, 0x68, 0x69, 0x6e, 0x20, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x28, 0x29, 0x0a,
 	0x74, 0x68, 0x69, 0x6e, 0x20, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x28, 0x29, 0x0a,
-	0x09, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 
-	0x74, 0x75, 0x72, 0x65, 0x32, 0x44, 0x28, 0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x2c, 0x20, 0x76, 0x65, 0x63, 
-	0x32, 0x28, 0x2e, 0x35, 0x29, 0x29, 0x2e, 0x72, 0x3b, 0x0a,
+	0x09, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x20, 0x3d, 0x20, 0x54, 0x65, 0x78, 
+	0x65, 0x6c, 0x28, 0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x32, 0x28, 0x2e, 0x35, 
+	0x29, 0x29, 0x2e, 0x72, 0x3b, 0x0a,
 	0x09, 0x2f, 0x2f, 0x20, 0x53, 0x65, 0x65, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x3a, 0x3a, 0x63, 0x68, 
 	0x09, 0x2f, 0x2f, 0x20, 0x53, 0x65, 0x65, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x3a, 0x3a, 0x63, 0x68, 
 	0x65, 0x63, 0x6b, 0x53, 0x65, 0x74, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 
 	0x65, 0x63, 0x6b, 0x53, 0x65, 0x74, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 
 	0x20, 0x69, 0x6e, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x63, 0x70, 0x70, 0x2e, 0x0a,
 	0x20, 0x69, 0x6e, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x63, 0x70, 0x70, 0x2e, 0x0a,
@@ -6476,7 +6476,10 @@ const unsigned char graphics_lua[] =
 	0x63, 0x34, 0x20, 0x56, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 
 	0x63, 0x34, 0x20, 0x56, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 
 	0x3b, 0x0a,
 	0x3b, 0x0a,
 	0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x6c, 0x6f, 0x77, 0x70, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 
 	0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x6c, 0x6f, 0x77, 0x70, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 
-	0x56, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x5d, 0x5d, 0x2c, 0x0a,
+	0x56, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a,
+	0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f, 0x43, 0x61, 0x6e, 0x76, 0x61, 
+	0x73, 0x65, 0x73, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x3b, 0x5d, 0x5d, 
+	0x2c, 0x0a,
 	0x09, 0x09, 0x46, 0x4f, 0x4f, 0x54, 0x45, 0x52, 0x20, 0x3d, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x50, 0x49, 
 	0x09, 0x09, 0x46, 0x4f, 0x4f, 0x54, 0x45, 0x52, 0x20, 0x3d, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x50, 0x49, 
 	0x58, 0x45, 0x4c, 0x2e, 0x46, 0x4f, 0x4f, 0x54, 0x45, 0x52, 0x2c, 0x0a,
 	0x58, 0x45, 0x4c, 0x2e, 0x46, 0x4f, 0x4f, 0x54, 0x45, 0x52, 0x2c, 0x0a,
 	0x09, 0x09, 0x46, 0x4f, 0x4f, 0x54, 0x45, 0x52, 0x5f, 0x4d, 0x55, 0x4c, 0x54, 0x49, 0x5f, 0x43, 0x41, 0x4e, 
 	0x09, 0x09, 0x46, 0x4f, 0x4f, 0x54, 0x45, 0x52, 0x5f, 0x4d, 0x55, 0x4c, 0x54, 0x49, 0x5f, 0x43, 0x41, 0x4e,