Browse Source

Merge with default branch (should have done that before, right?)

--HG--
branch : minor
vrld 13 years ago
parent
commit
5fd704219c
100 changed files with 13470 additions and 2511 deletions
  1. 1 0
      .hgtags
  2. 110 0
      changes.txt
  3. 32 9
      configure.in
  4. 14 12
      extra/nsis/love.nsi
  5. 12 0
      extra/resources/b64.lua
  6. BIN
      extra/resources/heart.png
  7. BIN
      extra/resources/knoll1.png
  8. BIN
      extra/resources/love.png
  9. BIN
      extra/resources/pig.png
  10. BIN
      extra/resources/planet.png
  11. BIN
      extra/resources/star1.png
  12. 863 1
      license.txt
  13. 36 42
      platform/macosx/love-Info.plist
  14. 519 274
      platform/macosx/love.xcodeproj/project.pbxproj
  15. BIN
      platform/msvc2010/app.rc
  16. 193 56
      platform/msvc2010/love.vcxproj
  17. 641 236
      platform/msvc2010/love.vcxproj.filters
  18. 22 7
      platform/unix/automagic
  19. 3 0
      platform/unix/exclude
  20. 2 1
      platform/unix/gen-makefile
  21. 67 0
      readme.md
  22. 0 25
      readme.txt
  23. 56 56
      src/common/Data.h
  24. 11 11
      src/common/EnumMap.h
  25. 62 38
      src/common/Exception.cpp
  26. 64 68
      src/common/Exception.h
  27. 196 182
      src/common/Matrix.cpp
  28. 166 150
      src/common/Matrix.h
  29. 44 0
      src/common/Memoizer.cpp
  30. 18 13
      src/common/Memoizer.h
  31. 7 7
      src/common/Module.h
  32. 2 2
      src/common/Object.cpp
  33. 1 1
      src/common/Object.h
  34. 81 70
      src/common/Reference.cpp
  35. 7 7
      src/common/Reference.h
  36. 23 20
      src/common/StringMap.h
  37. 173 0
      src/common/Variant.cpp
  38. 73 0
      src/common/Variant.h
  39. 25 25
      src/common/Vector.cpp
  40. 310 310
      src/common/Vector.h
  41. 14 13
      src/common/b64.cpp
  42. 4 4
      src/common/b64.h
  43. 14 4
      src/common/config.h
  44. 41 0
      src/common/delay.cpp
  45. 33 0
      src/common/delay.h
  46. 64 0
      src/common/int.h
  47. 98 84
      src/common/math.h
  48. 480 432
      src/common/runtime.cpp
  49. 58 9
      src/common/runtime.h
  50. 173 161
      src/common/types.h
  51. 12 12
      src/common/utf8.cpp
  52. 4 4
      src/common/utf8.h
  53. 6 7
      src/common/version.h
  54. 5 5
      src/common/wrap_Data.cpp
  55. 4 4
      src/common/wrap_Data.h
  56. 67 0
      src/libraries/Box2D/Box2D.h
  57. 171 0
      src/libraries/Box2D/Collision/Shapes/b2ChainShape.cpp
  58. 102 0
      src/libraries/Box2D/Collision/Shapes/b2ChainShape.h
  59. 100 0
      src/libraries/Box2D/Collision/Shapes/b2CircleShape.cpp
  60. 91 0
      src/libraries/Box2D/Collision/Shapes/b2CircleShape.h
  61. 139 0
      src/libraries/Box2D/Collision/Shapes/b2EdgeShape.cpp
  62. 74 0
      src/libraries/Box2D/Collision/Shapes/b2EdgeShape.h
  63. 361 0
      src/libraries/Box2D/Collision/Shapes/b2PolygonShape.cpp
  64. 95 0
      src/libraries/Box2D/Collision/Shapes/b2PolygonShape.h
  65. 101 0
      src/libraries/Box2D/Collision/Shapes/b2Shape.h
  66. 122 0
      src/libraries/Box2D/Collision/b2BroadPhase.cpp
  67. 248 0
      src/libraries/Box2D/Collision/b2BroadPhase.h
  68. 154 0
      src/libraries/Box2D/Collision/b2CollideCircle.cpp
  69. 698 0
      src/libraries/Box2D/Collision/b2CollideEdge.cpp
  70. 317 0
      src/libraries/Box2D/Collision/b2CollidePolygon.cpp
  71. 249 0
      src/libraries/Box2D/Collision/b2Collision.cpp
  72. 276 0
      src/libraries/Box2D/Collision/b2Collision.h
  73. 603 0
      src/libraries/Box2D/Collision/b2Distance.cpp
  74. 141 0
      src/libraries/Box2D/Collision/b2Distance.h
  75. 771 0
      src/libraries/Box2D/Collision/b2DynamicTree.cpp
  76. 284 0
      src/libraries/Box2D/Collision/b2DynamicTree.h
  77. 483 0
      src/libraries/Box2D/Collision/b2TimeOfImpact.cpp
  78. 58 0
      src/libraries/Box2D/Collision/b2TimeOfImpact.h
  79. 19 8
      src/libraries/Box2D/Common/b2BlockAllocator.cpp
  80. 9 6
      src/libraries/Box2D/Common/b2BlockAllocator.h
  81. 23 12
      src/libraries/Box2D/Common/b2Draw.cpp
  82. 81 0
      src/libraries/Box2D/Common/b2Draw.h
  83. 85 0
      src/libraries/Box2D/Common/b2GrowableStack.h
  84. 94 0
      src/libraries/Box2D/Common/b2Math.cpp
  85. 731 0
      src/libraries/Box2D/Common/b2Math.h
  86. 22 21
      src/libraries/Box2D/Common/b2Settings.cpp
  87. 57 82
      src/libraries/Box2D/Common/b2Settings.h
  88. 3 3
      src/libraries/Box2D/Common/b2StackAllocator.cpp
  89. 2 2
      src/libraries/Box2D/Common/b2StackAllocator.h
  90. 100 0
      src/libraries/Box2D/Common/b2Timer.cpp
  91. 45 0
      src/libraries/Box2D/Common/b2Timer.h
  92. 54 0
      src/libraries/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.cpp
  93. 39 0
      src/libraries/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.h
  94. 54 0
      src/libraries/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.cpp
  95. 39 0
      src/libraries/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.h
  96. 53 0
      src/libraries/Box2D/Dynamics/Contacts/b2CircleContact.cpp
  97. 8 15
      src/libraries/Box2D/Dynamics/Contacts/b2CircleContact.h
  98. 240 0
      src/libraries/Box2D/Dynamics/Contacts/b2Contact.cpp
  99. 331 0
      src/libraries/Box2D/Dynamics/Contacts/b2Contact.h
  100. 832 0
      src/libraries/Box2D/Dynamics/Contacts/b2ContactSolver.cpp

+ 1 - 0
.hgtags

@@ -3,3 +3,4 @@
 db7cd0682883ed357adef013a326bbb26de28c98 0.6.2
 db7cd0682883ed357adef013a326bbb26de28c98 0.6.2
 9240be0fe0ea1070bc604954ab2e81320e278ad9 0.7.0
 9240be0fe0ea1070bc604954ab2e81320e278ad9 0.7.0
 18d79c306466d188919c238d23e50ea705b07c03 0.7.1
 18d79c306466d188919c238d23e50ea705b07c03 0.7.1
+bcca82b60d0f5cd724edbe4ed65db18ab95d4691 0.7.2

+ 110 - 0
changes.txt

@@ -1,3 +1,113 @@
+LOVE 0.8.0 [Rubber Piggy]
+-------------------------
+
+  * Added release error screen.
+  * Added alpha to love.graphics.setBackgroundColor.
+  * Added Canvas:clear(r, g, b, a).
+  * Added Canvas support to love.graphics.drawq.
+  * Added Canvas:getWidth and Canvas:getHeight.
+  * Added love.graphics.arc.
+  * Added seek and tell to Source objects.
+  * Added color interpolation to ParticleSystem.
+  * Added automatic PO2 padding for systems not supporting the OpenGL extension.
+  * Added UTF-8 support for fonts.
+  * Added Box2D error handling for some commonly failing functions.
+  * Added ability for fused release games to have their write dir in appdata.
+  * Added shear transformation to drawing functions.
+  * Added origin to font printing.
+  * Added love.graphics.getMode.
+  * Added per-sprite colors on SpriteBatches.
+  * Added pixel effects.
+  * Added love.graphics.isSupported.
+  * Added love.graphics.getCanvas.
+  * Added love.event.quit.
+  * Added stencil masks.
+  * Added alternative SpriteBatch provider, it should work everywhere now.
+  * Added a loader for binary modules.
+  * Added Thread:getKeys.
+  * Added option of fractions for Quads.
+  * Added PNG, JPEG and GIF support to ImageData:encode.
+  * Added 64-bit support for Mac OS X.
+  * Added premultiplied blending mode.
+  * Added functions to set/get default image filter modes.
+  * Added SpriteBatch:set.
+  * Added new events system, with support for custom events and long event names.
+  * Added sound attenuation by distance.
+  * Added SpriteBatch:getImage.
+
+  * Fixed wrapping for single words.
+  * Fixed tracebacks not showing filenames.
+  * Fixed love.graphics.push/pop capable of causing overflows/underflows.
+  * Fixed setScissor on Canvases.
+  * Fixed several issues with audio, e.g. clicks and pops in mp3s.
+  * Fixed crashes when bodies were destroyed during collisions.
+  * Fixed bound SpriteBatches corrupting when drawing.
+  * Fixed thread-safety issues with ImageData.
+  * Fixed memory leaks in audio sources.
+  * Fixed thread's set (previously send) accidentally changing the type.
+  * Fixed SoundData allocating the wrong number of samples.
+  * Fixed SpriteBatch support on Intel cards.
+  * Fixed love.filesystem.lines() leaking.
+  * Fixed Source controls inconsistencies.
+  * Fixed most leaking on unclosed File objects.
+  * Fixed crashes when operating on non-existent files.
+  * Fixed a bug where empty files on windows would never reach eof.
+  * Fixed crash when SoundData runs out of memory.
+  * Fixed ordering of loaders, love should have priority over Lua.
+  * Fixed several miscellaneous memory leaks.
+  * Fixed love.filesystem's priority for require.
+  * Fixed a few cases where strings with \0 in them would not be stored correctly.
+  * Fixed love's startup time being in the first dt.
+  * Fixed internal string conversions, they are faster now.
+  * Fixed (bad) performance of ImageData:paste.
+
+  * Renamed SpriteBatch's lock/unlock to bind/unbind.
+  * Renamed Framebuffer to Canvas.
+  * Renamed love.thread.send/receive to set/get.
+  * Renamed love.graphics.setRenderTarget to setCanvas.
+
+  * Removed canvas auto-clearing.
+  * Removed EncodedImageData.
+  * Removed old syntax for require (with extension).
+  * Removed love.graphics.setFont([file], [size]).
+  * Removed Thread:kill.
+
+  * Updated love.joystick to be 1-indexed.
+  * Updated Sources to update more cleanly and control more intuitively.
+  * Updated font engine.
+  * Updated line drawing to a custom system.
+  * Updated love.timer.sleep to use seconds, like the rest of love.
+  * Updated love.timer to be more accurate.
+  * Updated love.graphics.circle to have max(10, r) as default for segments.
+  * Updated ImageData:encode to write to files directly.
+  * Updated version compatibility system to actually do something.
+  * Updated love.run's order, events are checked just before update.
+  * Updated Box2D to version 2.2.1.
+
+LOVE 0.7.2 [Game Slave]
+-----------------------
+
+  * Added Framebuffer:get/setWrap.
+  * Added love.event.clear.
+  * Added support for any number of arguments to love.keyboard.isDown, love.mouse.isDown and love.joystick.isDown.
+  * Added SpriteBatch:setImage().
+
+  * Fixed fused games not working.
+  * Fixed ParticleSystem:setSize ignoring the variation argument.
+  * Fixed some file-opening exceptions not being caught.
+  * Fixed files loaded by libmodplug being too loud.
+  * Fixed paths with periods in them not working.
+  * Fixed love.graphics.getBlendMode not detecting subtractive and multiplicative blend modes.
+  * Fixed crash when there was no memory available for newImageData(w, h).
+
+  * Updated PhysicsFS version to 2.0.2 on Windows
+  * Updated OpenAL Soft version to 1.13 on Windows
+  * Updated libmodplug version to 0.8.8.1 on Windows
+  * Updated FreeType version to 2.4.4 on Windows
+  * Updated libmpg123 version to 1.13.2 on Windows
+  * Windows binary no longer depends on VC2005 runtime.
+  * Windows binary no longer depends on SSE2 support.
+
 LOVE 0.7.1 [Game Slave]
 LOVE 0.7.1 [Game Slave]
 -----------------------
 -----------------------
 
 

+ 32 - 9
configure.in

@@ -13,14 +13,17 @@ AC_SEARCH_LIBS([SDL_Init], [SDL], [], AC_MSG_ERROR([Can't LÖVE without SDL]))
 AC_SEARCH_LIBS([glLoadIdentity], [GL], [], AC_MSG_ERROR([Can't LÖVE without OpenGL]))
 AC_SEARCH_LIBS([glLoadIdentity], [GL], [], AC_MSG_ERROR([Can't LÖVE without OpenGL]))
 #AC_SEARCH_LIBS([gluOrtho2D], [GLU], [], AC_MSG_ERROR([Can't LÖVE without OpenGL Utility Library]))
 #AC_SEARCH_LIBS([gluOrtho2D], [GLU], [], AC_MSG_ERROR([Can't LÖVE without OpenGL Utility Library]))
 AC_SEARCH_LIBS([alSourcePlay], [openal], [], AC_MSG_ERROR([Can't LÖVE without OpenAL]))
 AC_SEARCH_LIBS([alSourcePlay], [openal], [], AC_MSG_ERROR([Can't LÖVE without OpenAL]))
-AC_ARG_ENABLE([luajit],
-	[  --enable-luajit Use LuaJIT instead of lua],
-	AC_SEARCH_LIBS(
-		[lua_pcall],
-		[luajit luajit-5.1],
-		AC_SUBST([INCLUDE_LUA], [-I/usr/include/luajit-2.0]),
-		AC_MSG_ERROR([Can't LÖVE without LuaJIT])
-	),
+lua=lua
+AC_ARG_WITH([luajit],
+	    [AS_HELP_STRING([--with-luajit], [Use LuaJIT instead of lua and llvm-lua])],
+	    [lua=luajit],
+	    [])
+AC_ARG_WITH([llvm-lua],
+	    [AS_HELP_STRING([--with-llvm-lua], [Use llvm-lua instead of lua and LuaJIT])],
+	    [lua=llvm-lua],
+	    [])
+
+AS_IF([test "$lua" == "lua"],
 	AC_SEARCH_LIBS(
 	AC_SEARCH_LIBS(
 		[lua_pcall],
 		[lua_pcall],
 		[lua lua5.1],
 		[lua lua5.1],
@@ -29,7 +32,24 @@ AC_ARG_ENABLE([luajit],
 		fi,
 		fi,
 		AC_MSG_ERROR([Can't LÖVE without Lua])
 		AC_MSG_ERROR([Can't LÖVE without Lua])
 	)
 	)
-)
+      )
+AS_IF([test "$lua" == "luajit"],
+	AC_SEARCH_LIBS(
+		[lua_pcall],
+		[luajit luajit-5.1],
+		AC_SUBST([INCLUDE_LUA], [-I/usr/include/luajit-2.0]),
+		AC_MSG_ERROR([Can't LÖVE without LuaJIT])
+	)
+      )
+AS_IF([test "$lua" == "llvm-lua"],
+	AC_SEARCH_LIBS(
+		[lua_pcall],
+		[llvm-lua],
+		[],
+		AC_MSG_ERROR([Can't LÖVE without llvm-lua])
+	)
+      )
+
 AC_SEARCH_LIBS([ilInit], [IL], [], AC_MSG_ERROR([Can't LÖVE without DevIL]))
 AC_SEARCH_LIBS([ilInit], [IL], [], AC_MSG_ERROR([Can't LÖVE without DevIL]))
 AC_SEARCH_LIBS([mng_initialize], [mng], [], AC_MSG_ERROR([DevIL needs MNG]))
 AC_SEARCH_LIBS([mng_initialize], [mng], [], AC_MSG_ERROR([DevIL needs MNG]))
 AC_SEARCH_LIBS([TIFFOpen], [tiff], [], AC_MSG_ERROR([DevIL needs TIFF]))
 AC_SEARCH_LIBS([TIFFOpen], [tiff], [], AC_MSG_ERROR([DevIL needs TIFF]))
@@ -39,6 +59,9 @@ AC_SEARCH_LIBS([ModPlug_Load], [modplug], [], AC_MSG_ERROR([Can't LÖVE without
 AC_SEARCH_LIBS([mpg123_open_feed], [mpg123], [], AC_MSG_ERROR([Can't LÖVE without Mpg123]))
 AC_SEARCH_LIBS([mpg123_open_feed], [mpg123], [], AC_MSG_ERROR([Can't LÖVE without Mpg123]))
 AC_SEARCH_LIBS([mpg123_seek_64], [mpg123], AC_SUBST([FILE_OFFSET],[-D_FILE_OFFSET_BITS=64]), AC_SUBST([FILE_OFFSET],[]))
 AC_SEARCH_LIBS([mpg123_seek_64], [mpg123], AC_SUBST([FILE_OFFSET],[-D_FILE_OFFSET_BITS=64]), AC_SUBST([FILE_OFFSET],[]))
 AC_SEARCH_LIBS([ov_open], [vorbisfile], [], AC_MSG_ERROR([Can't LÖVE without VorbisFile]))
 AC_SEARCH_LIBS([ov_open], [vorbisfile], [], AC_MSG_ERROR([Can't LÖVE without VorbisFile]))
+AC_ARG_ENABLE([headless],
+	      [  --enable-headless Build with less SDL],
+	      AC_DEFINE([LOVE_HEADLESS], [], [Build with less SDL]), [])
 AC_CONFIG_FILES([
 AC_CONFIG_FILES([
 	Makefile
 	Makefile
 	src/Makefile
 	src/Makefile

+ 14 - 12
extra/nsis/love.nsi

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

+ 12 - 0
extra/resources/b64.lua

@@ -0,0 +1,12 @@
+function b64(name)
+	local i = io.popen("base64 " .. name)
+	local encoded = i:read("*a")
+	i:close()
+
+	local output = ("local %s =\n%q"):format(name:gsub("%.", "_"), encoded)
+	return output
+end
+
+for i, v in ipairs(arg) do
+	print(b64(v))
+end

BIN
extra/resources/heart.png


BIN
extra/resources/knoll1.png


BIN
extra/resources/love.png


BIN
extra/resources/pig.png


BIN
extra/resources/planet.png


BIN
extra/resources/star1.png


+ 863 - 1
license.txt

@@ -17,4 +17,866 @@ appreciated but is not required.
 misrepresented as being the original software.
 misrepresented as being the original software.
 
 
 3. This notice may not be removed or altered from any source
 3. This notice may not be removed or altered from any source
-distribution.
+distribution.
+
+
+
+
+-------
+LÖVE also uses the following LGPL libraries:
+
+ - SDL
+     Website: http://libsdl.org
+     Source download: http://www.libsdl.org/release/SDL-1.2.14.tar.gz
+ - libmpg123
+     Website: http://www.mpg123.de/
+     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
+ - DevIL
+     Website: http://openil.sourceforge.net/
+     Source download: http://downloads.sourceforge.net/openil/DevIL-1.7.8.tar.gz
+
+Following are the LGPL and GPL license texts:
+
+                   GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+  This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+  0. Additional Definitions.
+
+  As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+  "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+  An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+  A "Combined Work" is a work produced by combining or linking an
+Application with the Library.  The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+  The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+  The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+  1. Exception to Section 3 of the GNU GPL.
+
+  You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+  2. Conveying Modified Versions.
+
+  If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+   a) under this License, provided that you make a good faith effort to
+   ensure that, in the event an Application does not supply the
+   function or data, the facility still operates, and performs
+   whatever part of its purpose remains meaningful, or
+
+   b) under the GNU GPL, with none of the additional permissions of
+   this License applicable to that copy.
+
+  3. Object Code Incorporating Material from Library Header Files.
+
+  The object code form of an Application may incorporate material from
+a header file that is part of the Library.  You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+   a) Give prominent notice with each copy of the object code that the
+   Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the object code with a copy of the GNU GPL and this license
+   document.
+
+  4. Combined Works.
+
+  You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+   a) Give prominent notice with each copy of the Combined Work that
+   the Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the Combined Work with a copy of the GNU GPL and this license
+   document.
+
+   c) For a Combined Work that displays copyright notices during
+   execution, include the copyright notice for the Library among
+   these notices, as well as a reference directing the user to the
+   copies of the GNU GPL and this license document.
+
+   d) Do one of the following:
+
+       0) Convey the Minimal Corresponding Source under the terms of this
+       License, and the Corresponding Application Code in a form
+       suitable for, and under terms that permit, the user to
+       recombine or relink the Application with a modified version of
+       the Linked Version to produce a modified Combined Work, in the
+       manner specified by section 6 of the GNU GPL for conveying
+       Corresponding Source.
+
+       1) Use a suitable shared library mechanism for linking with the
+       Library.  A suitable mechanism is one that (a) uses at run time
+       a copy of the Library already present on the user's computer
+       system, and (b) will operate properly with a modified version
+       of the Library that is interface-compatible with the Linked
+       Version.
+
+   e) Provide Installation Information, but only if you would otherwise
+   be required to provide such information under section 6 of the
+   GNU GPL, and only to the extent that such information is
+   necessary to install and execute a modified version of the
+   Combined Work produced by recombining or relinking the
+   Application with a modified version of the Linked Version. (If
+   you use option 4d0, the Installation Information must accompany
+   the Minimal Corresponding Source and Corresponding Application
+   Code. If you use option 4d1, you must provide the Installation
+   Information in the manner specified by section 6 of the GNU GPL
+   for conveying Corresponding Source.)
+
+  5. Combined Libraries.
+
+  You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+   a) Accompany the combined library with a copy of the same work based
+   on the Library, uncombined with any other library facilities,
+   conveyed under the terms of this License.
+
+   b) Give prominent notice with the combined library that part of it
+   is a work based on the Library, and explaining where to find the
+   accompanying uncombined form of the same work.
+
+  6. Revised Versions of the GNU Lesser General Public License.
+
+  The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+  Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+  If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
+
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.

+ 36 - 42
platform/macosx/love-Info.plist

@@ -7,28 +7,18 @@
 	<key>CFBundleDocumentTypes</key>
 	<key>CFBundleDocumentTypes</key>
 	<array>
 	<array>
 		<dict>
 		<dict>
-			<key>CFBundleTypeExtensions</key>
-			<array>
-				<string>love</string>
-			</array>
 			<key>CFBundleTypeIconFile</key>
 			<key>CFBundleTypeIconFile</key>
 			<string>LoveDocument.icns</string>
 			<string>LoveDocument.icns</string>
 			<key>CFBundleTypeName</key>
 			<key>CFBundleTypeName</key>
-			<string>Love Project</string>
-			<key>CFBundleTypeOSTypes</key>
-			<array>
-				<string>LOVE</string>
-			</array>
-			<key>CFBundleTypeMIMETypes</key>
-			<array>
-				<string>application/x-love-game</string>
-			</array>
+			<string>LÖVE Project</string>
 			<key>CFBundleTypeRole</key>
 			<key>CFBundleTypeRole</key>
 			<string>Viewer</string>
 			<string>Viewer</string>
-			<key>LSIsAppleDefaultForType</key>
-			<true/>
-			<key>LSTypeIsPackage</key>
-			<true/>
+			<key>LSItemContentTypes</key>
+			<array>
+				<string>org.love2d.love-game</string>
+			</array>
+			<key>LSHandlerRank</key>
+			<string>Owner</string>
 		</dict>
 		</dict>
 		<dict>
 		<dict>
 			<key>CFBundleTypeName</key>
 			<key>CFBundleTypeName</key>
@@ -39,8 +29,32 @@
 			</array>
 			</array>
 			<key>CFBundleTypeRole</key>
 			<key>CFBundleTypeRole</key>
 			<string>Viewer</string>
 			<string>Viewer</string>
+			<key>LSHandlerRank</key>
+			<string>None</string>
 		</dict>
 		</dict>
 	</array>
 	</array>
+	<key>CFBundleExecutable</key>
+	<string>love</string>
+	<key>CFBundleIconFile</key>
+	<string>Love.icns</string>
+	<key>CFBundleIdentifier</key>
+	<string>org.love2d.love</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>LÖVE</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>0.8.0</string>
+	<key>CFBundleSignature</key>
+	<string>LoVe</string>
+	<key>NSHumanReadableCopyright</key>
+	<string>© 2006-2012 LÖVE Development Team</string>
+	<key>NSMainNibFile</key>
+	<string>SDLMain</string>
+	<key>NSPrincipalClass</key>
+	<string>NSApplication</string>
 	<key>UTExportedTypeDeclarations</key>
 	<key>UTExportedTypeDeclarations</key>
 	<array>
 	<array>
 		<dict>
 		<dict>
@@ -48,12 +62,14 @@
 			<array>
 			<array>
 				<string>com.pkware.zip-archive</string>
 				<string>com.pkware.zip-archive</string>
 			</array>
 			</array>
-			<key>UTTypeIdentifier</key>
-			<string>org.love2d.love-game</string>
 			<key>UTTypeDescription</key>
 			<key>UTTypeDescription</key>
-			<string>Love Project</string>
+			<string>LÖVE Project</string>
 			<key>UTTypeIconFile</key>
 			<key>UTTypeIconFile</key>
 			<string>LoveDocument.icns</string>
 			<string>LoveDocument.icns</string>
+			<key>UTTypeIdentifier</key>
+			<string>org.love2d.love-game</string>
+			<key>UTTypeReferenceURL</key>
+			<string>http://love2d.org/wiki/Game_Distribution</string>
 			<key>UTTypeTagSpecification</key>
 			<key>UTTypeTagSpecification</key>
 			<dict>
 			<dict>
 				<key>com.apple.ostype</key>
 				<key>com.apple.ostype</key>
@@ -65,29 +81,7 @@
 				<key>public.mime-type</key>
 				<key>public.mime-type</key>
 				<string>application/x-love-game</string>
 				<string>application/x-love-game</string>
 			</dict>
 			</dict>
-			<key>UTTypeReferenceURL</key>
-			<string>http://love2d.org/wiki/Game_Distribution</string>
 		</dict>
 		</dict>
 	</array>
 	</array>
-	<key>CFBundleExecutable</key>
-	<string>love</string>
-	<key>CFBundleIconFile</key>
-	<string>Love.icns</string>
-	<key>CFBundleIdentifier</key>
-	<string>org.love2d.love</string>
-	<key>CFBundleInfoDictionaryVersion</key>
-	<string>6.0</string>
-	<key>CFBundleName</key>
-	<string>love</string>
-	<key>CFBundlePackageType</key>
-	<string>LoVe</string>
-	<key>CFBundleSignature</key>
-	<string>LoVe</string>
-	<key>CFBundleVersion</key>
-	<string>0.7.1</string>
-	<key>NSMainNibFile</key>
-	<string>SDLMain</string>
-	<key>NSPrincipalClass</key>
-	<string>NSApplication</string>
 </dict>
 </dict>
 </plist>
 </plist>

File diff suppressed because it is too large
+ 519 - 274
platform/macosx/love.xcodeproj/project.pbxproj


BIN
platform/msvc2010/app.rc


+ 193 - 56
platform/msvc2010/love.vcxproj

@@ -12,15 +12,62 @@
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\src\common\b64.cpp" />
     <ClCompile Include="..\..\src\common\b64.cpp" />
+    <ClCompile Include="..\..\src\common\delay.cpp" />
     <ClCompile Include="..\..\src\common\Exception.cpp" />
     <ClCompile Include="..\..\src\common\Exception.cpp" />
     <ClCompile Include="..\..\src\common\Matrix.cpp" />
     <ClCompile Include="..\..\src\common\Matrix.cpp" />
-    <ClCompile Include="..\..\src\common\MemoryData.cpp" />
+    <ClCompile Include="..\..\src\common\Memoizer.cpp" />
     <ClCompile Include="..\..\src\common\Object.cpp" />
     <ClCompile Include="..\..\src\common\Object.cpp" />
     <ClCompile Include="..\..\src\common\Reference.cpp" />
     <ClCompile Include="..\..\src\common\Reference.cpp" />
     <ClCompile Include="..\..\src\common\runtime.cpp" />
     <ClCompile Include="..\..\src\common\runtime.cpp" />
     <ClCompile Include="..\..\src\common\utf8.cpp" />
     <ClCompile Include="..\..\src\common\utf8.cpp" />
+    <ClCompile Include="..\..\src\common\Variant.cpp" />
     <ClCompile Include="..\..\src\common\Vector.cpp" />
     <ClCompile Include="..\..\src\common\Vector.cpp" />
     <ClCompile Include="..\..\src\common\wrap_Data.cpp" />
     <ClCompile Include="..\..\src\common\wrap_Data.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Collision\b2BroadPhase.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Collision\b2CollideCircle.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Collision\b2CollideEdge.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Collision\b2CollidePolygon.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Collision\b2Collision.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Collision\b2Distance.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Collision\b2DynamicTree.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Collision\b2TimeOfImpact.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Collision\Shapes\b2ChainShape.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Collision\Shapes\b2CircleShape.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Collision\Shapes\b2EdgeShape.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Collision\Shapes\b2PolygonShape.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Common\b2BlockAllocator.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Common\b2Draw.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Common\b2Math.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Common\b2Settings.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Common\b2StackAllocator.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Common\b2Timer.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Dynamics\b2Body.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Dynamics\b2ContactManager.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Dynamics\b2Fixture.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Dynamics\b2Island.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Dynamics\b2World.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Dynamics\b2WorldCallbacks.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Dynamics\Contacts\b2ChainAndCircleContact.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Dynamics\Contacts\b2ChainAndPolygonContact.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Dynamics\Contacts\b2CircleContact.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Dynamics\Contacts\b2Contact.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Dynamics\Contacts\b2ContactSolver.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Dynamics\Contacts\b2EdgeAndCircleContact.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Dynamics\Contacts\b2EdgeAndPolygonContact.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Dynamics\Contacts\b2PolygonAndCircleContact.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Dynamics\Contacts\b2PolygonContact.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Dynamics\Joints\b2DistanceJoint.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Dynamics\Joints\b2FrictionJoint.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Dynamics\Joints\b2GearJoint.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Dynamics\Joints\b2Joint.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Dynamics\Joints\b2MouseJoint.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Dynamics\Joints\b2PrismaticJoint.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Dynamics\Joints\b2PulleyJoint.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Dynamics\Joints\b2RevoluteJoint.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Dynamics\Joints\b2RopeJoint.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Dynamics\Joints\b2WeldJoint.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Dynamics\Joints\b2WheelJoint.cpp" />
+    <ClCompile Include="..\..\src\libraries\Box2D\Rope\b2Rope.cpp" />
     <ClCompile Include="..\..\src\libraries\luasocket\libluasocket\auxiliar.c">
     <ClCompile Include="..\..\src\libraries\luasocket\libluasocket\auxiliar.c">
       <WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">TurnOffAllWarnings</WarningLevel>
       <WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">TurnOffAllWarnings</WarningLevel>
     </ClCompile>
     </ClCompile>
@@ -64,6 +111,7 @@
     <ClCompile Include="..\..\src\love.cpp">
     <ClCompile Include="..\..\src\love.cpp">
       <ShowIncludes Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ShowIncludes>
       <ShowIncludes Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ShowIncludes>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="..\..\src\modules\audio\Audio.cpp" />
     <ClCompile Include="..\..\src\modules\audio\null\Audio.cpp" />
     <ClCompile Include="..\..\src\modules\audio\null\Audio.cpp" />
     <ClCompile Include="..\..\src\modules\audio\null\Source.cpp" />
     <ClCompile Include="..\..\src\modules\audio\null\Source.cpp" />
     <ClCompile Include="..\..\src\modules\audio\openal\Audio.cpp" />
     <ClCompile Include="..\..\src\modules\audio\openal\Audio.cpp" />
@@ -91,25 +139,31 @@
     <ClCompile Include="..\..\src\modules\font\wrap_GlyphData.cpp" />
     <ClCompile Include="..\..\src\modules\font\wrap_GlyphData.cpp" />
     <ClCompile Include="..\..\src\modules\font\wrap_Rasterizer.cpp" />
     <ClCompile Include="..\..\src\modules\font\wrap_Rasterizer.cpp" />
     <ClCompile Include="..\..\src\modules\graphics\Drawable.cpp" />
     <ClCompile Include="..\..\src\modules\graphics\Drawable.cpp" />
+    <ClCompile Include="..\..\src\modules\graphics\DrawQable.cpp" />
     <ClCompile Include="..\..\src\modules\graphics\Graphics.cpp" />
     <ClCompile Include="..\..\src\modules\graphics\Graphics.cpp" />
     <ClCompile Include="..\..\src\modules\graphics\Image.cpp" />
     <ClCompile Include="..\..\src\modules\graphics\Image.cpp" />
+    <ClCompile Include="..\..\src\modules\graphics\opengl\Canvas.cpp" />
     <ClCompile Include="..\..\src\modules\graphics\opengl\Font.cpp" />
     <ClCompile Include="..\..\src\modules\graphics\opengl\Font.cpp" />
-    <ClCompile Include="..\..\src\modules\graphics\opengl\Framebuffer.cpp" />
     <ClCompile Include="..\..\src\modules\graphics\opengl\GLee.c">
     <ClCompile Include="..\..\src\modules\graphics\opengl\GLee.c">
       <WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">TurnOffAllWarnings</WarningLevel>
       <WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">TurnOffAllWarnings</WarningLevel>
     </ClCompile>
     </ClCompile>
     <ClCompile Include="..\..\src\modules\graphics\opengl\Graphics.cpp" />
     <ClCompile Include="..\..\src\modules\graphics\opengl\Graphics.cpp" />
     <ClCompile Include="..\..\src\modules\graphics\opengl\Image.cpp" />
     <ClCompile Include="..\..\src\modules\graphics\opengl\Image.cpp" />
+    <ClCompile Include="..\..\src\modules\graphics\opengl\OpenGL.cpp" />
     <ClCompile Include="..\..\src\modules\graphics\opengl\ParticleSystem.cpp" />
     <ClCompile Include="..\..\src\modules\graphics\opengl\ParticleSystem.cpp" />
+    <ClCompile Include="..\..\src\modules\graphics\opengl\PixelEffect.cpp" />
     <ClCompile Include="..\..\src\modules\graphics\opengl\Quad.cpp" />
     <ClCompile Include="..\..\src\modules\graphics\opengl\Quad.cpp" />
     <ClCompile Include="..\..\src\modules\graphics\opengl\SpriteBatch.cpp" />
     <ClCompile Include="..\..\src\modules\graphics\opengl\SpriteBatch.cpp" />
+    <ClCompile Include="..\..\src\modules\graphics\opengl\VertexBuffer.cpp" />
+    <ClCompile Include="..\..\src\modules\graphics\opengl\wrap_Canvas.cpp" />
     <ClCompile Include="..\..\src\modules\graphics\opengl\wrap_Font.cpp" />
     <ClCompile Include="..\..\src\modules\graphics\opengl\wrap_Font.cpp" />
-    <ClCompile Include="..\..\src\modules\graphics\opengl\wrap_Framebuffer.cpp" />
     <ClCompile Include="..\..\src\modules\graphics\opengl\wrap_Graphics.cpp" />
     <ClCompile Include="..\..\src\modules\graphics\opengl\wrap_Graphics.cpp" />
     <ClCompile Include="..\..\src\modules\graphics\opengl\wrap_Image.cpp" />
     <ClCompile Include="..\..\src\modules\graphics\opengl\wrap_Image.cpp" />
     <ClCompile Include="..\..\src\modules\graphics\opengl\wrap_ParticleSystem.cpp" />
     <ClCompile Include="..\..\src\modules\graphics\opengl\wrap_ParticleSystem.cpp" />
+    <ClCompile Include="..\..\src\modules\graphics\opengl\wrap_PixelEffect.cpp" />
     <ClCompile Include="..\..\src\modules\graphics\opengl\wrap_Quad.cpp" />
     <ClCompile Include="..\..\src\modules\graphics\opengl\wrap_Quad.cpp" />
     <ClCompile Include="..\..\src\modules\graphics\opengl\wrap_SpriteBatch.cpp" />
     <ClCompile Include="..\..\src\modules\graphics\opengl\wrap_SpriteBatch.cpp" />
+    <ClCompile Include="..\..\src\modules\graphics\Quad.cpp" />
     <ClCompile Include="..\..\src\modules\graphics\Volatile.cpp" />
     <ClCompile Include="..\..\src\modules\graphics\Volatile.cpp" />
     <ClCompile Include="..\..\src\modules\image\devil\Image.cpp" />
     <ClCompile Include="..\..\src\modules\image\devil\Image.cpp" />
     <ClCompile Include="..\..\src\modules\image\devil\ImageData.cpp" />
     <ClCompile Include="..\..\src\modules\image\devil\ImageData.cpp" />
@@ -121,16 +175,20 @@
     <ClCompile Include="..\..\src\modules\joystick\sdl\wrap_Joystick.cpp" />
     <ClCompile Include="..\..\src\modules\joystick\sdl\wrap_Joystick.cpp" />
     <ClCompile Include="..\..\src\modules\keyboard\Keyboard.cpp" />
     <ClCompile Include="..\..\src\modules\keyboard\Keyboard.cpp" />
     <ClCompile Include="..\..\src\modules\keyboard\sdl\Keyboard.cpp" />
     <ClCompile Include="..\..\src\modules\keyboard\sdl\Keyboard.cpp" />
-    <ClCompile Include="..\..\src\modules\keyboard\sdl\wrap_Keyboard.cpp" />
+    <ClCompile Include="..\..\src\modules\keyboard\wrap_Keyboard.cpp" />
     <ClCompile Include="..\..\src\modules\mouse\Mouse.cpp" />
     <ClCompile Include="..\..\src\modules\mouse\Mouse.cpp" />
     <ClCompile Include="..\..\src\modules\mouse\sdl\Mouse.cpp" />
     <ClCompile Include="..\..\src\modules\mouse\sdl\Mouse.cpp" />
-    <ClCompile Include="..\..\src\modules\mouse\sdl\wrap_Mouse.cpp" />
+    <ClCompile Include="..\..\src\modules\mouse\wrap_Mouse.cpp" />
+    <ClCompile Include="..\..\src\modules\physics\Body.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\Body.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\Body.cpp" />
+    <ClCompile Include="..\..\src\modules\physics\box2d\ChainShape.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\CircleShape.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\CircleShape.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\Contact.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\Contact.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\DistanceJoint.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\DistanceJoint.cpp" />
+    <ClCompile Include="..\..\src\modules\physics\box2d\EdgeShape.cpp" />
+    <ClCompile Include="..\..\src\modules\physics\box2d\Fixture.cpp" />
+    <ClCompile Include="..\..\src\modules\physics\box2d\FrictionJoint.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\GearJoint.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\GearJoint.cpp" />
-    <ClCompile Include="..\..\src\modules\physics\box2d\graham\GrahamScanConvexHull.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\Joint.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\Joint.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\MouseJoint.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\MouseJoint.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\Physics.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\Physics.cpp" />
@@ -138,43 +196,19 @@
     <ClCompile Include="..\..\src\modules\physics\box2d\PrismaticJoint.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\PrismaticJoint.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\PulleyJoint.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\PulleyJoint.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\RevoluteJoint.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\RevoluteJoint.cpp" />
+    <ClCompile Include="..\..\src\modules\physics\box2d\RopeJoint.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\Shape.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\Shape.cpp" />
-    <ClCompile Include="..\..\src\modules\physics\box2d\Source\Collision\b2BroadPhase.cpp" />
-    <ClCompile Include="..\..\src\modules\physics\box2d\Source\Collision\b2CollideCircle.cpp" />
-    <ClCompile Include="..\..\src\modules\physics\box2d\Source\Collision\b2CollidePoly.cpp" />
-    <ClCompile Include="..\..\src\modules\physics\box2d\Source\Collision\b2Collision.cpp" />
-    <ClCompile Include="..\..\src\modules\physics\box2d\Source\Collision\b2Distance.cpp" />
-    <ClCompile Include="..\..\src\modules\physics\box2d\Source\Collision\b2PairManager.cpp" />
-    <ClCompile Include="..\..\src\modules\physics\box2d\Source\Collision\b2TimeOfImpact.cpp" />
-    <ClCompile Include="..\..\src\modules\physics\box2d\Source\Collision\Shapes\b2CircleShape.cpp" />
-    <ClCompile Include="..\..\src\modules\physics\box2d\Source\Collision\Shapes\b2PolygonShape.cpp" />
-    <ClCompile Include="..\..\src\modules\physics\box2d\Source\Collision\Shapes\b2Shape.cpp" />
-    <ClCompile Include="..\..\src\modules\physics\box2d\Source\Common\b2BlockAllocator.cpp" />
-    <ClCompile Include="..\..\src\modules\physics\box2d\Source\Common\b2Math.cpp" />
-    <ClCompile Include="..\..\src\modules\physics\box2d\Source\Common\b2Settings.cpp" />
-    <ClCompile Include="..\..\src\modules\physics\box2d\Source\Common\b2StackAllocator.cpp" />
-    <ClCompile Include="..\..\src\modules\physics\box2d\Source\Dynamics\b2Body.cpp" />
-    <ClCompile Include="..\..\src\modules\physics\box2d\Source\Dynamics\b2ContactManager.cpp" />
-    <ClCompile Include="..\..\src\modules\physics\box2d\Source\Dynamics\b2Island.cpp" />
-    <ClCompile Include="..\..\src\modules\physics\box2d\Source\Dynamics\b2World.cpp" />
-    <ClCompile Include="..\..\src\modules\physics\box2d\Source\Dynamics\b2WorldCallbacks.cpp" />
-    <ClCompile Include="..\..\src\modules\physics\box2d\Source\Dynamics\Contacts\b2CircleContact.cpp" />
-    <ClCompile Include="..\..\src\modules\physics\box2d\Source\Dynamics\Contacts\b2Contact.cpp" />
-    <ClCompile Include="..\..\src\modules\physics\box2d\Source\Dynamics\Contacts\b2ContactSolver.cpp" />
-    <ClCompile Include="..\..\src\modules\physics\box2d\Source\Dynamics\Contacts\b2PolyAndCircleContact.cpp" />
-    <ClCompile Include="..\..\src\modules\physics\box2d\Source\Dynamics\Contacts\b2PolyContact.cpp" />
-    <ClCompile Include="..\..\src\modules\physics\box2d\Source\Dynamics\Joints\b2DistanceJoint.cpp" />
-    <ClCompile Include="..\..\src\modules\physics\box2d\Source\Dynamics\Joints\b2GearJoint.cpp" />
-    <ClCompile Include="..\..\src\modules\physics\box2d\Source\Dynamics\Joints\b2Joint.cpp" />
-    <ClCompile Include="..\..\src\modules\physics\box2d\Source\Dynamics\Joints\b2MouseJoint.cpp" />
-    <ClCompile Include="..\..\src\modules\physics\box2d\Source\Dynamics\Joints\b2PrismaticJoint.cpp" />
-    <ClCompile Include="..\..\src\modules\physics\box2d\Source\Dynamics\Joints\b2PulleyJoint.cpp" />
-    <ClCompile Include="..\..\src\modules\physics\box2d\Source\Dynamics\Joints\b2RevoluteJoint.cpp" />
+    <ClCompile Include="..\..\src\modules\physics\box2d\WeldJoint.cpp" />
+    <ClCompile Include="..\..\src\modules\physics\box2d\WheelJoint.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\World.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\World.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\wrap_Body.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\wrap_Body.cpp" />
+    <ClCompile Include="..\..\src\modules\physics\box2d\wrap_ChainShape.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\wrap_CircleShape.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\wrap_CircleShape.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\wrap_Contact.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\wrap_Contact.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\wrap_DistanceJoint.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\wrap_DistanceJoint.cpp" />
+    <ClCompile Include="..\..\src\modules\physics\box2d\wrap_EdgeShape.cpp" />
+    <ClCompile Include="..\..\src\modules\physics\box2d\wrap_Fixture.cpp" />
+    <ClCompile Include="..\..\src\modules\physics\box2d\wrap_FrictionJoint.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\wrap_GearJoint.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\wrap_GearJoint.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\wrap_Joint.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\wrap_Joint.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\wrap_MouseJoint.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\wrap_MouseJoint.cpp" />
@@ -183,7 +217,10 @@
     <ClCompile Include="..\..\src\modules\physics\box2d\wrap_PrismaticJoint.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\wrap_PrismaticJoint.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\wrap_PulleyJoint.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\wrap_PulleyJoint.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\wrap_RevoluteJoint.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\wrap_RevoluteJoint.cpp" />
+    <ClCompile Include="..\..\src\modules\physics\box2d\wrap_RopeJoint.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\wrap_Shape.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\wrap_Shape.cpp" />
+    <ClCompile Include="..\..\src\modules\physics\box2d\wrap_WeldJoint.cpp" />
+    <ClCompile Include="..\..\src\modules\physics\box2d\wrap_WheelJoint.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\wrap_World.cpp" />
     <ClCompile Include="..\..\src\modules\physics\box2d\wrap_World.cpp" />
     <ClCompile Include="..\..\src\modules\physics\Joint.cpp" />
     <ClCompile Include="..\..\src\modules\physics\Joint.cpp" />
     <ClCompile Include="..\..\src\modules\physics\Shape.cpp" />
     <ClCompile Include="..\..\src\modules\physics\Shape.cpp" />
@@ -198,20 +235,36 @@
     <ClCompile Include="..\..\src\modules\sound\wrap_Decoder.cpp" />
     <ClCompile Include="..\..\src\modules\sound\wrap_Decoder.cpp" />
     <ClCompile Include="..\..\src\modules\sound\wrap_Sound.cpp" />
     <ClCompile Include="..\..\src\modules\sound\wrap_Sound.cpp" />
     <ClCompile Include="..\..\src\modules\sound\wrap_SoundData.cpp" />
     <ClCompile Include="..\..\src\modules\sound\wrap_SoundData.cpp" />
-    <ClCompile Include="..\..\src\modules\thread\sdl\Thread.cpp" />
-    <ClCompile Include="..\..\src\modules\thread\sdl\wrap_Thread.cpp" />
+    <ClCompile Include="..\..\src\modules\thread\posix\threads.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+    </ClCompile>
+    <ClCompile Include="..\..\src\modules\thread\sdl\threads.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+    </ClCompile>
+    <ClCompile Include="..\..\src\modules\thread\Thread.cpp" />
+    <ClCompile Include="..\..\src\modules\thread\threads.cpp" />
+    <ClCompile Include="..\..\src\modules\thread\win32\threads.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+    </ClCompile>
+    <ClCompile Include="..\..\src\modules\thread\wrap_Thread.cpp" />
     <ClCompile Include="..\..\src\modules\timer\sdl\Timer.cpp" />
     <ClCompile Include="..\..\src\modules\timer\sdl\Timer.cpp" />
-    <ClCompile Include="..\..\src\modules\timer\sdl\wrap_Timer.cpp" />
+    <ClCompile Include="..\..\src\modules\timer\wrap_Timer.cpp" />
+    <ClCompile Include="..\..\src\modules\window\sdl\Window.cpp" />
+    <ClCompile Include="..\..\src\modules\window\Window.cpp" />
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\src\common\b64.h" />
     <ClInclude Include="..\..\src\common\b64.h" />
     <ClInclude Include="..\..\src\common\config.h" />
     <ClInclude Include="..\..\src\common\config.h" />
     <ClInclude Include="..\..\src\common\Data.h" />
     <ClInclude Include="..\..\src\common\Data.h" />
+    <ClInclude Include="..\..\src\common\delay.h" />
     <ClInclude Include="..\..\src\common\EnumMap.h" />
     <ClInclude Include="..\..\src\common\EnumMap.h" />
     <ClInclude Include="..\..\src\common\Exception.h" />
     <ClInclude Include="..\..\src\common\Exception.h" />
     <ClInclude Include="..\..\src\common\math.h" />
     <ClInclude Include="..\..\src\common\math.h" />
     <ClInclude Include="..\..\src\common\Matrix.h" />
     <ClInclude Include="..\..\src\common\Matrix.h" />
-    <ClInclude Include="..\..\src\common\MemoryData.h" />
+    <ClInclude Include="..\..\src\common\Memoizer.h" />
     <ClInclude Include="..\..\src\common\Module.h" />
     <ClInclude Include="..\..\src\common\Module.h" />
     <ClInclude Include="..\..\src\common\Object.h" />
     <ClInclude Include="..\..\src\common\Object.h" />
     <ClInclude Include="..\..\src\common\Reference.h" />
     <ClInclude Include="..\..\src\common\Reference.h" />
@@ -219,9 +272,56 @@
     <ClInclude Include="..\..\src\common\StringMap.h" />
     <ClInclude Include="..\..\src\common\StringMap.h" />
     <ClInclude Include="..\..\src\common\types.h" />
     <ClInclude Include="..\..\src\common\types.h" />
     <ClInclude Include="..\..\src\common\utf8.h" />
     <ClInclude Include="..\..\src\common\utf8.h" />
+    <ClInclude Include="..\..\src\common\Variant.h" />
     <ClInclude Include="..\..\src\common\Vector.h" />
     <ClInclude Include="..\..\src\common\Vector.h" />
     <ClInclude Include="..\..\src\common\version.h" />
     <ClInclude Include="..\..\src\common\version.h" />
     <ClInclude Include="..\..\src\common\wrap_Data.h" />
     <ClInclude Include="..\..\src\common\wrap_Data.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Box2D.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Collision\b2BroadPhase.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Collision\b2Collision.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Collision\b2Distance.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Collision\b2DynamicTree.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Collision\b2TimeOfImpact.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Collision\Shapes\b2ChainShape.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Collision\Shapes\b2CircleShape.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Collision\Shapes\b2EdgeShape.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Collision\Shapes\b2PolygonShape.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Collision\Shapes\b2Shape.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Common\b2BlockAllocator.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Common\b2Draw.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Common\b2GrowableStack.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Common\b2Math.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Common\b2Settings.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Common\b2StackAllocator.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Common\b2Timer.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Dynamics\b2Body.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Dynamics\b2ContactManager.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Dynamics\b2Fixture.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Dynamics\b2Island.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Dynamics\b2TimeStep.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Dynamics\b2World.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Dynamics\b2WorldCallbacks.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Dynamics\Contacts\b2ChainAndCircleContact.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Dynamics\Contacts\b2ChainAndPolygonContact.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Dynamics\Contacts\b2CircleContact.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Dynamics\Contacts\b2Contact.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Dynamics\Contacts\b2ContactSolver.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Dynamics\Contacts\b2EdgeAndCircleContact.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Dynamics\Contacts\b2EdgeAndPolygonContact.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Dynamics\Contacts\b2PolygonAndCircleContact.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Dynamics\Contacts\b2PolygonContact.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Dynamics\Joints\b2DistanceJoint.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Dynamics\Joints\b2FrictionJoint.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Dynamics\Joints\b2GearJoint.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Dynamics\Joints\b2Joint.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Dynamics\Joints\b2MouseJoint.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Dynamics\Joints\b2PrismaticJoint.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Dynamics\Joints\b2PulleyJoint.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Dynamics\Joints\b2RevoluteJoint.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Dynamics\Joints\b2RopeJoint.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Dynamics\Joints\b2WeldJoint.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Dynamics\Joints\b2WheelJoint.h" />
+    <ClInclude Include="..\..\src\libraries\Box2D\Rope\b2Rope.h" />
     <ClInclude Include="..\..\src\libraries\luasocket\luasocket.h" />
     <ClInclude Include="..\..\src\libraries\luasocket\luasocket.h" />
     <ClInclude Include="..\..\src\libraries\utf8\utf8.h" />
     <ClInclude Include="..\..\src\libraries\utf8\utf8.h" />
     <ClInclude Include="..\..\src\libraries\utf8\utf8\checked.h" />
     <ClInclude Include="..\..\src\libraries\utf8\utf8\checked.h" />
@@ -256,23 +356,29 @@
     <ClInclude Include="..\..\src\modules\font\wrap_GlyphData.h" />
     <ClInclude Include="..\..\src\modules\font\wrap_GlyphData.h" />
     <ClInclude Include="..\..\src\modules\font\wrap_Rasterizer.h" />
     <ClInclude Include="..\..\src\modules\font\wrap_Rasterizer.h" />
     <ClInclude Include="..\..\src\modules\graphics\Drawable.h" />
     <ClInclude Include="..\..\src\modules\graphics\Drawable.h" />
+    <ClInclude Include="..\..\src\modules\graphics\DrawQable.h" />
     <ClInclude Include="..\..\src\modules\graphics\Graphics.h" />
     <ClInclude Include="..\..\src\modules\graphics\Graphics.h" />
     <ClInclude Include="..\..\src\modules\graphics\Image.h" />
     <ClInclude Include="..\..\src\modules\graphics\Image.h" />
+    <ClInclude Include="..\..\src\modules\graphics\opengl\Canvas.h" />
     <ClInclude Include="..\..\src\modules\graphics\opengl\Font.h" />
     <ClInclude Include="..\..\src\modules\graphics\opengl\Font.h" />
-    <ClInclude Include="..\..\src\modules\graphics\opengl\Framebuffer.h" />
     <ClInclude Include="..\..\src\modules\graphics\opengl\GLee.h" />
     <ClInclude Include="..\..\src\modules\graphics\opengl\GLee.h" />
     <ClInclude Include="..\..\src\modules\graphics\opengl\Graphics.h" />
     <ClInclude Include="..\..\src\modules\graphics\opengl\Graphics.h" />
     <ClInclude Include="..\..\src\modules\graphics\opengl\Image.h" />
     <ClInclude Include="..\..\src\modules\graphics\opengl\Image.h" />
+    <ClInclude Include="..\..\src\modules\graphics\opengl\OpenGL.h" />
     <ClInclude Include="..\..\src\modules\graphics\opengl\ParticleSystem.h" />
     <ClInclude Include="..\..\src\modules\graphics\opengl\ParticleSystem.h" />
+    <ClInclude Include="..\..\src\modules\graphics\opengl\PixelEffect.h" />
     <ClInclude Include="..\..\src\modules\graphics\opengl\Quad.h" />
     <ClInclude Include="..\..\src\modules\graphics\opengl\Quad.h" />
     <ClInclude Include="..\..\src\modules\graphics\opengl\SpriteBatch.h" />
     <ClInclude Include="..\..\src\modules\graphics\opengl\SpriteBatch.h" />
+    <ClInclude Include="..\..\src\modules\graphics\opengl\VertexBuffer.h" />
+    <ClInclude Include="..\..\src\modules\graphics\opengl\wrap_Canvas.h" />
     <ClInclude Include="..\..\src\modules\graphics\opengl\wrap_Font.h" />
     <ClInclude Include="..\..\src\modules\graphics\opengl\wrap_Font.h" />
-    <ClInclude Include="..\..\src\modules\graphics\opengl\wrap_Framebuffer.h" />
     <ClInclude Include="..\..\src\modules\graphics\opengl\wrap_Graphics.h" />
     <ClInclude Include="..\..\src\modules\graphics\opengl\wrap_Graphics.h" />
     <ClInclude Include="..\..\src\modules\graphics\opengl\wrap_Image.h" />
     <ClInclude Include="..\..\src\modules\graphics\opengl\wrap_Image.h" />
     <ClInclude Include="..\..\src\modules\graphics\opengl\wrap_ParticleSystem.h" />
     <ClInclude Include="..\..\src\modules\graphics\opengl\wrap_ParticleSystem.h" />
+    <ClInclude Include="..\..\src\modules\graphics\opengl\wrap_PixelEffect.h" />
     <ClInclude Include="..\..\src\modules\graphics\opengl\wrap_Quad.h" />
     <ClInclude Include="..\..\src\modules\graphics\opengl\wrap_Quad.h" />
     <ClInclude Include="..\..\src\modules\graphics\opengl\wrap_SpriteBatch.h" />
     <ClInclude Include="..\..\src\modules\graphics\opengl\wrap_SpriteBatch.h" />
+    <ClInclude Include="..\..\src\modules\graphics\Quad.h" />
     <ClInclude Include="..\..\src\modules\graphics\Volatile.h" />
     <ClInclude Include="..\..\src\modules\graphics\Volatile.h" />
     <ClInclude Include="..\..\src\modules\image\devil\Image.h" />
     <ClInclude Include="..\..\src\modules\image\devil\Image.h" />
     <ClInclude Include="..\..\src\modules\image\devil\ImageData.h" />
     <ClInclude Include="..\..\src\modules\image\devil\ImageData.h" />
@@ -285,14 +391,19 @@
     <ClInclude Include="..\..\src\modules\joystick\sdl\wrap_Joystick.h" />
     <ClInclude Include="..\..\src\modules\joystick\sdl\wrap_Joystick.h" />
     <ClInclude Include="..\..\src\modules\keyboard\Keyboard.h" />
     <ClInclude Include="..\..\src\modules\keyboard\Keyboard.h" />
     <ClInclude Include="..\..\src\modules\keyboard\sdl\Keyboard.h" />
     <ClInclude Include="..\..\src\modules\keyboard\sdl\Keyboard.h" />
-    <ClInclude Include="..\..\src\modules\keyboard\sdl\wrap_Keyboard.h" />
+    <ClInclude Include="..\..\src\modules\keyboard\wrap_Keyboard.h" />
     <ClInclude Include="..\..\src\modules\mouse\Mouse.h" />
     <ClInclude Include="..\..\src\modules\mouse\Mouse.h" />
     <ClInclude Include="..\..\src\modules\mouse\sdl\Mouse.h" />
     <ClInclude Include="..\..\src\modules\mouse\sdl\Mouse.h" />
-    <ClInclude Include="..\..\src\modules\mouse\sdl\wrap_Mouse.h" />
+    <ClInclude Include="..\..\src\modules\mouse\wrap_Mouse.h" />
+    <ClInclude Include="..\..\src\modules\physics\Body.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\Body.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\Body.h" />
+    <ClInclude Include="..\..\src\modules\physics\box2d\ChainShape.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\CircleShape.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\CircleShape.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\Contact.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\Contact.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\DistanceJoint.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\DistanceJoint.h" />
+    <ClInclude Include="..\..\src\modules\physics\box2d\EdgeShape.h" />
+    <ClInclude Include="..\..\src\modules\physics\box2d\Fixture.h" />
+    <ClInclude Include="..\..\src\modules\physics\box2d\FrictionJoint.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\GearJoint.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\GearJoint.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\Joint.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\Joint.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\MouseJoint.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\MouseJoint.h" />
@@ -301,12 +412,19 @@
     <ClInclude Include="..\..\src\modules\physics\box2d\PrismaticJoint.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\PrismaticJoint.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\PulleyJoint.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\PulleyJoint.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\RevoluteJoint.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\RevoluteJoint.h" />
+    <ClInclude Include="..\..\src\modules\physics\box2d\RopeJoint.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\Shape.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\Shape.h" />
+    <ClInclude Include="..\..\src\modules\physics\box2d\WeldJoint.h" />
+    <ClInclude Include="..\..\src\modules\physics\box2d\WheelJoint.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\World.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\World.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\wrap_Body.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\wrap_Body.h" />
+    <ClInclude Include="..\..\src\modules\physics\box2d\wrap_ChainShape.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\wrap_CircleShape.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\wrap_CircleShape.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\wrap_Contact.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\wrap_Contact.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\wrap_DistanceJoint.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\wrap_DistanceJoint.h" />
+    <ClInclude Include="..\..\src\modules\physics\box2d\wrap_EdgeShape.h" />
+    <ClInclude Include="..\..\src\modules\physics\box2d\wrap_Fixture.h" />
+    <ClInclude Include="..\..\src\modules\physics\box2d\wrap_FrictionJoint.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\wrap_GearJoint.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\wrap_GearJoint.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\wrap_Joint.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\wrap_Joint.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\wrap_MouseJoint.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\wrap_MouseJoint.h" />
@@ -315,15 +433,33 @@
     <ClInclude Include="..\..\src\modules\physics\box2d\wrap_PrismaticJoint.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\wrap_PrismaticJoint.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\wrap_PulleyJoint.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\wrap_PulleyJoint.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\wrap_RevoluteJoint.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\wrap_RevoluteJoint.h" />
+    <ClInclude Include="..\..\src\modules\physics\box2d\wrap_RopeJoint.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\wrap_Shape.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\wrap_Shape.h" />
+    <ClInclude Include="..\..\src\modules\physics\box2d\wrap_WeldJoint.h" />
+    <ClInclude Include="..\..\src\modules\physics\box2d\wrap_WheelJoint.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\wrap_World.h" />
     <ClInclude Include="..\..\src\modules\physics\box2d\wrap_World.h" />
     <ClInclude Include="..\..\src\modules\physics\Joint.h" />
     <ClInclude Include="..\..\src\modules\physics\Joint.h" />
     <ClInclude Include="..\..\src\modules\physics\Shape.h" />
     <ClInclude Include="..\..\src\modules\physics\Shape.h" />
-    <ClInclude Include="..\..\src\modules\thread\sdl\Thread.h" />
-    <ClInclude Include="..\..\src\modules\thread\sdl\wrap_Thread.h" />
-    <ClInclude Include="..\..\src\modules\thread\ThreadModule.h" />
+    <ClInclude Include="..\..\src\modules\thread\posix\threads.h">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+    </ClInclude>
+    <ClInclude Include="..\..\src\modules\thread\sdl\threads.h">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+    </ClInclude>
+    <ClInclude Include="..\..\src\modules\thread\Thread.h" />
+    <ClInclude Include="..\..\src\modules\thread\threads.h" />
+    <ClInclude Include="..\..\src\modules\thread\win32\threads.h">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+    </ClInclude>
+    <ClInclude Include="..\..\src\modules\thread\wrap_Thread.h" />
     <ClInclude Include="..\..\src\modules\timer\sdl\Timer.h" />
     <ClInclude Include="..\..\src\modules\timer\sdl\Timer.h" />
-    <ClInclude Include="..\..\src\modules\timer\sdl\wrap_Timer.h" />
+    <ClInclude Include="..\..\src\modules\timer\Timer.h" />
+    <ClInclude Include="..\..\src\modules\timer\wrap_Timer.h" />
+    <ClInclude Include="..\..\src\modules\window\sdl\Window.h" />
+    <ClInclude Include="..\..\src\modules\window\Window.h" />
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="app.rc" />
     <ResourceCompile Include="app.rc" />
@@ -362,19 +498,19 @@
     <ClCompile>
     <ClCompile>
       <WarningLevel>Level3</WarningLevel>
       <WarningLevel>Level3</WarningLevel>
       <Optimization>Disabled</Optimization>
       <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>include;include\SDL;include\AL;..\..\src;..\..\src\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>include;include\SDL;include\AL;..\..\src;..\..\src\libraries;..\..\src\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <ObjectFileName>%(Identity)_d.obj</ObjectFileName>
       <ObjectFileName>%(Identity)_d.obj</ObjectFileName>
       <MultiProcessorCompilation>true</MultiProcessorCompilation>
       <MultiProcessorCompilation>true</MultiProcessorCompilation>
       <PrecompiledHeader>NotUsing</PrecompiledHeader>
       <PrecompiledHeader>NotUsing</PrecompiledHeader>
       <PrecompiledHeaderFile>
       <PrecompiledHeaderFile>
       </PrecompiledHeaderFile>
       </PrecompiledHeaderFile>
-      <PreprocessorDefinitions>VC_EXTRALEAN;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;VC_EXTRALEAN;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ClCompile>
     </ClCompile>
     <Link>
     <Link>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <AdditionalLibraryDirectories>lib</AdditionalLibraryDirectories>
       <AdditionalLibraryDirectories>lib</AdditionalLibraryDirectories>
-      <AdditionalDependencies>opengl32.lib;glu32.lib;DevIL.lib;freetype242MT.lib;libmpg123.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;lua.lib;modplug_d.lib;OpenAL32.lib;physfs.lib;SDL.lib;SDLmain.lib;libFLAC_static_D.lib;libFLAC++_static_D.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>opengl32.lib;glu32.lib;DevIL.lib;freetype244MT.lib;libmpg123.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;lua.lib;modplug_d.lib;OpenAL32.lib;physfs.lib;SDL.lib;SDLmain.lib;libFLAC_static_D.lib;libFLAC++_static_D.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <SubSystem>Console</SubSystem>
       <SubSystem>Console</SubSystem>
       <AdditionalOptions>/FORCE:MULTIPLE %(AdditionalOptions)</AdditionalOptions>
       <AdditionalOptions>/FORCE:MULTIPLE %(AdditionalOptions)</AdditionalOptions>
     </Link>
     </Link>
@@ -385,11 +521,11 @@
       <Optimization>MaxSpeed</Optimization>
       <Optimization>MaxSpeed</Optimization>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <IntrinsicFunctions>true</IntrinsicFunctions>
-      <AdditionalIncludeDirectories>include;include\SDL;include\AL;..\..\src;..\..\src\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>include;include\SDL;include\AL;..\..\src;..\..\src\libraries;..\..\src\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
+      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
       <ObjectFileName>%(Identity).obj</ObjectFileName>
       <ObjectFileName>%(Identity).obj</ObjectFileName>
-      <PreprocessorDefinitions>VC_EXTRALEAN;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;VC_EXTRALEAN;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <StringPooling>
       <StringPooling>
       </StringPooling>
       </StringPooling>
       <MinimalRebuild>
       <MinimalRebuild>
@@ -400,9 +536,10 @@
       <GenerateDebugInformation>false</GenerateDebugInformation>
       <GenerateDebugInformation>false</GenerateDebugInformation>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
       <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>opengl32.lib;glu32.lib;DevIL.lib;freetype242MT.lib;libmpg123.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;lua.lib;modplug.lib;OpenAL32.lib;physfs.lib;SDL.lib;SDLmain.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>opengl32.lib;glu32.lib;DevIL.lib;freetype244MT.lib;libmpg123.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;lua.lib;modplug.lib;OpenAL32.lib;physfs.lib;SDL.lib;SDLmain.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>lib</AdditionalLibraryDirectories>
       <AdditionalLibraryDirectories>lib</AdditionalLibraryDirectories>
       <SubSystem>Windows</SubSystem>
       <SubSystem>Windows</SubSystem>
+      <AdditionalOptions>/FORCE:MULTIPLE %(AdditionalOptions)</AdditionalOptions>
     </Link>
     </Link>
   </ItemDefinitionGroup>
   </ItemDefinitionGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

File diff suppressed because it is too large
+ 641 - 236
platform/msvc2010/love.vcxproj.filters


+ 22 - 7
platform/unix/automagic

@@ -1,10 +1,25 @@
 #!/bin/bash
 #!/bin/bash
-if ! sh platform/unix/gen-makefile; then
-	echo "You should be doing this from the root directory of the project."
+
+automagic() {
+	if ! sh platform/unix/gen-makefile; then
+		echo "You should be doing this from the root directory of the project."
+		exit 1
+	fi
+	autoheader 2>&1 || return 1 # Gimmie config.h.in
+	libtoolize --force 2>&1 || return 1
+	aclocal 2>&1 || return 1
+	autoconf 2>&1 || return 1
+	automake -a 2>&1 || return 1
+}
+
+if [[ $1 == "-d" ]]; then
+	automagic
+else
+	automagic > /dev/null
+fi
+if [ $? -eq 1 ]; then
+	echo "Failed, please contact the developers."
 	exit 1
 	exit 1
+else
+	echo "Success, carry on configuring."
 fi
 fi
-autoheader # Gimmie config.h.in
-libtoolize --force
-aclocal
-autoconf
-automake -a

+ 3 - 0
platform/unix/exclude

@@ -21,3 +21,6 @@
 ./modules/native/tcc/libtcc/stab.h
 ./modules/native/tcc/libtcc/stab.h
 ./libraries/luasocket/libluasocket/wsocket.*
 ./libraries/luasocket/libluasocket/wsocket.*
 ./modules/sound/lullaby/FLACDecoder.*
 ./modules/sound/lullaby/FLACDecoder.*
+./modules/thread/sdl/*
+./modules/thread/win32/*
+./modules/thread/posix/*

+ 2 - 1
platform/unix/gen-makefile

@@ -3,7 +3,8 @@ echo Generating src/Makefile.am ...
 cd src
 cd src
 inc_current=.
 inc_current=.
 inc_modules="$inc_current/modules"
 inc_modules="$inc_current/modules"
-echo "AM_CPPFLAGS = -I$inc_current -I$inc_modules -I/usr/include/AL -I/usr/include/freetype2  \$(INCLUDE_LUA) -I/usr/include/SDL \$(FILE_OFFSET)
+inc_libraries="$inc_current/libraries"
+echo "AM_CPPFLAGS = -I$inc_current -I$inc_modules -I$inc_libraries -I/usr/include/AL -I/usr/include/freetype2  \$(INCLUDE_LUA) -I/usr/include/SDL \$(FILE_OFFSET)
 AUTOMAKE_OPTIONS = subdir-objects
 AUTOMAKE_OPTIONS = subdir-objects
 DEFAULT_INCLUDES =
 DEFAULT_INCLUDES =
 SUBDIRS =
 SUBDIRS =

+ 67 - 0
readme.md

@@ -0,0 +1,67 @@
+LÖVE is an *awesome* framework you can use to make 2D games in Lua. It's free, open-source, and works on Windows, Mac OS X and Linux.
+
+Documentation
+-------------
+
+We use our [wiki][wiki] for documentation.
+If you need further help, feel free to ask on our [forums][forums], and last but not least there's the irc channel [#love on Freenode][irc].
+
+Compilation
+-----------
+
+###Windows
+Use the project files for Visual C++ 2008 or 2010 (2010 preferred) located in the platform dir.
+
+###*nix
+Run platform/unix/automagic, then run ./configure and make.
+
+###OSX
+Use the XCode project in platform/macosx.
+
+For both Windows and OSX there are dependencies available [here][dependencies].
+
+Repository information
+----------------------
+
+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
+not our development target (which would be the next revision). (Version numbers formatted major.minor.revision.)
+
+We tag all our releases (since we started using mercurial), and have binary downloads available for them.
+
+Builds
+------
+
+Releases are found in the 'downloads' section on bitbucket, are linked on [the site][site],
+and there's a ppa for ubuntu, [ppa:bartbes/love-stable][stableppa].
+
+There are also unstable/nightly builds:
+
+- For windows they are located [here][winbuilds].
+- For ubuntu linux they are in [ppa:bartbes/love-unstable][unstableppa]
+- For arch linux there's [love-hg][aur] in the AUR.
+- For other linuxes and OSX there are currently no official builds.
+
+Dependencies
+------------
+
+- SDL
+- OpenGL
+- OpenAL
+- Lua / LuaJIT / LLVM-lua
+- DevIL with MNG and TIFF
+- FreeType
+- PhysicsFS
+- ModPlug
+- mpg123
+- Vorbisfile
+
+[site]: http://love2d.org
+[wiki]: http://love2d.org/wiki
+[forums]: http://love2d.org/forums
+[irc]: irc://irc.freenode.net/love
+[dependencies]: http://love2d.org/sdk
+[winbuilds]: http://love2d.org/builds
+[stableppa]: https://launchpad.net/~bartbes/+archive/love-stable
+[unstableppa]: https://launchpad.net/~bartbes/+archive/love-unstable
+[aur]: http://aur.archlinux.org/packages.php?ID=35279

+ 0 - 25
readme.txt

@@ -1,25 +0,0 @@
-
-! WARNING ! 
------------
-
-This software is not complete. This is just a preview. Don't expect to find any 
-interface consistencies between releases at all. With each release, everything 
-you once knew and loved may be brutally murdered. By which I mean removed and/or 
-changed.
-
-
-RUNNING GAMES
--------------
-
-In Windows or other graphical enviroments, just open the .love file you want to 
-run with the love binary, such as love.exe. (~^-^)~
-
-In a console, type "love" followed by the relative or absolute path to a directory 
-(or archive).
-
-Examples: 
-
-* love mygame.love
-* love /home/hax/ultragame
-
-Remember that what you are trying to run at least should contain the file "main.lua".

+ 56 - 56
src/common/Data.h

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

+ 11 - 11
src/common/EnumMap.h

@@ -1,14 +1,14 @@
 /**
 /**
-* Copyright (c) 2006-2011 LOVE Development Team
-* 
+* Copyright (c) 2006-2012 LOVE Development Team
+*
 * This software is provided 'as-is', without any express or implied
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * warranty.  In no event will the authors be held liable for any damages
 * arising from the use of this software.
 * arising from the use of this software.
-* 
+*
 * Permission is granted to anyone to use this software for any purpose,
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 * freely, subject to the following restrictions:
-* 
+*
 * 1. The origin of this software must not be misrepresented; you must not
 * 1. The origin of this software must not be misrepresented; you must not
 *    claim that you wrote the original software. If you use this software
 *    claim that you wrote the original software. If you use this software
 *    in a product, an acknowledgment in the product documentation would be
 *    in a product, an acknowledgment in the product documentation would be
@@ -41,7 +41,7 @@ namespace love
 		Value values_u[PEAK];
 		Value values_u[PEAK];
 
 
 	public:
 	public:
-		
+
 		struct Entry
 		struct Entry
 		{
 		{
 			T t;
 			T t;
@@ -52,27 +52,27 @@ namespace love
 		{
 		{
 			unsigned n = size/sizeof(Entry);
 			unsigned n = size/sizeof(Entry);
 
 
-			for(unsigned i = 0; i<n; ++i)
+			for (unsigned i = 0; i<n; ++i)
 			{
 			{
 				unsigned e_t = (unsigned)entries[i].t;
 				unsigned e_t = (unsigned)entries[i].t;
 				unsigned e_u = (unsigned)entries[i].u;
 				unsigned e_u = (unsigned)entries[i].u;
 
 
-				if(e_t < PEAK)
+				if (e_t < PEAK)
 				{
 				{
 					values_u[e_t].v = e_u;
 					values_u[e_t].v = e_u;
 					values_u[e_t].set = true;
 					values_u[e_t].set = true;
 				}
 				}
-				if(e_u < PEAK)
+				if (e_u < PEAK)
 				{
 				{
 					values_t[e_u].v = e_t;
 					values_t[e_u].v = e_t;
 					values_t[e_u].set = true;
 					values_t[e_u].set = true;
 				}
 				}
 			}
 			}
 		}
 		}
-			
+
 		bool find(T t, U & u)
 		bool find(T t, U & u)
 		{
 		{
-			if((unsigned)t < PEAK && values_u[(unsigned)t].set)
+			if ((unsigned)t < PEAK && values_u[(unsigned)t].set)
 			{
 			{
 				u = (U)values_u[(unsigned)t].v;
 				u = (U)values_u[(unsigned)t].v;
 				return true;
 				return true;
@@ -83,7 +83,7 @@ namespace love
 
 
 		bool find(U u, T & t)
 		bool find(U u, T & t)
 		{
 		{
-			if((unsigned)u < PEAK && values_t[(unsigned)u].set)
+			if ((unsigned)u < PEAK && values_t[(unsigned)u].set)
 			{
 			{
 				t = (T)values_t[(unsigned)u].v;
 				t = (T)values_t[(unsigned)u].v;
 				return true;
 				return true;

+ 62 - 38
src/common/Exception.cpp

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

+ 64 - 68
src/common/Exception.h

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

+ 196 - 182
src/common/Matrix.cpp

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

+ 166 - 150
src/common/Matrix.h

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

+ 44 - 0
src/common/Memoizer.cpp

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

+ 18 - 13
src/modules/thread/ThreadModule.h → src/common/Memoizer.h

@@ -1,5 +1,5 @@
 /**
 /**
-* Copyright (c) 2006-2011 LOVE Development Team
+* Copyright (c) 2006-2012 LOVE Development Team
 *
 *
 * This software is provided 'as-is', without any express or implied
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * warranty.  In no event will the authors be held liable for any damages
@@ -18,24 +18,29 @@
 * 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.
 **/
 **/
 
 
-#ifndef LOVE_THREAD_THREAD_H
-#define LOVE_THREAD_THREAD_H
+#ifndef LOVE_MEMOIZER_H
+#define LOVE_MEMOIZER_H
 
 
-#include <common/Module.h>
-#include <string>
+#include <map>
 
 
 namespace love
 namespace love
 {
 {
-namespace thread
-{
-	class ThreadModule : public Module
+	class Memoizer
 	{
 	{
+	private:
+
+		static std::map<void *, void *> objectMap;
+
 	public:
 	public:
-		virtual ~ThreadModule(){};
-		virtual void unregister(const std::string & name) = 0;
-	}; // ThreadModule
 
 
-} // thread
+		static void add(void * key, void * val);
+
+		static void remove(void * key);
+
+		static void * find(void * key);
+
+	}; // Memoizer
+
 } // love
 } // love
 
 
-#endif // LOVE_THREAD_THREAD_H
+#endif // LOVE_MEMOIZER_H

+ 7 - 7
src/common/Module.h

@@ -1,14 +1,14 @@
 /**
 /**
-* Copyright (c) 2006-2011 LOVE Development Team
-* 
+* Copyright (c) 2006-2012 LOVE Development Team
+*
 * This software is provided 'as-is', without any express or implied
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * warranty.  In no event will the authors be held liable for any damages
 * arising from the use of this software.
 * arising from the use of this software.
-* 
+*
 * Permission is granted to anyone to use this software for any purpose,
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 * freely, subject to the following restrictions:
-* 
+*
 * 1. The origin of this software must not be misrepresented; you must not
 * 1. The origin of this software must not be misrepresented; you must not
 *    claim that you wrote the original software. If you use this software
 *    claim that you wrote the original software. If you use this software
 *    in a product, an acknowledgment in the product documentation would be
 *    in a product, an acknowledgment in the product documentation would be
@@ -29,7 +29,7 @@
 namespace love
 namespace love
 {
 {
 	/**
 	/**
-	* Abstract superclass for all modules. 
+	* Abstract superclass for all modules.
 	**/
 	**/
 	class Module : public Object
 	class Module : public Object
 	{
 	{
@@ -43,8 +43,8 @@ namespace love
 		/**
 		/**
 		* Gets the name of the module. This is used in case of errors
 		* Gets the name of the module. This is used in case of errors
 		* and other messages.
 		* and other messages.
-		* 
-		* @return The full name of the module, eg. love.graphics.opengl. 
+		*
+		* @return The full name of the module, eg. love.graphics.opengl.
 		**/
 		**/
 		virtual const char * getName() const = 0;
 		virtual const char * getName() const = 0;
 
 

+ 2 - 2
src/common/Object.cpp

@@ -1,5 +1,5 @@
 /**
 /**
-* Copyright (c) 2006-2011 LOVE Development Team
+* Copyright (c) 2006-2012 LOVE Development Team
 *
 *
 * This software is provided 'as-is', without any express or implied
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * warranty.  In no event will the authors be held liable for any damages
@@ -45,7 +45,7 @@ namespace love
 
 
 	void Object::release()
 	void Object::release()
 	{
 	{
-		if(--count <= 0)
+		if (--count <= 0)
 			delete this;
 			delete this;
 	}
 	}
 
 

+ 1 - 1
src/common/Object.h

@@ -1,5 +1,5 @@
 /**
 /**
-* Copyright (c) 2006-2011 LOVE Development Team
+* Copyright (c) 2006-2012 LOVE Development Team
 *
 *
 * This software is provided 'as-is', without any express or implied
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * warranty.  In no event will the authors be held liable for any damages

+ 81 - 70
src/common/Reference.cpp

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

+ 7 - 7
src/common/Reference.h

@@ -1,14 +1,14 @@
 /**
 /**
-* Copyright (c) 2006-2011 LOVE Development Team
-* 
+* Copyright (c) 2006-2012 LOVE Development Team
+*
 * This software is provided 'as-is', without any express or implied
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * warranty.  In no event will the authors be held liable for any damages
 * arising from the use of this software.
 * arising from the use of this software.
-* 
+*
 * Permission is granted to anyone to use this software for any purpose,
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 * freely, subject to the following restrictions:
-* 
+*
 * 1. The origin of this software must not be misrepresented; you must not
 * 1. The origin of this software must not be misrepresented; you must not
 *    claim that you wrote the original software. If you use this software
 *    claim that you wrote the original software. If you use this software
 *    in a product, an acknowledgment in the product documentation would be
 *    in a product, an acknowledgment in the product documentation would be
@@ -49,7 +49,7 @@ namespace love
 		Reference();
 		Reference();
 
 
 		/**
 		/**
-		* Creates the object and a reference to the value 
+		* Creates the object and a reference to the value
 		* on the top of the stack.
 		* on the top of the stack.
 		**/
 		**/
 		Reference(lua_State * L);
 		Reference(lua_State * L);
@@ -58,11 +58,11 @@ namespace love
 		* Deletes the reference, if any.
 		* Deletes the reference, if any.
 		**/
 		**/
 		virtual ~Reference();
 		virtual ~Reference();
-		
+
 		/**
 		/**
 		* Creates a reference to the value on the
 		* Creates a reference to the value on the
 		* top of the stack.
 		* top of the stack.
-		**/ 
+		**/
 		void ref(lua_State * L);
 		void ref(lua_State * L);
 
 
 		/**
 		/**

+ 23 - 20
src/common/StringMap.h

@@ -1,14 +1,14 @@
 /**
 /**
-* Copyright (c) 2006-2011 LOVE Development Team
-* 
+* Copyright (c) 2006-2012 LOVE Development Team
+*
 * This software is provided 'as-is', without any express or implied
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * warranty.  In no event will the authors be held liable for any damages
 * arising from the use of this software.
 * arising from the use of this software.
-* 
+*
 * Permission is granted to anyone to use this software for any purpose,
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 * freely, subject to the following restrictions:
-* 
+*
 * 1. The origin of this software must not be misrepresented; you must not
 * 1. The origin of this software must not be misrepresented; you must not
 *    claim that you wrote the original software. If you use this software
 *    claim that you wrote the original software. If you use this software
 *    in a product, an acknowledgment in the product documentation would be
 *    in a product, an acknowledgment in the product documentation would be
@@ -54,12 +54,12 @@ namespace love
 		StringMap(Entry * entries, unsigned num)
 		StringMap(Entry * entries, unsigned num)
 		{
 		{
 
 
-			for(unsigned i = 0; i < SIZE; ++i)
+			for (unsigned i = 0; i < SIZE; ++i)
 				reverse[i] = 0;
 				reverse[i] = 0;
 
 
 			unsigned n = num/sizeof(Entry);
 			unsigned n = num/sizeof(Entry);
 
 
-			for(unsigned i = 0; i < n; ++i)
+			for (unsigned i = 0; i < n; ++i)
 			{
 			{
 				add(entries[i].key, entries[i].value);
 				add(entries[i].key, entries[i].value);
 			}
 			}
@@ -67,9 +67,9 @@ namespace love
 
 
 		bool streq(const char * a, const char * b)
 		bool streq(const char * a, const char * b)
 		{
 		{
-			while(*a != 0 && *b != 0)
+			while (*a != 0 && *b != 0)
 			{
 			{
-				if(*a != *b)
+				if (*a != *b)
 					return false;
 					return false;
 				++a;
 				++a;
 				++b;
 				++b;
@@ -80,15 +80,18 @@ namespace love
 
 
 		bool find(const char * key, T & t)
 		bool find(const char * key, T & t)
 		{
 		{
-			//unsigned str_hash = djb2(key);
+			unsigned str_hash = djb2(key);
 
 
-			for(unsigned i = 0; i < MAX; ++i)
+			for (unsigned i = 0; i < MAX; ++i)
 			{
 			{
-				//unsigned str_i = (str_hash + i) % MAX; //this isn't used, is this intentional?
+				unsigned str_i = (str_hash + i) % MAX; //this isn't used, is this intentional?
+
+				if (!records[str_i].set)
+					return false;
 
 
-				if(records[i].set && streq(records[i].key, key))
+				if (streq(records[str_i].key, key))
 				{
 				{
-					t = records[i].value;
+					t = records[str_i].value;
 					return true;
 					return true;
 				}
 				}
 			}
 			}
@@ -100,10 +103,10 @@ namespace love
 		{
 		{
 			unsigned index = (unsigned)key;
 			unsigned index = (unsigned)key;
 
 
-			if(index >= SIZE)
+			if (index >= SIZE)
 				return false;
 				return false;
-			
-			if(reverse[index] != 0)
+
+			if (reverse[index] != 0)
 			{
 			{
 				str = reverse[index];
 				str = reverse[index];
 				return true;
 				return true;
@@ -118,12 +121,12 @@ namespace love
 		{
 		{
 			unsigned str_hash = djb2(key);
 			unsigned str_hash = djb2(key);
 			bool inserted = false;
 			bool inserted = false;
-			
-			for(unsigned i = 0; i < MAX; ++i)
+
+			for (unsigned i = 0; i < MAX; ++i)
 			{
 			{
 				unsigned str_i = (str_hash + i) % MAX;
 				unsigned str_i = (str_hash + i) % MAX;
 
 
-				if(!records[str_i].set)
+				if (!records[str_i].set)
 				{
 				{
 					inserted = true;
 					inserted = true;
 					records[str_i].set = true;
 					records[str_i].set = true;
@@ -135,7 +138,7 @@ namespace love
 
 
 			unsigned index = (unsigned)value;
 			unsigned index = (unsigned)value;
 
 
-			if(index >= SIZE)
+			if (index >= SIZE)
 			{
 			{
 				printf("\nConstant %s out of bounds with %i!\n", key, index);
 				printf("\nConstant %s out of bounds with %i!\n", key, index);
 				return false;
 				return false;

+ 173 - 0
src/common/Variant.cpp

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

+ 73 - 0
src/common/Variant.h

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

+ 25 - 25
src/common/Vector.cpp

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

+ 310 - 310
src/common/Vector.h

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

+ 14 - 13
src/common/b64.cpp

@@ -1,14 +1,14 @@
 /**
 /**
-* Copyright (c) 2006-2011 LOVE Development Team
-* 
+* Copyright (c) 2006-2012 LOVE Development Team
+*
 * This software is provided 'as-is', without any express or implied
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * warranty.  In no event will the authors be held liable for any damages
 * arising from the use of this software.
 * arising from the use of this software.
-* 
+*
 * Permission is granted to anyone to use this software for any purpose,
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 * freely, subject to the following restrictions:
-* 
+*
 * 1. The origin of this software must not be misrepresented; you must not
 * 1. The origin of this software must not be misrepresented; you must not
 *    claim that you wrote the original software. If you use this software
 *    claim that you wrote the original software. If you use this software
 *    in a product, an acknowledgment in the product documentation would be
 *    in a product, an acknowledgment in the product documentation would be
@@ -25,7 +25,7 @@ namespace love
 	static const char cd64[]="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq";
 	static const char cd64[]="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq";
 
 
 	void b64_decode_block(char in[4], char out[3])
 	void b64_decode_block(char in[4], char out[3])
-	{   
+	{
 		out[0] = (char)(in[0] << 2 | in[1] >> 4);
 		out[0] = (char)(in[0] << 2 | in[1] >> 4);
 		out[1] = (char)(in[1] << 4 | in[2] >> 2);
 		out[1] = (char)(in[1] << 4 | in[2] >> 2);
 		out[2] = (char)(((in[2] << 6) & 0xc0) | in[3]);
 		out[2] = (char)(((in[2] << 6) & 0xc0) | in[3]);
@@ -41,33 +41,34 @@ namespace love
 		char in[4], out[3], v;
 		char in[4], out[3], v;
 		int i, len, pos = 0;
 		int i, len, pos = 0;
 
 
-		while(pos <= slen)
+		while (pos <= slen)
 		{
 		{
-			for(len = 0, i = 0; i < 4 && pos <= slen; i++ )
+			for (len = 0, i = 0; i < 4 && pos <= slen; i++ )
 			{
 			{
 				v = 0;
 				v = 0;
 
 
-				while(pos <= slen && v == 0 )
+				while (pos <= slen && v == 0 )
 				{
 				{
 					v = src[pos++];
 					v = src[pos++];
 					v = (char)((v < 43 || v > 122) ? 0 : cd64[v - 43]);
 					v = (char)((v < 43 || v > 122) ? 0 : cd64[v - 43]);
-					if(v)
+					if (v)
 						v = (char)((v == '$') ? 0 : v - 61);
 						v = (char)((v == '$') ? 0 : v - 61);
 				}
 				}
 
 
-				if(pos <= slen)
+				if (pos <= slen)
 				{
 				{
 					len++;
 					len++;
-					if(v)
+					if (v)
 						in[i] = (char)(v - 1);
 						in[i] = (char)(v - 1);
 				}
 				}
 				else
 				else
 					in[i] = 0;
 					in[i] = 0;
 			}
 			}
 
 
-			if(len) {
+			if (len)
+			{
 				b64_decode_block(in, out);
 				b64_decode_block(in, out);
-				for(i = 0; i < len - 1; i++)
+				for (i = 0; i < len - 1; i++)
 					*(d++) = out[i];
 					*(d++) = out[i];
 			}
 			}
 		}
 		}

+ 4 - 4
src/common/b64.h

@@ -1,14 +1,14 @@
 /**
 /**
-* Copyright (c) 2006-2011 LOVE Development Team
-* 
+* Copyright (c) 2006-2012 LOVE Development Team
+*
 * This software is provided 'as-is', without any express or implied
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * warranty.  In no event will the authors be held liable for any damages
 * arising from the use of this software.
 * arising from the use of this software.
-* 
+*
 * Permission is granted to anyone to use this software for any purpose,
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 * freely, subject to the following restrictions:
-* 
+*
 * 1. The origin of this software must not be misrepresented; you must not
 * 1. The origin of this software must not be misrepresented; you must not
 *    claim that you wrote the original software. If you use this software
 *    claim that you wrote the original software. If you use this software
 *    in a product, an acknowledgment in the product documentation would be
 *    in a product, an acknowledgment in the product documentation would be

+ 14 - 4
src/common/config.h

@@ -1,14 +1,14 @@
 /**
 /**
-* Copyright (c) 2006-2011 LOVE Development Team
-* 
+* Copyright (c) 2006-2012 LOVE Development Team
+*
 * This software is provided 'as-is', without any express or implied
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * warranty.  In no event will the authors be held liable for any damages
 * arising from the use of this software.
 * arising from the use of this software.
-* 
+*
 * Permission is granted to anyone to use this software for any purpose,
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 * freely, subject to the following restrictions:
-* 
+*
 * 1. The origin of this software must not be misrepresented; you must not
 * 1. The origin of this software must not be misrepresented; you must not
 *    claim that you wrote the original software. If you use this software
 *    claim that you wrote the original software. If you use this software
 *    in a product, an acknowledgment in the product documentation would be
 *    in a product, an acknowledgment in the product documentation would be
@@ -48,6 +48,10 @@
 #	define _CRT_SECURE_NO_WARNINGS
 #	define _CRT_SECURE_NO_WARNINGS
 #endif
 #endif
 
 
+#ifndef LOVE_UNUSED
+#	define LOVE_UNUSED(x) (void)sizeof(x)
+#endif
+
 #ifndef LOVE_BUILD
 #ifndef LOVE_BUILD
 #	define LOVE_BUILD
 #	define LOVE_BUILD
 #	define LOVE_BUILD_STANDALONE
 #	define LOVE_BUILD_STANDALONE
@@ -68,4 +72,10 @@
 #	define NOMINMAX
 #	define NOMINMAX
 #endif
 #endif
 
 
+// Autotools config.h
+#ifdef HAVE_CONFIG_H
+#	include <../config.h>
+#	undef VERSION
+#endif
+
 #endif // LOVE_CONFIG_H
 #endif // LOVE_CONFIG_H

+ 41 - 0
src/common/delay.cpp

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

+ 33 - 0
src/common/delay.h

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

+ 64 - 0
src/common/int.h

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

+ 98 - 84
src/common/math.h

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

+ 480 - 432
src/common/runtime.cpp

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

+ 58 - 9
src/common/runtime.h

@@ -1,5 +1,5 @@
 /**
 /**
-* Copyright (c) 2006-2011 LOVE Development Team
+* Copyright (c) 2006-2012 LOVE Development Team
 *
 *
 * This software is provided 'as-is', without any express or implied
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * warranty.  In no event will the authors be held liable for any damages
@@ -109,7 +109,7 @@ namespace love
 	* Converts the value at idx to a bool. It follow the same rules
 	* Converts the value at idx to a bool. It follow the same rules
 	* as lua_toboolean, but returns a bool instead of an int.
 	* as lua_toboolean, but returns a bool instead of an int.
 	* @param L The Lua state.
 	* @param L The Lua state.
-	* @param idx The index on the Lua state.
+	* @param idx The index on the Lua stack.
 	* @return True if the value evaluates to true, false otherwise.
 	* @return True if the value evaluates to true, false otherwise.
 	**/
 	**/
 	bool luax_toboolean(lua_State * L, int idx);
 	bool luax_toboolean(lua_State * L, int idx);
@@ -118,19 +118,36 @@ namespace love
 	* Pushes a bool onto the stack. It's the same as lua_pushboolean,
 	* Pushes a bool onto the stack. It's the same as lua_pushboolean,
 	* but with bool instead of int.
 	* but with bool instead of int.
 	* @param L The Lua state.
 	* @param L The Lua state.
-	* @paarm b The bool to push.
+	* @param b The bool to push.
 	**/
 	**/
 	void luax_pushboolean(lua_State * L, bool b);
 	void luax_pushboolean(lua_State * L, bool b);
 
 
 	/**
 	/**
 	* Converts the value at idx to a bool, or if not present, b is returned.
 	* Converts the value at idx to a bool, or if not present, b is returned.
 	* @param L The Lua state.
 	* @param L The Lua state.
-	* @param idx The index of the Lua state.
+	* @param idx The index of the Lua stack.
 	* @param b The value to return if no value exist at the specified index.
 	* @param b The value to return if no value exist at the specified index.
 	* @return True if the value evaluates to true, false otherwise.
 	* @return True if the value evaluates to true, false otherwise.
 	**/
 	**/
 	bool luax_optboolean(lua_State * L, int idx, bool b);
 	bool luax_optboolean(lua_State * L, int idx, bool b);
 
 
+	/**
+	* Converts the value at idx to a std::string. It takes care of the string
+	* size and possible embedded nulls.
+	* @param L The Lua state.
+	* @param idx The index on the Lua stack.
+	* @return Copy of the string at the specified index.
+	**/
+	std::string luax_checkstring(lua_State * L, int idx);
+
+	/**
+	* Pushes a std::string onto the stack. It uses the length of the string
+	* for lua_pushlstring's len argument.
+	* @param L The Lua state.
+	* @param str The string to push.
+	**/
+	void luax_pushstring(lua_State * L, std::string str);
+
 	/**
 	/**
 	* Require at least 'min' number of items on the stack.
 	* Require at least 'min' number of items on the stack.
 	* @param L The Lua state.
 	* @param L The Lua state.
@@ -176,13 +193,23 @@ namespace love
 	**/
 	**/
 	int luax_register_type(lua_State * L, const char * tname, const luaL_Reg * f = 0);
 	int luax_register_type(lua_State * L, const char * tname, const luaL_Reg * f = 0);
 
 
+	/**
+	 * Do a table.insert from C
+	 * @param L the state
+	 * @param tindex the stack index of the table
+	 * @param vindex the stack index of the value
+	 * @param pos the position to insert it in
+	 **/
+	int luax_table_insert(lua_State * L, int tindex, int vindex, int pos = -1);
+
 	/**
 	/**
 	* Register a new searcher function for package.loaders. This can for instance enable
 	* Register a new searcher function for package.loaders. This can for instance enable
 	* loading of files through love.filesystem using standard require.
 	* loading of files through love.filesystem using standard require.
 	* @param L The Lua state.
 	* @param L The Lua state.
 	* @param f The searcher function.
 	* @param f The searcher function.
+	* @param pos The position to insert the loader in.
 	**/
 	**/
-	int luax_register_searcher(lua_State * L, lua_CFunction f);
+	int luax_register_searcher(lua_State * L, lua_CFunction f, int pos = -1);
 
 
 	/**
 	/**
 	* Creates a new Lua-accessible object of the given type, and put it on the stack.
 	* Creates a new Lua-accessible object of the given type, and put it on the stack.
@@ -273,6 +300,28 @@ namespace love
 
 
 	Type luax_type(lua_State * L, int idx);
 	Type luax_type(lua_State * L, int idx);
 
 
+	/**
+	 * Convert the value at the specified index to an Lua number, and then
+	 * convert to a float.
+	 *
+	 * @param L The Lua state.
+	 * @param idx The index on the stack.
+	 */
+	inline float luax_tofloat(lua_State *L, int idx)
+	{
+		return static_cast<float>(lua_tonumber(L, idx));
+	}
+
+	/**
+	 * Like luax_tofloat, but checks that the value is a number.
+	 *
+	 * @see luax_tofloat
+	 */
+	inline float luax_checkfloat(lua_State *L, int idx)
+	{
+		return static_cast<float>(luaL_checknumber(L, idx));
+	}
+
 	/**
 	/**
 	* Converts the value at idx to the specified type without checking that
 	* Converts the value at idx to the specified type without checking that
 	* this conversion is valid. If the type has been previously verified with
 	* this conversion is valid. If the type has been previously verified with
@@ -299,12 +348,12 @@ namespace love
 	template <typename T>
 	template <typename T>
 	T * luax_checktype(lua_State * L, int idx, const char * name, love::bits type)
 	T * luax_checktype(lua_State * L, int idx, const char * name, love::bits type)
 	{
 	{
-		if(lua_isuserdata(L, idx) == 0)
+		if (lua_isuserdata(L, idx) == 0)
 			luaL_error(L, "Incorrect parameter type: expected userdata.");
 			luaL_error(L, "Incorrect parameter type: expected userdata.");
 
 
 		Proxy * u = (Proxy *)lua_touserdata(L, idx);
 		Proxy * u = (Proxy *)lua_touserdata(L, idx);
 
 
-		if((u->flags & type) != type)
+		if ((u->flags & type) != type)
 			luaL_error(L, "Incorrect parameter type: expected %s", name);
 			luaL_error(L, "Incorrect parameter type: expected %s", name);
 
 
 		return (T *)u->data;
 		return (T *)u->data;
@@ -316,12 +365,12 @@ namespace love
 		luax_getregistry(L, REGISTRY_MODULES);
 		luax_getregistry(L, REGISTRY_MODULES);
 		lua_getfield(L, -1, k);
 		lua_getfield(L, -1, k);
 
 
-		if(!lua_isuserdata(L, -1))
+		if (!lua_isuserdata(L, -1))
 			luaL_error(L, "Tried to get nonexisting module %s.", k);
 			luaL_error(L, "Tried to get nonexisting module %s.", k);
 
 
 		Proxy * u = (Proxy *)lua_touserdata(L, -1);
 		Proxy * u = (Proxy *)lua_touserdata(L, -1);
 
 
-		if((u->flags & type) != type)
+		if ((u->flags & type) != type)
 			luaL_error(L, "Incorrect module %s", k);
 			luaL_error(L, "Incorrect module %s", k);
 
 
 		lua_pop(L, 2);
 		lua_pop(L, 2);

+ 173 - 161
src/common/types.h

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

+ 12 - 12
src/common/utf8.cpp

@@ -1,14 +1,14 @@
 /**
 /**
-* Copyright (c) 2006-2011 LOVE Development Team
-* 
+* Copyright (c) 2006-2012 LOVE Development Team
+*
 * This software is provided 'as-is', without any express or implied
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * warranty.  In no event will the authors be held liable for any damages
 * arising from the use of this software.
 * arising from the use of this software.
-* 
+*
 * Permission is granted to anyone to use this software for any purpose,
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 * freely, subject to the following restrictions:
-* 
+*
 * 1. The origin of this software must not be misrepresented; you must not
 * 1. The origin of this software must not be misrepresented; you must not
 *    claim that you wrote the original software. If you use this software
 *    claim that you wrote the original software. If you use this software
 *    in a product, an acknowledgment in the product documentation would be
 *    in a product, an acknowledgment in the product documentation would be
@@ -36,25 +36,25 @@ namespace love
 		// Convert to UTF-8.
 		// Convert to UTF-8.
 		int ok = WideCharToMultiByte(CP_UTF8, 0, wstr, wide_len, utf8_str, utf8_size, 0, 0);
 		int ok = WideCharToMultiByte(CP_UTF8, 0, wstr, wide_len, utf8_str, utf8_size, 0, 0);
 
 
-		if(!ok)
-		{
-			delete [] utf8_str;
-		}
+		std::string ret;
+		if (ok)
+			ret = utf8_str;
 
 
-		return ok ? std::string(utf8_str) : std::string();
+		delete utf8_str;
+		return ret;
 	}
 	}
 
 
 	void replace_char(std::string & str, char find, char replace)
 	void replace_char(std::string & str, char find, char replace)
 	{
 	{
 		int length = str.length();
 		int length = str.length();
 
 
-		for(int i = 0; i<length; i++)
+		for (int i = 0; i<length; i++)
 		{
 		{
-			if(str[i] == find)
+			if (str[i] == find)
 				str[i] = replace;
 				str[i] = replace;
 		}
 		}
 	}
 	}
 
 
 } // love
 } // love
 
 
-#endif // LOVE_WINDOWS
+#endif // LOVE_WINDOWS

+ 4 - 4
src/common/utf8.h

@@ -1,14 +1,14 @@
 /**
 /**
-* Copyright (c) 2006-2011 LOVE Development Team
-* 
+* Copyright (c) 2006-2012 LOVE Development Team
+*
 * This software is provided 'as-is', without any express or implied
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * warranty.  In no event will the authors be held liable for any damages
 * arising from the use of this software.
 * arising from the use of this software.
-* 
+*
 * Permission is granted to anyone to use this software for any purpose,
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 * freely, subject to the following restrictions:
-* 
+*
 * 1. The origin of this software must not be misrepresented; you must not
 * 1. The origin of this software must not be misrepresented; you must not
 *    claim that you wrote the original software. If you use this software
 *    claim that you wrote the original software. If you use this software
 *    in a product, an acknowledgment in the product documentation would be
 *    in a product, an acknowledgment in the product documentation would be

+ 6 - 7
src/common/version.h

@@ -1,5 +1,5 @@
 /**
 /**
-* Copyright (c) 2006-2011 LOVE Development Team
+* Copyright (c) 2006-2012 LOVE Development Team
 *
 *
 * This software is provided 'as-is', without any express or implied
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * warranty.  In no event will the authors be held liable for any damages
@@ -25,12 +25,11 @@ namespace love
 {
 {
 	// Version stuff.
 	// Version stuff.
 	const int VERSION_MAJOR = 0;
 	const int VERSION_MAJOR = 0;
-	const int VERSION_MINOR = 7;
-	const int VERSION_REV = 1;
-	const int VERSION = VERSION_MAJOR*100 + VERSION_MINOR*10 + VERSION_REV;
-	const int VERSION_COMPATIBILITY[] =  { VERSION, 070, 0 };
-	const char * VERSION_STR = "0.7.1";
-	const char * VERSION_CODENAME = "Game Slave";
+	const int VERSION_MINOR = 8;
+	const int VERSION_REV = 0;
+	const char * VERSION = "0.8.0";
+	const char * VERSION_COMPATIBILITY[] =  { VERSION, 0 };
+	const char * VERSION_CODENAME = "Rubber Piggy";
 
 
 } // love
 } // love
 
 

+ 5 - 5
src/common/wrap_Data.cpp

@@ -1,14 +1,14 @@
 /**
 /**
-* Copyright (c) 2006-2011 LOVE Development Team
-* 
+* Copyright (c) 2006-2012 LOVE Development Team
+*
 * This software is provided 'as-is', without any express or implied
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * warranty.  In no event will the authors be held liable for any damages
 * arising from the use of this software.
 * arising from the use of this software.
-* 
+*
 * Permission is granted to anyone to use this software for any purpose,
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 * freely, subject to the following restrictions:
-* 
+*
 * 1. The origin of this software must not be misrepresented; you must not
 * 1. The origin of this software must not be misrepresented; you must not
 *    claim that you wrote the original software. If you use this software
 *    claim that you wrote the original software. If you use this software
 *    in a product, an acknowledgment in the product documentation would be
 *    in a product, an acknowledgment in the product documentation would be
@@ -52,5 +52,5 @@ namespace love
 		luax_register_type(L, "Data", w_Data_functions);
 		luax_register_type(L, "Data", w_Data_functions);
 		return 0;
 		return 0;
 	}
 	}
-	
+
 } // love
 } // love

+ 4 - 4
src/common/wrap_Data.h

@@ -1,14 +1,14 @@
 /**
 /**
-* Copyright (c) 2006-2011 LOVE Development Team
-* 
+* Copyright (c) 2006-2012 LOVE Development Team
+*
 * This software is provided 'as-is', without any express or implied
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * warranty.  In no event will the authors be held liable for any damages
 * arising from the use of this software.
 * arising from the use of this software.
-* 
+*
 * Permission is granted to anyone to use this software for any purpose,
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 * freely, subject to the following restrictions:
-* 
+*
 * 1. The origin of this software must not be misrepresented; you must not
 * 1. The origin of this software must not be misrepresented; you must not
 *    claim that you wrote the original software. If you use this software
 *    claim that you wrote the original software. If you use this software
 *    in a product, an acknowledgment in the product documentation would be
 *    in a product, an acknowledgment in the product documentation would be

+ 67 - 0
src/libraries/Box2D/Box2D.h

@@ -0,0 +1,67 @@
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef BOX2D_H
+#define BOX2D_H
+
+/**
+\mainpage Box2D API Documentation
+
+\section intro_sec Getting Started
+
+For documentation please see http://box2d.org/documentation.html
+
+For discussion please visit http://box2d.org/forum
+*/
+
+// These include files constitute the main Box2D API
+
+#include <Box2D/Common/b2Settings.h>
+#include <Box2D/Common/b2Draw.h>
+#include <Box2D/Common/b2Timer.h>
+
+#include <Box2D/Collision/Shapes/b2CircleShape.h>
+#include <Box2D/Collision/Shapes/b2EdgeShape.h>
+#include <Box2D/Collision/Shapes/b2ChainShape.h>
+#include <Box2D/Collision/Shapes/b2PolygonShape.h>
+
+#include <Box2D/Collision/b2BroadPhase.h>
+#include <Box2D/Collision/b2Distance.h>
+#include <Box2D/Collision/b2DynamicTree.h>
+#include <Box2D/Collision/b2TimeOfImpact.h>
+
+#include <Box2D/Dynamics/b2Body.h>
+#include <Box2D/Dynamics/b2Fixture.h>
+#include <Box2D/Dynamics/b2WorldCallbacks.h>
+#include <Box2D/Dynamics/b2TimeStep.h>
+#include <Box2D/Dynamics/b2World.h>
+
+#include <Box2D/Dynamics/Contacts/b2Contact.h>
+
+#include <Box2D/Dynamics/Joints/b2DistanceJoint.h>
+#include <Box2D/Dynamics/Joints/b2FrictionJoint.h>
+#include <Box2D/Dynamics/Joints/b2GearJoint.h>
+#include <Box2D/Dynamics/Joints/b2WheelJoint.h>
+#include <Box2D/Dynamics/Joints/b2MouseJoint.h>
+#include <Box2D/Dynamics/Joints/b2PrismaticJoint.h>
+#include <Box2D/Dynamics/Joints/b2PulleyJoint.h>
+#include <Box2D/Dynamics/Joints/b2RevoluteJoint.h>
+#include <Box2D/Dynamics/Joints/b2RopeJoint.h>
+#include <Box2D/Dynamics/Joints/b2WeldJoint.h>
+
+#endif

+ 171 - 0
src/libraries/Box2D/Collision/Shapes/b2ChainShape.cpp

@@ -0,0 +1,171 @@
+/*
+* Copyright (c) 2006-2010 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Collision/Shapes/b2ChainShape.h>
+#include <Box2D/Collision/Shapes/b2EdgeShape.h>
+#include <new>
+#include <cstring>
+using namespace std;
+
+b2ChainShape::~b2ChainShape()
+{
+	b2Free(m_vertices);
+	m_vertices = NULL;
+	m_count = 0;
+}
+
+void b2ChainShape::CreateLoop(const b2Vec2* vertices, int32 count)
+{
+	b2Assert(m_vertices == NULL && m_count == 0);
+	b2Assert(count >= 3);
+	m_count = count + 1;
+	m_vertices = (b2Vec2*)b2Alloc(m_count * sizeof(b2Vec2));
+	memcpy(m_vertices, vertices, count * sizeof(b2Vec2));
+	m_vertices[count] = m_vertices[0];
+	m_prevVertex = m_vertices[m_count - 2];
+	m_nextVertex = m_vertices[1];
+	m_hasPrevVertex = true;
+	m_hasNextVertex = true;
+}
+
+void b2ChainShape::CreateChain(const b2Vec2* vertices, int32 count)
+{
+	b2Assert(m_vertices == NULL && m_count == 0);
+	b2Assert(count >= 2);
+	m_count = count;
+	m_vertices = (b2Vec2*)b2Alloc(count * sizeof(b2Vec2));
+	memcpy(m_vertices, vertices, m_count * sizeof(b2Vec2));
+	m_hasPrevVertex = false;
+	m_hasNextVertex = false;
+}
+
+void b2ChainShape::SetPrevVertex(const b2Vec2& prevVertex)
+{
+	m_prevVertex = prevVertex;
+	m_hasPrevVertex = true;
+}
+
+void b2ChainShape::SetNextVertex(const b2Vec2& nextVertex)
+{
+	m_nextVertex = nextVertex;
+	m_hasNextVertex = true;
+}
+
+b2Shape* b2ChainShape::Clone(b2BlockAllocator* allocator) const
+{
+	void* mem = allocator->Allocate(sizeof(b2ChainShape));
+	b2ChainShape* clone = new (mem) b2ChainShape;
+	clone->CreateChain(m_vertices, m_count);
+	clone->m_prevVertex = m_prevVertex;
+	clone->m_nextVertex = m_nextVertex;
+	clone->m_hasPrevVertex = m_hasPrevVertex;
+	clone->m_hasNextVertex = m_hasNextVertex;
+	return clone;
+}
+
+int32 b2ChainShape::GetChildCount() const
+{
+	// edge count = vertex count - 1
+	return m_count - 1;
+}
+
+void b2ChainShape::GetChildEdge(b2EdgeShape* edge, int32 index) const
+{
+	b2Assert(0 <= index && index < m_count - 1);
+	edge->m_type = b2Shape::e_edge;
+	edge->m_radius = m_radius;
+
+	edge->m_vertex1 = m_vertices[index + 0];
+	edge->m_vertex2 = m_vertices[index + 1];
+
+	if (index > 0)
+	{
+		edge->m_vertex0 = m_vertices[index - 1];
+		edge->m_hasVertex0 = true;
+	}
+	else
+	{
+		edge->m_vertex0 = m_prevVertex;
+		edge->m_hasVertex0 = m_hasPrevVertex;
+	}
+
+	if (index < m_count - 2)
+	{
+		edge->m_vertex3 = m_vertices[index + 2];
+		edge->m_hasVertex3 = true;
+	}
+	else
+	{
+		edge->m_vertex3 = m_nextVertex;
+		edge->m_hasVertex3 = m_hasNextVertex;
+	}
+}
+
+bool b2ChainShape::TestPoint(const b2Transform& xf, const b2Vec2& p) const
+{
+	B2_NOT_USED(xf);
+	B2_NOT_USED(p);
+	return false;
+}
+
+bool b2ChainShape::RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
+							const b2Transform& xf, int32 childIndex) const
+{
+	b2Assert(childIndex < m_count);
+
+	b2EdgeShape edgeShape;
+
+	int32 i1 = childIndex;
+	int32 i2 = childIndex + 1;
+	if (i2 == m_count)
+	{
+		i2 = 0;
+	}
+
+	edgeShape.m_vertex1 = m_vertices[i1];
+	edgeShape.m_vertex2 = m_vertices[i2];
+
+	return edgeShape.RayCast(output, input, xf, 0);
+}
+
+void b2ChainShape::ComputeAABB(b2AABB* aabb, const b2Transform& xf, int32 childIndex) const
+{
+	b2Assert(childIndex < m_count);
+
+	int32 i1 = childIndex;
+	int32 i2 = childIndex + 1;
+	if (i2 == m_count)
+	{
+		i2 = 0;
+	}
+
+	b2Vec2 v1 = b2Mul(xf, m_vertices[i1]);
+	b2Vec2 v2 = b2Mul(xf, m_vertices[i2]);
+
+	aabb->lowerBound = b2Min(v1, v2);
+	aabb->upperBound = b2Max(v1, v2);
+}
+
+void b2ChainShape::ComputeMass(b2MassData* massData, float32 density) const
+{
+	B2_NOT_USED(density);
+
+	massData->mass = 0.0f;
+	massData->center.SetZero();
+	massData->I = 0.0f;
+}

+ 102 - 0
src/libraries/Box2D/Collision/Shapes/b2ChainShape.h

@@ -0,0 +1,102 @@
+/*
+* Copyright (c) 2006-2010 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef B2_CHAIN_SHAPE_H
+#define B2_CHAIN_SHAPE_H
+
+#include <Box2D/Collision/Shapes/b2Shape.h>
+
+class b2EdgeShape;
+
+/// A chain shape is a free form sequence of line segments.
+/// The chain has two-sided collision, so you can use inside and outside collision.
+/// Therefore, you may use any winding order.
+/// Since there may be many vertices, they are allocated using b2Alloc.
+/// Connectivity information is used to create smooth collisions.
+/// WARNING: The chain will not collide properly if there are self-intersections.
+class b2ChainShape : public b2Shape
+{
+public:
+	b2ChainShape();
+
+	/// The destructor frees the vertices using b2Free.
+	~b2ChainShape();
+
+	/// Create a loop. This automatically adjusts connectivity.
+	/// @param vertices an array of vertices, these are copied
+	/// @param count the vertex count
+	void CreateLoop(const b2Vec2* vertices, int32 count);
+
+	/// Create a chain with isolated end vertices.
+	/// @param vertices an array of vertices, these are copied
+	/// @param count the vertex count
+	void CreateChain(const b2Vec2* vertices, int32 count);
+
+	/// Establish connectivity to a vertex that precedes the first vertex.
+	/// Don't call this for loops.
+	void SetPrevVertex(const b2Vec2& prevVertex);
+
+	/// Establish connectivity to a vertex that follows the last vertex.
+	/// Don't call this for loops.
+	void SetNextVertex(const b2Vec2& nextVertex);
+
+	/// Implement b2Shape. Vertices are cloned using b2Alloc.
+	b2Shape* Clone(b2BlockAllocator* allocator) const;
+
+	/// @see b2Shape::GetChildCount
+	int32 GetChildCount() const;
+
+	/// Get a child edge.
+	void GetChildEdge(b2EdgeShape* edge, int32 index) const;
+
+	/// This always return false.
+	/// @see b2Shape::TestPoint
+	bool TestPoint(const b2Transform& transform, const b2Vec2& p) const;
+
+	/// Implement b2Shape.
+	bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
+					const b2Transform& transform, int32 childIndex) const;
+
+	/// @see b2Shape::ComputeAABB
+	void ComputeAABB(b2AABB* aabb, const b2Transform& transform, int32 childIndex) const;
+
+	/// Chains have zero mass.
+	/// @see b2Shape::ComputeMass
+	void ComputeMass(b2MassData* massData, float32 density) const;
+
+	/// The vertices. Owned by this class.
+	b2Vec2* m_vertices;
+
+	/// The vertex count.
+	int32 m_count;
+
+	b2Vec2 m_prevVertex, m_nextVertex;
+	bool m_hasPrevVertex, m_hasNextVertex;
+};
+
+inline b2ChainShape::b2ChainShape()
+{
+	m_type = e_chain;
+	m_radius = b2_polygonRadius;
+	m_vertices = NULL;
+	m_count = 0;
+	m_hasPrevVertex = NULL;
+	m_hasNextVertex = NULL;
+}
+
+#endif

+ 100 - 0
src/libraries/Box2D/Collision/Shapes/b2CircleShape.cpp

@@ -0,0 +1,100 @@
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Collision/Shapes/b2CircleShape.h>
+#include <new>
+using namespace std;
+
+b2Shape* b2CircleShape::Clone(b2BlockAllocator* allocator) const
+{
+	void* mem = allocator->Allocate(sizeof(b2CircleShape));
+	b2CircleShape* clone = new (mem) b2CircleShape;
+	*clone = *this;
+	return clone;
+}
+
+int32 b2CircleShape::GetChildCount() const
+{
+	return 1;
+}
+
+bool b2CircleShape::TestPoint(const b2Transform& transform, const b2Vec2& p) const
+{
+	b2Vec2 center = transform.p + b2Mul(transform.q, m_p);
+	b2Vec2 d = p - center;
+	return b2Dot(d, d) <= m_radius * m_radius;
+}
+
+// Collision Detection in Interactive 3D Environments by Gino van den Bergen
+// From Section 3.1.2
+// x = s + a * r
+// norm(x) = radius
+bool b2CircleShape::RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
+							const b2Transform& transform, int32 childIndex) const
+{
+	B2_NOT_USED(childIndex);
+
+	b2Vec2 position = transform.p + b2Mul(transform.q, m_p);
+	b2Vec2 s = input.p1 - position;
+	float32 b = b2Dot(s, s) - m_radius * m_radius;
+
+	// Solve quadratic equation.
+	b2Vec2 r = input.p2 - input.p1;
+	float32 c =  b2Dot(s, r);
+	float32 rr = b2Dot(r, r);
+	float32 sigma = c * c - rr * b;
+
+	// Check for negative discriminant and short segment.
+	if (sigma < 0.0f || rr < b2_epsilon)
+	{
+		return false;
+	}
+
+	// Find the point of intersection of the line with the circle.
+	float32 a = -(c + b2Sqrt(sigma));
+
+	// Is the intersection point on the segment?
+	if (0.0f <= a && a <= input.maxFraction * rr)
+	{
+		a /= rr;
+		output->fraction = a;
+		output->normal = s + a * r;
+		output->normal.Normalize();
+		return true;
+	}
+
+	return false;
+}
+
+void b2CircleShape::ComputeAABB(b2AABB* aabb, const b2Transform& transform, int32 childIndex) const
+{
+	B2_NOT_USED(childIndex);
+
+	b2Vec2 p = transform.p + b2Mul(transform.q, m_p);
+	aabb->lowerBound.Set(p.x - m_radius, p.y - m_radius);
+	aabb->upperBound.Set(p.x + m_radius, p.y + m_radius);
+}
+
+void b2CircleShape::ComputeMass(b2MassData* massData, float32 density) const
+{
+	massData->mass = density * b2_pi * m_radius * m_radius;
+	massData->center = m_p;
+
+	// inertia about the local origin
+	massData->I = massData->mass * (0.5f * m_radius * m_radius + b2Dot(m_p, m_p));
+}

+ 91 - 0
src/libraries/Box2D/Collision/Shapes/b2CircleShape.h

@@ -0,0 +1,91 @@
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef B2_CIRCLE_SHAPE_H
+#define B2_CIRCLE_SHAPE_H
+
+#include <Box2D/Collision/Shapes/b2Shape.h>
+
+/// A circle shape.
+class b2CircleShape : public b2Shape
+{
+public:
+	b2CircleShape();
+
+	/// Implement b2Shape.
+	b2Shape* Clone(b2BlockAllocator* allocator) const;
+
+	/// @see b2Shape::GetChildCount
+	int32 GetChildCount() const;
+
+	/// Implement b2Shape.
+	bool TestPoint(const b2Transform& transform, const b2Vec2& p) const;
+
+	/// Implement b2Shape.
+	bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
+				const b2Transform& transform, int32 childIndex) const;
+
+	/// @see b2Shape::ComputeAABB
+	void ComputeAABB(b2AABB* aabb, const b2Transform& transform, int32 childIndex) const;
+
+	/// @see b2Shape::ComputeMass
+	void ComputeMass(b2MassData* massData, float32 density) const;
+
+	/// Get the supporting vertex index in the given direction.
+	int32 GetSupport(const b2Vec2& d) const;
+
+	/// Get the supporting vertex in the given direction.
+	const b2Vec2& GetSupportVertex(const b2Vec2& d) const;
+
+	/// Get the vertex count.
+	int32 GetVertexCount() const { return 1; }
+
+	/// Get a vertex by index. Used by b2Distance.
+	const b2Vec2& GetVertex(int32 index) const;
+
+	/// Position
+	b2Vec2 m_p;
+};
+
+inline b2CircleShape::b2CircleShape()
+{
+	m_type = e_circle;
+	m_radius = 0.0f;
+	m_p.SetZero();
+}
+
+inline int32 b2CircleShape::GetSupport(const b2Vec2 &d) const
+{
+	B2_NOT_USED(d);
+	return 0;
+}
+
+inline const b2Vec2& b2CircleShape::GetSupportVertex(const b2Vec2 &d) const
+{
+	B2_NOT_USED(d);
+	return m_p;
+}
+
+inline const b2Vec2& b2CircleShape::GetVertex(int32 index) const
+{
+	B2_NOT_USED(index);
+	b2Assert(index == 0);
+	return m_p;
+}
+
+#endif

+ 139 - 0
src/libraries/Box2D/Collision/Shapes/b2EdgeShape.cpp

@@ -0,0 +1,139 @@
+/*
+* Copyright (c) 2006-2010 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Collision/Shapes/b2EdgeShape.h>
+#include <new>
+using namespace std;
+
+void b2EdgeShape::Set(const b2Vec2& v1, const b2Vec2& v2)
+{
+	m_vertex1 = v1;
+	m_vertex2 = v2;
+	m_hasVertex0 = false;
+	m_hasVertex3 = false;
+}
+
+b2Shape* b2EdgeShape::Clone(b2BlockAllocator* allocator) const
+{
+	void* mem = allocator->Allocate(sizeof(b2EdgeShape));
+	b2EdgeShape* clone = new (mem) b2EdgeShape;
+	*clone = *this;
+	return clone;
+}
+
+int32 b2EdgeShape::GetChildCount() const
+{
+	return 1;
+}
+
+bool b2EdgeShape::TestPoint(const b2Transform& xf, const b2Vec2& p) const
+{
+	B2_NOT_USED(xf);
+	B2_NOT_USED(p);
+	return false;
+}
+
+// p = p1 + t * d
+// v = v1 + s * e
+// p1 + t * d = v1 + s * e
+// s * e - t * d = p1 - v1
+bool b2EdgeShape::RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
+							const b2Transform& xf, int32 childIndex) const
+{
+	B2_NOT_USED(childIndex);
+
+	// Put the ray into the edge's frame of reference.
+	b2Vec2 p1 = b2MulT(xf.q, input.p1 - xf.p);
+	b2Vec2 p2 = b2MulT(xf.q, input.p2 - xf.p);
+	b2Vec2 d = p2 - p1;
+
+	b2Vec2 v1 = m_vertex1;
+	b2Vec2 v2 = m_vertex2;
+	b2Vec2 e = v2 - v1;
+	b2Vec2 normal(e.y, -e.x);
+	normal.Normalize();
+
+	// q = p1 + t * d
+	// dot(normal, q - v1) = 0
+	// dot(normal, p1 - v1) + t * dot(normal, d) = 0
+	float32 numerator = b2Dot(normal, v1 - p1);
+	float32 denominator = b2Dot(normal, d);
+
+	if (denominator == 0.0f)
+	{
+		return false;
+	}
+
+	float32 t = numerator / denominator;
+	if (t < 0.0f || input.maxFraction < t)
+	{
+		return false;
+	}
+
+	b2Vec2 q = p1 + t * d;
+
+	// q = v1 + s * r
+	// s = dot(q - v1, r) / dot(r, r)
+	b2Vec2 r = v2 - v1;
+	float32 rr = b2Dot(r, r);
+	if (rr == 0.0f)
+	{
+		return false;
+	}
+
+	float32 s = b2Dot(q - v1, r) / rr;
+	if (s < 0.0f || 1.0f < s)
+	{
+		return false;
+	}
+
+	output->fraction = t;
+	if (numerator > 0.0f)
+	{
+		output->normal = -normal;
+	}
+	else
+	{
+		output->normal = normal;
+	}
+	return true;
+}
+
+void b2EdgeShape::ComputeAABB(b2AABB* aabb, const b2Transform& xf, int32 childIndex) const
+{
+	B2_NOT_USED(childIndex);
+
+	b2Vec2 v1 = b2Mul(xf, m_vertex1);
+	b2Vec2 v2 = b2Mul(xf, m_vertex2);
+
+	b2Vec2 lower = b2Min(v1, v2);
+	b2Vec2 upper = b2Max(v1, v2);
+
+	b2Vec2 r(m_radius, m_radius);
+	aabb->lowerBound = lower - r;
+	aabb->upperBound = upper + r;
+}
+
+void b2EdgeShape::ComputeMass(b2MassData* massData, float32 density) const
+{
+	B2_NOT_USED(density);
+
+	massData->mass = 0.0f;
+	massData->center = 0.5f * (m_vertex1 + m_vertex2);
+	massData->I = 0.0f;
+}

+ 74 - 0
src/libraries/Box2D/Collision/Shapes/b2EdgeShape.h

@@ -0,0 +1,74 @@
+/*
+* Copyright (c) 2006-2010 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef B2_EDGE_SHAPE_H
+#define B2_EDGE_SHAPE_H
+
+#include <Box2D/Collision/Shapes/b2Shape.h>
+
+/// A line segment (edge) shape. These can be connected in chains or loops
+/// to other edge shapes. The connectivity information is used to ensure
+/// correct contact normals.
+class b2EdgeShape : public b2Shape
+{
+public:
+	b2EdgeShape();
+
+	/// Set this as an isolated edge.
+	void Set(const b2Vec2& v1, const b2Vec2& v2);
+
+	/// Implement b2Shape.
+	b2Shape* Clone(b2BlockAllocator* allocator) const;
+
+	/// @see b2Shape::GetChildCount
+	int32 GetChildCount() const;
+
+	/// @see b2Shape::TestPoint
+	bool TestPoint(const b2Transform& transform, const b2Vec2& p) const;
+
+	/// Implement b2Shape.
+	bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
+				const b2Transform& transform, int32 childIndex) const;
+
+	/// @see b2Shape::ComputeAABB
+	void ComputeAABB(b2AABB* aabb, const b2Transform& transform, int32 childIndex) const;
+
+	/// @see b2Shape::ComputeMass
+	void ComputeMass(b2MassData* massData, float32 density) const;
+	
+	/// These are the edge vertices
+	b2Vec2 m_vertex1, m_vertex2;
+
+	/// Optional adjacent vertices. These are used for smooth collision.
+	b2Vec2 m_vertex0, m_vertex3;
+	bool m_hasVertex0, m_hasVertex3;
+};
+
+inline b2EdgeShape::b2EdgeShape()
+{
+	m_type = e_edge;
+	m_radius = b2_polygonRadius;
+	m_vertex0.x = 0.0f;
+	m_vertex0.y = 0.0f;
+	m_vertex3.x = 0.0f;
+	m_vertex3.y = 0.0f;
+	m_hasVertex0 = false;
+	m_hasVertex3 = false;
+}
+
+#endif

+ 361 - 0
src/libraries/Box2D/Collision/Shapes/b2PolygonShape.cpp

@@ -0,0 +1,361 @@
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Collision/Shapes/b2PolygonShape.h>
+#include <new>
+
+b2Shape* b2PolygonShape::Clone(b2BlockAllocator* allocator) const
+{
+	void* mem = allocator->Allocate(sizeof(b2PolygonShape));
+	b2PolygonShape* clone = new (mem) b2PolygonShape;
+	*clone = *this;
+	return clone;
+}
+
+void b2PolygonShape::SetAsBox(float32 hx, float32 hy)
+{
+	m_vertexCount = 4;
+	m_vertices[0].Set(-hx, -hy);
+	m_vertices[1].Set( hx, -hy);
+	m_vertices[2].Set( hx,  hy);
+	m_vertices[3].Set(-hx,  hy);
+	m_normals[0].Set(0.0f, -1.0f);
+	m_normals[1].Set(1.0f, 0.0f);
+	m_normals[2].Set(0.0f, 1.0f);
+	m_normals[3].Set(-1.0f, 0.0f);
+	m_centroid.SetZero();
+}
+
+void b2PolygonShape::SetAsBox(float32 hx, float32 hy, const b2Vec2& center, float32 angle)
+{
+	m_vertexCount = 4;
+	m_vertices[0].Set(-hx, -hy);
+	m_vertices[1].Set( hx, -hy);
+	m_vertices[2].Set( hx,  hy);
+	m_vertices[3].Set(-hx,  hy);
+	m_normals[0].Set(0.0f, -1.0f);
+	m_normals[1].Set(1.0f, 0.0f);
+	m_normals[2].Set(0.0f, 1.0f);
+	m_normals[3].Set(-1.0f, 0.0f);
+	m_centroid = center;
+
+	b2Transform xf;
+	xf.p = center;
+	xf.q.Set(angle);
+
+	// Transform vertices and normals.
+	for (int32 i = 0; i < m_vertexCount; ++i)
+	{
+		m_vertices[i] = b2Mul(xf, m_vertices[i]);
+		m_normals[i] = b2Mul(xf.q, m_normals[i]);
+	}
+}
+
+int32 b2PolygonShape::GetChildCount() const
+{
+	return 1;
+}
+
+static b2Vec2 ComputeCentroid(const b2Vec2* vs, int32 count)
+{
+	b2Assert(count >= 3);
+
+	b2Vec2 c; c.Set(0.0f, 0.0f);
+	float32 area = 0.0f;
+
+	// pRef is the reference point for forming triangles.
+	// It's location doesn't change the result (except for rounding error).
+	b2Vec2 pRef(0.0f, 0.0f);
+#if 0
+	// This code would put the reference point inside the polygon.
+	for (int32 i = 0; i < count; ++i)
+	{
+		pRef += vs[i];
+	}
+	pRef *= 1.0f / count;
+#endif
+
+	const float32 inv3 = 1.0f / 3.0f;
+
+	for (int32 i = 0; i < count; ++i)
+	{
+		// Triangle vertices.
+		b2Vec2 p1 = pRef;
+		b2Vec2 p2 = vs[i];
+		b2Vec2 p3 = i + 1 < count ? vs[i+1] : vs[0];
+
+		b2Vec2 e1 = p2 - p1;
+		b2Vec2 e2 = p3 - p1;
+
+		float32 D = b2Cross(e1, e2);
+
+		float32 triangleArea = 0.5f * D;
+		area += triangleArea;
+
+		// Area weighted centroid
+		c += triangleArea * inv3 * (p1 + p2 + p3);
+	}
+
+	// Centroid
+	b2Assert(area > b2_epsilon);
+	c *= 1.0f / area;
+	return c;
+}
+
+void b2PolygonShape::Set(const b2Vec2* vertices, int32 count)
+{
+	b2Assert(3 <= count && count <= b2_maxPolygonVertices);
+	m_vertexCount = count;
+
+	// Copy vertices.
+	for (int32 i = 0; i < m_vertexCount; ++i)
+	{
+		m_vertices[i] = vertices[i];
+	}
+
+	// Compute normals. Ensure the edges have non-zero length.
+	for (int32 i = 0; i < m_vertexCount; ++i)
+	{
+		int32 i1 = i;
+		int32 i2 = i + 1 < m_vertexCount ? i + 1 : 0;
+		b2Vec2 edge = m_vertices[i2] - m_vertices[i1];
+		b2Assert(edge.LengthSquared() > b2_epsilon * b2_epsilon);
+		m_normals[i] = b2Cross(edge, 1.0f);
+		m_normals[i].Normalize();
+	}
+
+#ifdef _DEBUG
+	// Ensure the polygon is convex and the interior
+	// is to the left of each edge.
+	for (int32 i = 0; i < m_vertexCount; ++i)
+	{
+		int32 i1 = i;
+		int32 i2 = i + 1 < m_vertexCount ? i + 1 : 0;
+		b2Vec2 edge = m_vertices[i2] - m_vertices[i1];
+
+		for (int32 j = 0; j < m_vertexCount; ++j)
+		{
+			// Don't check vertices on the current edge.
+			if (j == i1 || j == i2)
+			{
+				continue;
+			}
+			
+			b2Vec2 r = m_vertices[j] - m_vertices[i1];
+
+			// If this crashes, your polygon is non-convex, has colinear edges,
+			// or the winding order is wrong.
+			float32 s = b2Cross(edge, r);
+			b2Assert(s > 0.0f && "ERROR: Please ensure your polygon is convex and has a CCW winding order");
+		}
+	}
+#endif
+
+	// Compute the polygon centroid.
+	m_centroid = ComputeCentroid(m_vertices, m_vertexCount);
+}
+
+bool b2PolygonShape::TestPoint(const b2Transform& xf, const b2Vec2& p) const
+{
+	b2Vec2 pLocal = b2MulT(xf.q, p - xf.p);
+
+	for (int32 i = 0; i < m_vertexCount; ++i)
+	{
+		float32 dot = b2Dot(m_normals[i], pLocal - m_vertices[i]);
+		if (dot > 0.0f)
+		{
+			return false;
+		}
+	}
+
+	return true;
+}
+
+bool b2PolygonShape::RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
+								const b2Transform& xf, int32 childIndex) const
+{
+	B2_NOT_USED(childIndex);
+
+	// Put the ray into the polygon's frame of reference.
+	b2Vec2 p1 = b2MulT(xf.q, input.p1 - xf.p);
+	b2Vec2 p2 = b2MulT(xf.q, input.p2 - xf.p);
+	b2Vec2 d = p2 - p1;
+
+	float32 lower = 0.0f, upper = input.maxFraction;
+
+	int32 index = -1;
+
+	for (int32 i = 0; i < m_vertexCount; ++i)
+	{
+		// p = p1 + a * d
+		// dot(normal, p - v) = 0
+		// dot(normal, p1 - v) + a * dot(normal, d) = 0
+		float32 numerator = b2Dot(m_normals[i], m_vertices[i] - p1);
+		float32 denominator = b2Dot(m_normals[i], d);
+
+		if (denominator == 0.0f)
+		{	
+			if (numerator < 0.0f)
+			{
+				return false;
+			}
+		}
+		else
+		{
+			// Note: we want this predicate without division:
+			// lower < numerator / denominator, where denominator < 0
+			// Since denominator < 0, we have to flip the inequality:
+			// lower < numerator / denominator <==> denominator * lower > numerator.
+			if (denominator < 0.0f && numerator < lower * denominator)
+			{
+				// Increase lower.
+				// The segment enters this half-space.
+				lower = numerator / denominator;
+				index = i;
+			}
+			else if (denominator > 0.0f && numerator < upper * denominator)
+			{
+				// Decrease upper.
+				// The segment exits this half-space.
+				upper = numerator / denominator;
+			}
+		}
+
+		// The use of epsilon here causes the assert on lower to trip
+		// in some cases. Apparently the use of epsilon was to make edge
+		// shapes work, but now those are handled separately.
+		//if (upper < lower - b2_epsilon)
+		if (upper < lower)
+		{
+			return false;
+		}
+	}
+
+	b2Assert(0.0f <= lower && lower <= input.maxFraction);
+
+	if (index >= 0)
+	{
+		output->fraction = lower;
+		output->normal = b2Mul(xf.q, m_normals[index]);
+		return true;
+	}
+
+	return false;
+}
+
+void b2PolygonShape::ComputeAABB(b2AABB* aabb, const b2Transform& xf, int32 childIndex) const
+{
+	B2_NOT_USED(childIndex);
+
+	b2Vec2 lower = b2Mul(xf, m_vertices[0]);
+	b2Vec2 upper = lower;
+
+	for (int32 i = 1; i < m_vertexCount; ++i)
+	{
+		b2Vec2 v = b2Mul(xf, m_vertices[i]);
+		lower = b2Min(lower, v);
+		upper = b2Max(upper, v);
+	}
+
+	b2Vec2 r(m_radius, m_radius);
+	aabb->lowerBound = lower - r;
+	aabb->upperBound = upper + r;
+}
+
+void b2PolygonShape::ComputeMass(b2MassData* massData, float32 density) const
+{
+	// Polygon mass, centroid, and inertia.
+	// Let rho be the polygon density in mass per unit area.
+	// Then:
+	// mass = rho * int(dA)
+	// centroid.x = (1/mass) * rho * int(x * dA)
+	// centroid.y = (1/mass) * rho * int(y * dA)
+	// I = rho * int((x*x + y*y) * dA)
+	//
+	// We can compute these integrals by summing all the integrals
+	// for each triangle of the polygon. To evaluate the integral
+	// for a single triangle, we make a change of variables to
+	// the (u,v) coordinates of the triangle:
+	// x = x0 + e1x * u + e2x * v
+	// y = y0 + e1y * u + e2y * v
+	// where 0 <= u && 0 <= v && u + v <= 1.
+	//
+	// We integrate u from [0,1-v] and then v from [0,1].
+	// We also need to use the Jacobian of the transformation:
+	// D = cross(e1, e2)
+	//
+	// Simplification: triangle centroid = (1/3) * (p1 + p2 + p3)
+	//
+	// The rest of the derivation is handled by computer algebra.
+
+	b2Assert(m_vertexCount >= 3);
+
+	b2Vec2 center; center.Set(0.0f, 0.0f);
+	float32 area = 0.0f;
+	float32 I = 0.0f;
+
+	// s is the reference point for forming triangles.
+	// It's location doesn't change the result (except for rounding error).
+	b2Vec2 s(0.0f, 0.0f);
+
+	// This code would put the reference point inside the polygon.
+	for (int32 i = 0; i < m_vertexCount; ++i)
+	{
+		s += m_vertices[i];
+	}
+	s *= 1.0f / m_vertexCount;
+
+	const float32 k_inv3 = 1.0f / 3.0f;
+
+	for (int32 i = 0; i < m_vertexCount; ++i)
+	{
+		// Triangle vertices.
+		b2Vec2 e1 = m_vertices[i] - s;
+		b2Vec2 e2 = i + 1 < m_vertexCount ? m_vertices[i+1] - s : m_vertices[0] - s;
+
+		float32 D = b2Cross(e1, e2);
+
+		float32 triangleArea = 0.5f * D;
+		area += triangleArea;
+
+		// Area weighted centroid
+		center += triangleArea * k_inv3 * (e1 + e2);
+
+		float32 ex1 = e1.x, ey1 = e1.y;
+		float32 ex2 = e2.x, ey2 = e2.y;
+
+		float32 intx2 = ex1*ex1 + ex2*ex1 + ex2*ex2;
+		float32 inty2 = ey1*ey1 + ey2*ey1 + ey2*ey2;
+
+		I += (0.25f * k_inv3 * D) * (intx2 + inty2);
+	}
+
+	// Total mass
+	massData->mass = density * area;
+
+	// Center of mass
+	b2Assert(area > b2_epsilon);
+	center *= 1.0f / area;
+	massData->center = center + s;
+
+	// Inertia tensor relative to the local origin (point s).
+	massData->I = density * I;
+	
+	// Shift to center of mass then to original body origin.
+	massData->I += massData->mass * (b2Dot(massData->center, massData->center) - b2Dot(center, center));
+}

+ 95 - 0
src/libraries/Box2D/Collision/Shapes/b2PolygonShape.h

@@ -0,0 +1,95 @@
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef B2_POLYGON_SHAPE_H
+#define B2_POLYGON_SHAPE_H
+
+#include <Box2D/Collision/Shapes/b2Shape.h>
+
+/// A convex polygon. It is assumed that the interior of the polygon is to
+/// the left of each edge.
+/// Polygons have a maximum number of vertices equal to b2_maxPolygonVertices.
+/// In most cases you should not need many vertices for a convex polygon.
+class b2PolygonShape : public b2Shape
+{
+public:
+	b2PolygonShape();
+
+	/// Implement b2Shape.
+	b2Shape* Clone(b2BlockAllocator* allocator) const;
+
+	/// @see b2Shape::GetChildCount
+	int32 GetChildCount() const;
+
+	/// Copy vertices. This assumes the vertices define a convex polygon.
+	/// It is assumed that the exterior is the the right of each edge.
+	/// The count must be in the range [3, b2_maxPolygonVertices].
+	void Set(const b2Vec2* vertices, int32 vertexCount);
+
+	/// Build vertices to represent an axis-aligned box.
+	/// @param hx the half-width.
+	/// @param hy the half-height.
+	void SetAsBox(float32 hx, float32 hy);
+
+	/// Build vertices to represent an oriented box.
+	/// @param hx the half-width.
+	/// @param hy the half-height.
+	/// @param center the center of the box in local coordinates.
+	/// @param angle the rotation of the box in local coordinates.
+	void SetAsBox(float32 hx, float32 hy, const b2Vec2& center, float32 angle);
+
+	/// @see b2Shape::TestPoint
+	bool TestPoint(const b2Transform& transform, const b2Vec2& p) const;
+
+	/// Implement b2Shape.
+	bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
+					const b2Transform& transform, int32 childIndex) const;
+
+	/// @see b2Shape::ComputeAABB
+	void ComputeAABB(b2AABB* aabb, const b2Transform& transform, int32 childIndex) const;
+
+	/// @see b2Shape::ComputeMass
+	void ComputeMass(b2MassData* massData, float32 density) const;
+
+	/// Get the vertex count.
+	int32 GetVertexCount() const { return m_vertexCount; }
+
+	/// Get a vertex by index.
+	const b2Vec2& GetVertex(int32 index) const;
+
+	b2Vec2 m_centroid;
+	b2Vec2 m_vertices[b2_maxPolygonVertices];
+	b2Vec2 m_normals[b2_maxPolygonVertices];
+	int32 m_vertexCount;
+};
+
+inline b2PolygonShape::b2PolygonShape()
+{
+	m_type = e_polygon;
+	m_radius = b2_polygonRadius;
+	m_vertexCount = 0;
+	m_centroid.SetZero();
+}
+
+inline const b2Vec2& b2PolygonShape::GetVertex(int32 index) const
+{
+	b2Assert(0 <= index && index < m_vertexCount);
+	return m_vertices[index];
+}
+
+#endif

+ 101 - 0
src/libraries/Box2D/Collision/Shapes/b2Shape.h

@@ -0,0 +1,101 @@
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef B2_SHAPE_H
+#define B2_SHAPE_H
+
+#include <Box2D/Common/b2BlockAllocator.h>
+#include <Box2D/Common/b2Math.h>
+#include <Box2D/Collision/b2Collision.h>
+
+/// This holds the mass data computed for a shape.
+struct b2MassData
+{
+	/// The mass of the shape, usually in kilograms.
+	float32 mass;
+
+	/// The position of the shape's centroid relative to the shape's origin.
+	b2Vec2 center;
+
+	/// The rotational inertia of the shape about the local origin.
+	float32 I;
+};
+
+/// A shape is used for collision detection. You can create a shape however you like.
+/// Shapes used for simulation in b2World are created automatically when a b2Fixture
+/// is created. Shapes may encapsulate a one or more child shapes.
+class b2Shape
+{
+public:
+	
+	enum Type
+	{
+		e_circle = 0,
+		e_edge = 1,
+		e_polygon = 2,
+		e_chain = 3,
+		e_typeCount = 4
+	};
+
+	virtual ~b2Shape() {}
+
+	/// Clone the concrete shape using the provided allocator.
+	virtual b2Shape* Clone(b2BlockAllocator* allocator) const = 0;
+
+	/// Get the type of this shape. You can use this to down cast to the concrete shape.
+	/// @return the shape type.
+	Type GetType() const;
+
+	/// Get the number of child primitives.
+	virtual int32 GetChildCount() const = 0;
+
+	/// Test a point for containment in this shape. This only works for convex shapes.
+	/// @param xf the shape world transform.
+	/// @param p a point in world coordinates.
+	virtual bool TestPoint(const b2Transform& xf, const b2Vec2& p) const = 0;
+
+	/// Cast a ray against a child shape.
+	/// @param output the ray-cast results.
+	/// @param input the ray-cast input parameters.
+	/// @param transform the transform to be applied to the shape.
+	/// @param childIndex the child shape index
+	virtual bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
+						const b2Transform& transform, int32 childIndex) const = 0;
+
+	/// Given a transform, compute the associated axis aligned bounding box for a child shape.
+	/// @param aabb returns the axis aligned box.
+	/// @param xf the world transform of the shape.
+	/// @param childIndex the child shape
+	virtual void ComputeAABB(b2AABB* aabb, const b2Transform& xf, int32 childIndex) const = 0;
+
+	/// Compute the mass properties of this shape using its dimensions and density.
+	/// The inertia tensor is computed about the local origin.
+	/// @param massData returns the mass data for this shape.
+	/// @param density the density in kilograms per meter squared.
+	virtual void ComputeMass(b2MassData* massData, float32 density) const = 0;
+
+	Type m_type;
+	float32 m_radius;
+};
+
+inline b2Shape::Type b2Shape::GetType() const
+{
+	return m_type;
+}
+
+#endif

+ 122 - 0
src/libraries/Box2D/Collision/b2BroadPhase.cpp

@@ -0,0 +1,122 @@
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Collision/b2BroadPhase.h>
+#include <cstring>
+using namespace std;
+
+b2BroadPhase::b2BroadPhase()
+{
+	m_proxyCount = 0;
+
+	m_pairCapacity = 16;
+	m_pairCount = 0;
+	m_pairBuffer = (b2Pair*)b2Alloc(m_pairCapacity * sizeof(b2Pair));
+
+	m_moveCapacity = 16;
+	m_moveCount = 0;
+	m_moveBuffer = (int32*)b2Alloc(m_moveCapacity * sizeof(int32));
+}
+
+b2BroadPhase::~b2BroadPhase()
+{
+	b2Free(m_moveBuffer);
+	b2Free(m_pairBuffer);
+}
+
+int32 b2BroadPhase::CreateProxy(const b2AABB& aabb, void* userData)
+{
+	int32 proxyId = m_tree.CreateProxy(aabb, userData);
+	++m_proxyCount;
+	BufferMove(proxyId);
+	return proxyId;
+}
+
+void b2BroadPhase::DestroyProxy(int32 proxyId)
+{
+	UnBufferMove(proxyId);
+	--m_proxyCount;
+	m_tree.DestroyProxy(proxyId);
+}
+
+void b2BroadPhase::MoveProxy(int32 proxyId, const b2AABB& aabb, const b2Vec2& displacement)
+{
+	bool buffer = m_tree.MoveProxy(proxyId, aabb, displacement);
+	if (buffer)
+	{
+		BufferMove(proxyId);
+	}
+}
+
+void b2BroadPhase::TouchProxy(int32 proxyId)
+{
+	BufferMove(proxyId);
+}
+
+void b2BroadPhase::BufferMove(int32 proxyId)
+{
+	if (m_moveCount == m_moveCapacity)
+	{
+		int32* oldBuffer = m_moveBuffer;
+		m_moveCapacity *= 2;
+		m_moveBuffer = (int32*)b2Alloc(m_moveCapacity * sizeof(int32));
+		memcpy(m_moveBuffer, oldBuffer, m_moveCount * sizeof(int32));
+		b2Free(oldBuffer);
+	}
+
+	m_moveBuffer[m_moveCount] = proxyId;
+	++m_moveCount;
+}
+
+void b2BroadPhase::UnBufferMove(int32 proxyId)
+{
+	for (int32 i = 0; i < m_moveCount; ++i)
+	{
+		if (m_moveBuffer[i] == proxyId)
+		{
+			m_moveBuffer[i] = e_nullProxy;
+			return;
+		}
+	}
+}
+
+// This is called from b2DynamicTree::Query when we are gathering pairs.
+bool b2BroadPhase::QueryCallback(int32 proxyId)
+{
+	// A proxy cannot form a pair with itself.
+	if (proxyId == m_queryProxyId)
+	{
+		return true;
+	}
+
+	// Grow the pair buffer as needed.
+	if (m_pairCount == m_pairCapacity)
+	{
+		b2Pair* oldBuffer = m_pairBuffer;
+		m_pairCapacity *= 2;
+		m_pairBuffer = (b2Pair*)b2Alloc(m_pairCapacity * sizeof(b2Pair));
+		memcpy(m_pairBuffer, oldBuffer, m_pairCount * sizeof(b2Pair));
+		b2Free(oldBuffer);
+	}
+
+	m_pairBuffer[m_pairCount].proxyIdA = b2Min(proxyId, m_queryProxyId);
+	m_pairBuffer[m_pairCount].proxyIdB = b2Max(proxyId, m_queryProxyId);
+	++m_pairCount;
+
+	return true;
+}

+ 248 - 0
src/libraries/Box2D/Collision/b2BroadPhase.h

@@ -0,0 +1,248 @@
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef B2_BROAD_PHASE_H
+#define B2_BROAD_PHASE_H
+
+#include <Box2D/Common/b2Settings.h>
+#include <Box2D/Collision/b2Collision.h>
+#include <Box2D/Collision/b2DynamicTree.h>
+#include <algorithm>
+
+struct b2Pair
+{
+	int32 proxyIdA;
+	int32 proxyIdB;
+	int32 next;
+};
+
+/// The broad-phase is used for computing pairs and performing volume queries and ray casts.
+/// This broad-phase does not persist pairs. Instead, this reports potentially new pairs.
+/// It is up to the client to consume the new pairs and to track subsequent overlap.
+class b2BroadPhase
+{
+public:
+
+	enum
+	{
+		e_nullProxy = -1
+	};
+
+	b2BroadPhase();
+	~b2BroadPhase();
+
+	/// Create a proxy with an initial AABB. Pairs are not reported until
+	/// UpdatePairs is called.
+	int32 CreateProxy(const b2AABB& aabb, void* userData);
+
+	/// Destroy a proxy. It is up to the client to remove any pairs.
+	void DestroyProxy(int32 proxyId);
+
+	/// Call MoveProxy as many times as you like, then when you are done
+	/// call UpdatePairs to finalized the proxy pairs (for your time step).
+	void MoveProxy(int32 proxyId, const b2AABB& aabb, const b2Vec2& displacement);
+
+	/// Call to trigger a re-processing of it's pairs on the next call to UpdatePairs.
+	void TouchProxy(int32 proxyId);
+
+	/// Get the fat AABB for a proxy.
+	const b2AABB& GetFatAABB(int32 proxyId) const;
+
+	/// Get user data from a proxy. Returns NULL if the id is invalid.
+	void* GetUserData(int32 proxyId) const;
+
+	/// Test overlap of fat AABBs.
+	bool TestOverlap(int32 proxyIdA, int32 proxyIdB) const;
+
+	/// Get the number of proxies.
+	int32 GetProxyCount() const;
+
+	/// Update the pairs. This results in pair callbacks. This can only add pairs.
+	template <typename T>
+	void UpdatePairs(T* callback);
+
+	/// Query an AABB for overlapping proxies. The callback class
+	/// is called for each proxy that overlaps the supplied AABB.
+	template <typename T>
+	void Query(T* callback, const b2AABB& aabb) const;
+
+	/// Ray-cast against the proxies in the tree. This relies on the callback
+	/// to perform a exact ray-cast in the case were the proxy contains a shape.
+	/// The callback also performs the any collision filtering. This has performance
+	/// roughly equal to k * log(n), where k is the number of collisions and n is the
+	/// number of proxies in the tree.
+	/// @param input the ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1).
+	/// @param callback a callback class that is called for each proxy that is hit by the ray.
+	template <typename T>
+	void RayCast(T* callback, const b2RayCastInput& input) const;
+
+	/// Get the height of the embedded tree.
+	int32 GetTreeHeight() const;
+
+	/// Get the balance of the embedded tree.
+	int32 GetTreeBalance() const;
+
+	/// Get the quality metric of the embedded tree.
+	float32 GetTreeQuality() const;
+
+private:
+
+	friend class b2DynamicTree;
+
+	void BufferMove(int32 proxyId);
+	void UnBufferMove(int32 proxyId);
+
+	bool QueryCallback(int32 proxyId);
+
+	b2DynamicTree m_tree;
+
+	int32 m_proxyCount;
+
+	int32* m_moveBuffer;
+	int32 m_moveCapacity;
+	int32 m_moveCount;
+
+	b2Pair* m_pairBuffer;
+	int32 m_pairCapacity;
+	int32 m_pairCount;
+
+	int32 m_queryProxyId;
+};
+
+/// This is used to sort pairs.
+inline bool b2PairLessThan(const b2Pair& pair1, const b2Pair& pair2)
+{
+	if (pair1.proxyIdA < pair2.proxyIdA)
+	{
+		return true;
+	}
+
+	if (pair1.proxyIdA == pair2.proxyIdA)
+	{
+		return pair1.proxyIdB < pair2.proxyIdB;
+	}
+
+	return false;
+}
+
+inline void* b2BroadPhase::GetUserData(int32 proxyId) const
+{
+	return m_tree.GetUserData(proxyId);
+}
+
+inline bool b2BroadPhase::TestOverlap(int32 proxyIdA, int32 proxyIdB) const
+{
+	const b2AABB& aabbA = m_tree.GetFatAABB(proxyIdA);
+	const b2AABB& aabbB = m_tree.GetFatAABB(proxyIdB);
+	return b2TestOverlap(aabbA, aabbB);
+}
+
+inline const b2AABB& b2BroadPhase::GetFatAABB(int32 proxyId) const
+{
+	return m_tree.GetFatAABB(proxyId);
+}
+
+inline int32 b2BroadPhase::GetProxyCount() const
+{
+	return m_proxyCount;
+}
+
+inline int32 b2BroadPhase::GetTreeHeight() const
+{
+	return m_tree.GetHeight();
+}
+
+inline int32 b2BroadPhase::GetTreeBalance() const
+{
+	return m_tree.GetMaxBalance();
+}
+
+inline float32 b2BroadPhase::GetTreeQuality() const
+{
+	return m_tree.GetAreaRatio();
+}
+
+template <typename T>
+void b2BroadPhase::UpdatePairs(T* callback)
+{
+	// Reset pair buffer
+	m_pairCount = 0;
+
+	// Perform tree queries for all moving proxies.
+	for (int32 i = 0; i < m_moveCount; ++i)
+	{
+		m_queryProxyId = m_moveBuffer[i];
+		if (m_queryProxyId == e_nullProxy)
+		{
+			continue;
+		}
+
+		// We have to query the tree with the fat AABB so that
+		// we don't fail to create a pair that may touch later.
+		const b2AABB& fatAABB = m_tree.GetFatAABB(m_queryProxyId);
+
+		// Query tree, create pairs and add them pair buffer.
+		m_tree.Query(this, fatAABB);
+	}
+
+	// Reset move buffer
+	m_moveCount = 0;
+
+	// Sort the pair buffer to expose duplicates.
+	std::sort(m_pairBuffer, m_pairBuffer + m_pairCount, b2PairLessThan);
+
+	// Send the pairs back to the client.
+	int32 i = 0;
+	while (i < m_pairCount)
+	{
+		b2Pair* primaryPair = m_pairBuffer + i;
+		void* userDataA = m_tree.GetUserData(primaryPair->proxyIdA);
+		void* userDataB = m_tree.GetUserData(primaryPair->proxyIdB);
+
+		callback->AddPair(userDataA, userDataB);
+		++i;
+
+		// Skip any duplicate pairs.
+		while (i < m_pairCount)
+		{
+			b2Pair* pair = m_pairBuffer + i;
+			if (pair->proxyIdA != primaryPair->proxyIdA || pair->proxyIdB != primaryPair->proxyIdB)
+			{
+				break;
+			}
+			++i;
+		}
+	}
+
+	// Try to keep the tree balanced.
+	//m_tree.Rebalance(4);
+}
+
+template <typename T>
+inline void b2BroadPhase::Query(T* callback, const b2AABB& aabb) const
+{
+	m_tree.Query(callback, aabb);
+}
+
+template <typename T>
+inline void b2BroadPhase::RayCast(T* callback, const b2RayCastInput& input) const
+{
+	m_tree.RayCast(callback, input);
+}
+
+#endif

+ 154 - 0
src/libraries/Box2D/Collision/b2CollideCircle.cpp

@@ -0,0 +1,154 @@
+/*
+* Copyright (c) 2007-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Collision/b2Collision.h>
+#include <Box2D/Collision/Shapes/b2CircleShape.h>
+#include <Box2D/Collision/Shapes/b2PolygonShape.h>
+
+void b2CollideCircles(
+	b2Manifold* manifold,
+	const b2CircleShape* circleA, const b2Transform& xfA,
+	const b2CircleShape* circleB, const b2Transform& xfB)
+{
+	manifold->pointCount = 0;
+
+	b2Vec2 pA = b2Mul(xfA, circleA->m_p);
+	b2Vec2 pB = b2Mul(xfB, circleB->m_p);
+
+	b2Vec2 d = pB - pA;
+	float32 distSqr = b2Dot(d, d);
+	float32 rA = circleA->m_radius, rB = circleB->m_radius;
+	float32 radius = rA + rB;
+	if (distSqr > radius * radius)
+	{
+		return;
+	}
+
+	manifold->type = b2Manifold::e_circles;
+	manifold->localPoint = circleA->m_p;
+	manifold->localNormal.SetZero();
+	manifold->pointCount = 1;
+
+	manifold->points[0].localPoint = circleB->m_p;
+	manifold->points[0].id.key = 0;
+}
+
+void b2CollidePolygonAndCircle(
+	b2Manifold* manifold,
+	const b2PolygonShape* polygonA, const b2Transform& xfA,
+	const b2CircleShape* circleB, const b2Transform& xfB)
+{
+	manifold->pointCount = 0;
+
+	// Compute circle position in the frame of the polygon.
+	b2Vec2 c = b2Mul(xfB, circleB->m_p);
+	b2Vec2 cLocal = b2MulT(xfA, c);
+
+	// Find the min separating edge.
+	int32 normalIndex = 0;
+	float32 separation = -b2_maxFloat;
+	float32 radius = polygonA->m_radius + circleB->m_radius;
+	int32 vertexCount = polygonA->m_vertexCount;
+	const b2Vec2* vertices = polygonA->m_vertices;
+	const b2Vec2* normals = polygonA->m_normals;
+
+	for (int32 i = 0; i < vertexCount; ++i)
+	{
+		float32 s = b2Dot(normals[i], cLocal - vertices[i]);
+
+		if (s > radius)
+		{
+			// Early out.
+			return;
+		}
+
+		if (s > separation)
+		{
+			separation = s;
+			normalIndex = i;
+		}
+	}
+
+	// Vertices that subtend the incident face.
+	int32 vertIndex1 = normalIndex;
+	int32 vertIndex2 = vertIndex1 + 1 < vertexCount ? vertIndex1 + 1 : 0;
+	b2Vec2 v1 = vertices[vertIndex1];
+	b2Vec2 v2 = vertices[vertIndex2];
+
+	// If the center is inside the polygon ...
+	if (separation < b2_epsilon)
+	{
+		manifold->pointCount = 1;
+		manifold->type = b2Manifold::e_faceA;
+		manifold->localNormal = normals[normalIndex];
+		manifold->localPoint = 0.5f * (v1 + v2);
+		manifold->points[0].localPoint = circleB->m_p;
+		manifold->points[0].id.key = 0;
+		return;
+	}
+
+	// Compute barycentric coordinates
+	float32 u1 = b2Dot(cLocal - v1, v2 - v1);
+	float32 u2 = b2Dot(cLocal - v2, v1 - v2);
+	if (u1 <= 0.0f)
+	{
+		if (b2DistanceSquared(cLocal, v1) > radius * radius)
+		{
+			return;
+		}
+
+		manifold->pointCount = 1;
+		manifold->type = b2Manifold::e_faceA;
+		manifold->localNormal = cLocal - v1;
+		manifold->localNormal.Normalize();
+		manifold->localPoint = v1;
+		manifold->points[0].localPoint = circleB->m_p;
+		manifold->points[0].id.key = 0;
+	}
+	else if (u2 <= 0.0f)
+	{
+		if (b2DistanceSquared(cLocal, v2) > radius * radius)
+		{
+			return;
+		}
+
+		manifold->pointCount = 1;
+		manifold->type = b2Manifold::e_faceA;
+		manifold->localNormal = cLocal - v2;
+		manifold->localNormal.Normalize();
+		manifold->localPoint = v2;
+		manifold->points[0].localPoint = circleB->m_p;
+		manifold->points[0].id.key = 0;
+	}
+	else
+	{
+		b2Vec2 faceCenter = 0.5f * (v1 + v2);
+		float32 separation = b2Dot(cLocal - faceCenter, normals[vertIndex1]);
+		if (separation > radius)
+		{
+			return;
+		}
+
+		manifold->pointCount = 1;
+		manifold->type = b2Manifold::e_faceA;
+		manifold->localNormal = normals[vertIndex1];
+		manifold->localPoint = faceCenter;
+		manifold->points[0].localPoint = circleB->m_p;
+		manifold->points[0].id.key = 0;
+	}
+}

+ 698 - 0
src/libraries/Box2D/Collision/b2CollideEdge.cpp

@@ -0,0 +1,698 @@
+/*
+ * Copyright (c) 2007-2009 Erin Catto http://www.box2d.org
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include <Box2D/Collision/b2Collision.h>
+#include <Box2D/Collision/Shapes/b2CircleShape.h>
+#include <Box2D/Collision/Shapes/b2EdgeShape.h>
+#include <Box2D/Collision/Shapes/b2PolygonShape.h>
+
+
+// Compute contact points for edge versus circle.
+// This accounts for edge connectivity.
+void b2CollideEdgeAndCircle(b2Manifold* manifold,
+							const b2EdgeShape* edgeA, const b2Transform& xfA,
+							const b2CircleShape* circleB, const b2Transform& xfB)
+{
+	manifold->pointCount = 0;
+	
+	// Compute circle in frame of edge
+	b2Vec2 Q = b2MulT(xfA, b2Mul(xfB, circleB->m_p));
+	
+	b2Vec2 A = edgeA->m_vertex1, B = edgeA->m_vertex2;
+	b2Vec2 e = B - A;
+	
+	// Barycentric coordinates
+	float32 u = b2Dot(e, B - Q);
+	float32 v = b2Dot(e, Q - A);
+	
+	float32 radius = edgeA->m_radius + circleB->m_radius;
+	
+	b2ContactFeature cf;
+	cf.indexB = 0;
+	cf.typeB = b2ContactFeature::e_vertex;
+	
+	// Region A
+	if (v <= 0.0f)
+	{
+		b2Vec2 P = A;
+		b2Vec2 d = Q - P;
+		float32 dd = b2Dot(d, d);
+		if (dd > radius * radius)
+		{
+			return;
+		}
+		
+		// Is there an edge connected to A?
+		if (edgeA->m_hasVertex0)
+		{
+			b2Vec2 A1 = edgeA->m_vertex0;
+			b2Vec2 B1 = A;
+			b2Vec2 e1 = B1 - A1;
+			float32 u1 = b2Dot(e1, B1 - Q);
+			
+			// Is the circle in Region AB of the previous edge?
+			if (u1 > 0.0f)
+			{
+				return;
+			}
+		}
+		
+		cf.indexA = 0;
+		cf.typeA = b2ContactFeature::e_vertex;
+		manifold->pointCount = 1;
+		manifold->type = b2Manifold::e_circles;
+		manifold->localNormal.SetZero();
+		manifold->localPoint = P;
+		manifold->points[0].id.key = 0;
+		manifold->points[0].id.cf = cf;
+		manifold->points[0].localPoint = circleB->m_p;
+		return;
+	}
+	
+	// Region B
+	if (u <= 0.0f)
+	{
+		b2Vec2 P = B;
+		b2Vec2 d = Q - P;
+		float32 dd = b2Dot(d, d);
+		if (dd > radius * radius)
+		{
+			return;
+		}
+		
+		// Is there an edge connected to B?
+		if (edgeA->m_hasVertex3)
+		{
+			b2Vec2 B2 = edgeA->m_vertex3;
+			b2Vec2 A2 = B;
+			b2Vec2 e2 = B2 - A2;
+			float32 v2 = b2Dot(e2, Q - A2);
+			
+			// Is the circle in Region AB of the next edge?
+			if (v2 > 0.0f)
+			{
+				return;
+			}
+		}
+		
+		cf.indexA = 1;
+		cf.typeA = b2ContactFeature::e_vertex;
+		manifold->pointCount = 1;
+		manifold->type = b2Manifold::e_circles;
+		manifold->localNormal.SetZero();
+		manifold->localPoint = P;
+		manifold->points[0].id.key = 0;
+		manifold->points[0].id.cf = cf;
+		manifold->points[0].localPoint = circleB->m_p;
+		return;
+	}
+	
+	// Region AB
+	float32 den = b2Dot(e, e);
+	b2Assert(den > 0.0f);
+	b2Vec2 P = (1.0f / den) * (u * A + v * B);
+	b2Vec2 d = Q - P;
+	float32 dd = b2Dot(d, d);
+	if (dd > radius * radius)
+	{
+		return;
+	}
+	
+	b2Vec2 n(-e.y, e.x);
+	if (b2Dot(n, Q - A) < 0.0f)
+	{
+		n.Set(-n.x, -n.y);
+	}
+	n.Normalize();
+	
+	cf.indexA = 0;
+	cf.typeA = b2ContactFeature::e_face;
+	manifold->pointCount = 1;
+	manifold->type = b2Manifold::e_faceA;
+	manifold->localNormal = n;
+	manifold->localPoint = A;
+	manifold->points[0].id.key = 0;
+	manifold->points[0].id.cf = cf;
+	manifold->points[0].localPoint = circleB->m_p;
+}
+
+// This structure is used to keep track of the best separating axis.
+struct b2EPAxis
+{
+	enum Type
+	{
+		e_unknown,
+		e_edgeA,
+		e_edgeB
+	};
+	
+	Type type;
+	int32 index;
+	float32 separation;
+};
+
+// This holds polygon B expressed in frame A.
+struct b2TempPolygon
+{
+	b2Vec2 vertices[b2_maxPolygonVertices];
+	b2Vec2 normals[b2_maxPolygonVertices];
+	int32 count;
+};
+
+// Reference face used for clipping
+struct b2ReferenceFace
+{
+	int32 i1, i2;
+	
+	b2Vec2 v1, v2;
+	
+	b2Vec2 normal;
+	
+	b2Vec2 sideNormal1;
+	float32 sideOffset1;
+	
+	b2Vec2 sideNormal2;
+	float32 sideOffset2;
+};
+
+// This class collides and edge and a polygon, taking into account edge adjacency.
+struct b2EPCollider
+{
+	void Collide(b2Manifold* manifold, const b2EdgeShape* edgeA, const b2Transform& xfA,
+				 const b2PolygonShape* polygonB, const b2Transform& xfB);
+	b2EPAxis ComputeEdgeSeparation();
+	b2EPAxis ComputePolygonSeparation();
+	
+	enum VertexType
+	{
+		e_isolated,
+		e_concave,
+		e_convex
+	};
+	
+	b2TempPolygon m_polygonB;
+	
+	b2Transform m_xf;
+	b2Vec2 m_centroidB;
+	b2Vec2 m_v0, m_v1, m_v2, m_v3;
+	b2Vec2 m_normal0, m_normal1, m_normal2;
+	b2Vec2 m_normal;
+	VertexType m_type1, m_type2;
+	b2Vec2 m_lowerLimit, m_upperLimit;
+	float32 m_radius;
+	bool m_front;
+};
+
+// Algorithm:
+// 1. Classify v1 and v2
+// 2. Classify polygon centroid as front or back
+// 3. Flip normal if necessary
+// 4. Initialize normal range to [-pi, pi] about face normal
+// 5. Adjust normal range according to adjacent edges
+// 6. Visit each separating axes, only accept axes within the range
+// 7. Return if _any_ axis indicates separation
+// 8. Clip
+void b2EPCollider::Collide(b2Manifold* manifold, const b2EdgeShape* edgeA, const b2Transform& xfA,
+						   const b2PolygonShape* polygonB, const b2Transform& xfB)
+{
+	m_xf = b2MulT(xfA, xfB);
+	
+	m_centroidB = b2Mul(m_xf, polygonB->m_centroid);
+	
+	m_v0 = edgeA->m_vertex0;
+	m_v1 = edgeA->m_vertex1;
+	m_v2 = edgeA->m_vertex2;
+	m_v3 = edgeA->m_vertex3;
+	
+	bool hasVertex0 = edgeA->m_hasVertex0;
+	bool hasVertex3 = edgeA->m_hasVertex3;
+	
+	b2Vec2 edge1 = m_v2 - m_v1;
+	edge1.Normalize();
+	m_normal1.Set(edge1.y, -edge1.x);
+	float32 offset1 = b2Dot(m_normal1, m_centroidB - m_v1);
+	float32 offset0 = 0.0f, offset2 = 0.0f;
+	bool convex1 = false, convex2 = false;
+	
+	// Is there a preceding edge?
+	if (hasVertex0)
+	{
+		b2Vec2 edge0 = m_v1 - m_v0;
+		edge0.Normalize();
+		m_normal0.Set(edge0.y, -edge0.x);
+		convex1 = b2Cross(edge0, edge1) >= 0.0f;
+		offset0 = b2Dot(m_normal0, m_centroidB - m_v0);
+	}
+	
+	// Is there a following edge?
+	if (hasVertex3)
+	{
+		b2Vec2 edge2 = m_v3 - m_v2;
+		edge2.Normalize();
+		m_normal2.Set(edge2.y, -edge2.x);
+		convex2 = b2Cross(edge1, edge2) > 0.0f;
+		offset2 = b2Dot(m_normal2, m_centroidB - m_v2);
+	}
+	
+	// Determine front or back collision. Determine collision normal limits.
+	if (hasVertex0 && hasVertex3)
+	{
+		if (convex1 && convex2)
+		{
+			m_front = offset0 >= 0.0f || offset1 >= 0.0f || offset2 >= 0.0f;
+			if (m_front)
+			{
+				m_normal = m_normal1;
+				m_lowerLimit = m_normal0;
+				m_upperLimit = m_normal2;
+			}
+			else
+			{
+				m_normal = -m_normal1;
+				m_lowerLimit = -m_normal1;
+				m_upperLimit = -m_normal1;
+			}
+		}
+		else if (convex1)
+		{
+			m_front = offset0 >= 0.0f || (offset1 >= 0.0f && offset2 >= 0.0f);
+			if (m_front)
+			{
+				m_normal = m_normal1;
+				m_lowerLimit = m_normal0;
+				m_upperLimit = m_normal1;
+			}
+			else
+			{
+				m_normal = -m_normal1;
+				m_lowerLimit = -m_normal2;
+				m_upperLimit = -m_normal1;
+			}
+		}
+		else if (convex2)
+		{
+			m_front = offset2 >= 0.0f || (offset0 >= 0.0f && offset1 >= 0.0f);
+			if (m_front)
+			{
+				m_normal = m_normal1;
+				m_lowerLimit = m_normal1;
+				m_upperLimit = m_normal2;
+			}
+			else
+			{
+				m_normal = -m_normal1;
+				m_lowerLimit = -m_normal1;
+				m_upperLimit = -m_normal0;
+			}
+		}
+		else
+		{
+			m_front = offset0 >= 0.0f && offset1 >= 0.0f && offset2 >= 0.0f;
+			if (m_front)
+			{
+				m_normal = m_normal1;
+				m_lowerLimit = m_normal1;
+				m_upperLimit = m_normal1;
+			}
+			else
+			{
+				m_normal = -m_normal1;
+				m_lowerLimit = -m_normal2;
+				m_upperLimit = -m_normal0;
+			}
+		}
+	}
+	else if (hasVertex0)
+	{
+		if (convex1)
+		{
+			m_front = offset0 >= 0.0f || offset1 >= 0.0f;
+			if (m_front)
+			{
+				m_normal = m_normal1;
+				m_lowerLimit = m_normal0;
+				m_upperLimit = -m_normal1;
+			}
+			else
+			{
+				m_normal = -m_normal1;
+				m_lowerLimit = m_normal1;
+				m_upperLimit = -m_normal1;
+			}
+		}
+		else
+		{
+			m_front = offset0 >= 0.0f && offset1 >= 0.0f;
+			if (m_front)
+			{
+				m_normal = m_normal1;
+				m_lowerLimit = m_normal1;
+				m_upperLimit = -m_normal1;
+			}
+			else
+			{
+				m_normal = -m_normal1;
+				m_lowerLimit = m_normal1;
+				m_upperLimit = -m_normal0;
+			}
+		}
+	}
+	else if (hasVertex3)
+	{
+		if (convex2)
+		{
+			m_front = offset1 >= 0.0f || offset2 >= 0.0f;
+			if (m_front)
+			{
+				m_normal = m_normal1;
+				m_lowerLimit = -m_normal1;
+				m_upperLimit = m_normal2;
+			}
+			else
+			{
+				m_normal = -m_normal1;
+				m_lowerLimit = -m_normal1;
+				m_upperLimit = m_normal1;
+			}
+		}
+		else
+		{
+			m_front = offset1 >= 0.0f && offset2 >= 0.0f;
+			if (m_front)
+			{
+				m_normal = m_normal1;
+				m_lowerLimit = -m_normal1;
+				m_upperLimit = m_normal1;
+			}
+			else
+			{
+				m_normal = -m_normal1;
+				m_lowerLimit = -m_normal2;
+				m_upperLimit = m_normal1;
+			}
+		}		
+	}
+	else
+	{
+		m_front = offset1 >= 0.0f;
+		if (m_front)
+		{
+			m_normal = m_normal1;
+			m_lowerLimit = -m_normal1;
+			m_upperLimit = -m_normal1;
+		}
+		else
+		{
+			m_normal = -m_normal1;
+			m_lowerLimit = m_normal1;
+			m_upperLimit = m_normal1;
+		}
+	}
+	
+	// Get polygonB in frameA
+	m_polygonB.count = polygonB->m_vertexCount;
+	for (int32 i = 0; i < polygonB->m_vertexCount; ++i)
+	{
+		m_polygonB.vertices[i] = b2Mul(m_xf, polygonB->m_vertices[i]);
+		m_polygonB.normals[i] = b2Mul(m_xf.q, polygonB->m_normals[i]);
+	}
+	
+	m_radius = 2.0f * b2_polygonRadius;
+	
+	manifold->pointCount = 0;
+	
+	b2EPAxis edgeAxis = ComputeEdgeSeparation();
+	
+	// If no valid normal can be found than this edge should not collide.
+	if (edgeAxis.type == b2EPAxis::e_unknown)
+	{
+		return;
+	}
+	
+	if (edgeAxis.separation > m_radius)
+	{
+		return;
+	}
+	
+	b2EPAxis polygonAxis = ComputePolygonSeparation();
+	if (polygonAxis.type != b2EPAxis::e_unknown && polygonAxis.separation > m_radius)
+	{
+		return;
+	}
+	
+	// Use hysteresis for jitter reduction.
+	const float32 k_relativeTol = 0.98f;
+	const float32 k_absoluteTol = 0.001f;
+	
+	b2EPAxis primaryAxis;
+	if (polygonAxis.type == b2EPAxis::e_unknown)
+	{
+		primaryAxis = edgeAxis;
+	}
+	else if (polygonAxis.separation > k_relativeTol * edgeAxis.separation + k_absoluteTol)
+	{
+		primaryAxis = polygonAxis;
+	}
+	else
+	{
+		primaryAxis = edgeAxis;
+	}
+	
+	b2ClipVertex ie[2];
+	b2ReferenceFace rf;
+	if (primaryAxis.type == b2EPAxis::e_edgeA)
+	{
+		manifold->type = b2Manifold::e_faceA;
+		
+		// Search for the polygon normal that is most anti-parallel to the edge normal.
+		int32 bestIndex = 0;
+		float32 bestValue = b2Dot(m_normal, m_polygonB.normals[0]);
+		for (int32 i = 1; i < m_polygonB.count; ++i)
+		{
+			float32 value = b2Dot(m_normal, m_polygonB.normals[i]);
+			if (value < bestValue)
+			{
+				bestValue = value;
+				bestIndex = i;
+			}
+		}
+		
+		int32 i1 = bestIndex;
+		int32 i2 = i1 + 1 < m_polygonB.count ? i1 + 1 : 0;
+		
+		ie[0].v = m_polygonB.vertices[i1];
+		ie[0].id.cf.indexA = 0;
+		ie[0].id.cf.indexB = i1;
+		ie[0].id.cf.typeA = b2ContactFeature::e_face;
+		ie[0].id.cf.typeB = b2ContactFeature::e_vertex;
+		
+		ie[1].v = m_polygonB.vertices[i2];
+		ie[1].id.cf.indexA = 0;
+		ie[1].id.cf.indexB = i2;
+		ie[1].id.cf.typeA = b2ContactFeature::e_face;
+		ie[1].id.cf.typeB = b2ContactFeature::e_vertex;
+		
+		if (m_front)
+		{
+			rf.i1 = 0;
+			rf.i2 = 1;
+			rf.v1 = m_v1;
+			rf.v2 = m_v2;
+			rf.normal = m_normal1;
+		}
+		else
+		{
+			rf.i1 = 1;
+			rf.i2 = 0;
+			rf.v1 = m_v2;
+			rf.v2 = m_v1;
+			rf.normal = -m_normal1;
+		}		
+	}
+	else
+	{
+		manifold->type = b2Manifold::e_faceB;
+		
+		ie[0].v = m_v1;
+		ie[0].id.cf.indexA = 0;
+		ie[0].id.cf.indexB = primaryAxis.index;
+		ie[0].id.cf.typeA = b2ContactFeature::e_vertex;
+		ie[0].id.cf.typeB = b2ContactFeature::e_face;
+		
+		ie[1].v = m_v2;
+		ie[1].id.cf.indexA = 0;
+		ie[1].id.cf.indexB = primaryAxis.index;		
+		ie[1].id.cf.typeA = b2ContactFeature::e_vertex;
+		ie[1].id.cf.typeB = b2ContactFeature::e_face;
+		
+		rf.i1 = primaryAxis.index;
+		rf.i2 = rf.i1 + 1 < m_polygonB.count ? rf.i1 + 1 : 0;
+		rf.v1 = m_polygonB.vertices[rf.i1];
+		rf.v2 = m_polygonB.vertices[rf.i2];
+		rf.normal = m_polygonB.normals[rf.i1];
+	}
+	
+	rf.sideNormal1.Set(rf.normal.y, -rf.normal.x);
+	rf.sideNormal2 = -rf.sideNormal1;
+	rf.sideOffset1 = b2Dot(rf.sideNormal1, rf.v1);
+	rf.sideOffset2 = b2Dot(rf.sideNormal2, rf.v2);
+	
+	// Clip incident edge against extruded edge1 side edges.
+	b2ClipVertex clipPoints1[2];
+	b2ClipVertex clipPoints2[2];
+	int32 np;
+	
+	// Clip to box side 1
+	np = b2ClipSegmentToLine(clipPoints1, ie, rf.sideNormal1, rf.sideOffset1, rf.i1);
+	
+	if (np < b2_maxManifoldPoints)
+	{
+		return;
+	}
+	
+	// Clip to negative box side 1
+	np = b2ClipSegmentToLine(clipPoints2, clipPoints1, rf.sideNormal2, rf.sideOffset2, rf.i2);
+	
+	if (np < b2_maxManifoldPoints)
+	{
+		return;
+	}
+	
+	// Now clipPoints2 contains the clipped points.
+	if (primaryAxis.type == b2EPAxis::e_edgeA)
+	{
+		manifold->localNormal = rf.normal;
+		manifold->localPoint = rf.v1;
+	}
+	else
+	{
+		manifold->localNormal = polygonB->m_normals[rf.i1];
+		manifold->localPoint = polygonB->m_vertices[rf.i1];
+	}
+	
+	int32 pointCount = 0;
+	for (int32 i = 0; i < b2_maxManifoldPoints; ++i)
+	{
+		float32 separation;
+		
+		separation = b2Dot(rf.normal, clipPoints2[i].v - rf.v1);
+		
+		if (separation <= m_radius)
+		{
+			b2ManifoldPoint* cp = manifold->points + pointCount;
+			
+			if (primaryAxis.type == b2EPAxis::e_edgeA)
+			{
+				cp->localPoint = b2MulT(m_xf, clipPoints2[i].v);
+				cp->id = clipPoints2[i].id;
+			}
+			else
+			{
+				cp->localPoint = clipPoints2[i].v;
+				cp->id.cf.typeA = clipPoints2[i].id.cf.typeB;
+				cp->id.cf.typeB = clipPoints2[i].id.cf.typeA;
+				cp->id.cf.indexA = clipPoints2[i].id.cf.indexB;
+				cp->id.cf.indexB = clipPoints2[i].id.cf.indexA;
+			}
+			
+			++pointCount;
+		}
+	}
+	
+	manifold->pointCount = pointCount;
+}
+
+b2EPAxis b2EPCollider::ComputeEdgeSeparation()
+{
+	b2EPAxis axis;
+	axis.type = b2EPAxis::e_edgeA;
+	axis.index = m_front ? 0 : 1;
+	axis.separation = FLT_MAX;
+	
+	for (int32 i = 0; i < m_polygonB.count; ++i)
+	{
+		float32 s = b2Dot(m_normal, m_polygonB.vertices[i] - m_v1);
+		if (s < axis.separation)
+		{
+			axis.separation = s;
+		}
+	}
+	
+	return axis;
+}
+
+b2EPAxis b2EPCollider::ComputePolygonSeparation()
+{
+	b2EPAxis axis;
+	axis.type = b2EPAxis::e_unknown;
+	axis.index = -1;
+	axis.separation = -FLT_MAX;
+
+	b2Vec2 perp(-m_normal.y, m_normal.x);
+
+	for (int32 i = 0; i < m_polygonB.count; ++i)
+	{
+		b2Vec2 n = -m_polygonB.normals[i];
+		
+		float32 s1 = b2Dot(n, m_polygonB.vertices[i] - m_v1);
+		float32 s2 = b2Dot(n, m_polygonB.vertices[i] - m_v2);
+		float32 s = b2Min(s1, s2);
+		
+		if (s > m_radius)
+		{
+			// No collision
+			axis.type = b2EPAxis::e_edgeB;
+			axis.index = i;
+			axis.separation = s;
+			return axis;
+		}
+		
+		// Adjacency
+		if (b2Dot(n, perp) >= 0.0f)
+		{
+			if (b2Dot(n - m_upperLimit, m_normal) < -b2_angularSlop)
+			{
+				continue;
+			}
+		}
+		else
+		{
+			if (b2Dot(n - m_lowerLimit, m_normal) < -b2_angularSlop)
+			{
+				continue;
+			}
+		}
+		
+		if (s > axis.separation)
+		{
+			axis.type = b2EPAxis::e_edgeB;
+			axis.index = i;
+			axis.separation = s;
+		}
+	}
+	
+	return axis;
+}
+
+void b2CollideEdgeAndPolygon(	b2Manifold* manifold,
+							 const b2EdgeShape* edgeA, const b2Transform& xfA,
+							 const b2PolygonShape* polygonB, const b2Transform& xfB)
+{
+	b2EPCollider collider;
+	collider.Collide(manifold, edgeA, xfA, polygonB, xfB);
+}

+ 317 - 0
src/libraries/Box2D/Collision/b2CollidePolygon.cpp

@@ -0,0 +1,317 @@
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Collision/b2Collision.h>
+#include <Box2D/Collision/Shapes/b2PolygonShape.h>
+
+// Find the separation between poly1 and poly2 for a give edge normal on poly1.
+static float32 b2EdgeSeparation(const b2PolygonShape* poly1, const b2Transform& xf1, int32 edge1,
+							  const b2PolygonShape* poly2, const b2Transform& xf2)
+{
+	const b2Vec2* vertices1 = poly1->m_vertices;
+	const b2Vec2* normals1 = poly1->m_normals;
+
+	int32 count2 = poly2->m_vertexCount;
+	const b2Vec2* vertices2 = poly2->m_vertices;
+
+	b2Assert(0 <= edge1 && edge1 < poly1->m_vertexCount);
+
+	// Convert normal from poly1's frame into poly2's frame.
+	b2Vec2 normal1World = b2Mul(xf1.q, normals1[edge1]);
+	b2Vec2 normal1 = b2MulT(xf2.q, normal1World);
+
+	// Find support vertex on poly2 for -normal.
+	int32 index = 0;
+	float32 minDot = b2_maxFloat;
+
+	for (int32 i = 0; i < count2; ++i)
+	{
+		float32 dot = b2Dot(vertices2[i], normal1);
+		if (dot < minDot)
+		{
+			minDot = dot;
+			index = i;
+		}
+	}
+
+	b2Vec2 v1 = b2Mul(xf1, vertices1[edge1]);
+	b2Vec2 v2 = b2Mul(xf2, vertices2[index]);
+	float32 separation = b2Dot(v2 - v1, normal1World);
+	return separation;
+}
+
+// Find the max separation between poly1 and poly2 using edge normals from poly1.
+static float32 b2FindMaxSeparation(int32* edgeIndex,
+								 const b2PolygonShape* poly1, const b2Transform& xf1,
+								 const b2PolygonShape* poly2, const b2Transform& xf2)
+{
+	int32 count1 = poly1->m_vertexCount;
+	const b2Vec2* normals1 = poly1->m_normals;
+
+	// Vector pointing from the centroid of poly1 to the centroid of poly2.
+	b2Vec2 d = b2Mul(xf2, poly2->m_centroid) - b2Mul(xf1, poly1->m_centroid);
+	b2Vec2 dLocal1 = b2MulT(xf1.q, d);
+
+	// Find edge normal on poly1 that has the largest projection onto d.
+	int32 edge = 0;
+	float32 maxDot = -b2_maxFloat;
+	for (int32 i = 0; i < count1; ++i)
+	{
+		float32 dot = b2Dot(normals1[i], dLocal1);
+		if (dot > maxDot)
+		{
+			maxDot = dot;
+			edge = i;
+		}
+	}
+
+	// Get the separation for the edge normal.
+	float32 s = b2EdgeSeparation(poly1, xf1, edge, poly2, xf2);
+
+	// Check the separation for the previous edge normal.
+	int32 prevEdge = edge - 1 >= 0 ? edge - 1 : count1 - 1;
+	float32 sPrev = b2EdgeSeparation(poly1, xf1, prevEdge, poly2, xf2);
+
+	// Check the separation for the next edge normal.
+	int32 nextEdge = edge + 1 < count1 ? edge + 1 : 0;
+	float32 sNext = b2EdgeSeparation(poly1, xf1, nextEdge, poly2, xf2);
+
+	// Find the best edge and the search direction.
+	int32 bestEdge;
+	float32 bestSeparation;
+	int32 increment;
+	if (sPrev > s && sPrev > sNext)
+	{
+		increment = -1;
+		bestEdge = prevEdge;
+		bestSeparation = sPrev;
+	}
+	else if (sNext > s)
+	{
+		increment = 1;
+		bestEdge = nextEdge;
+		bestSeparation = sNext;
+	}
+	else
+	{
+		*edgeIndex = edge;
+		return s;
+	}
+
+	// Perform a local search for the best edge normal.
+	for ( ; ; )
+	{
+		if (increment == -1)
+			edge = bestEdge - 1 >= 0 ? bestEdge - 1 : count1 - 1;
+		else
+			edge = bestEdge + 1 < count1 ? bestEdge + 1 : 0;
+
+		s = b2EdgeSeparation(poly1, xf1, edge, poly2, xf2);
+
+		if (s > bestSeparation)
+		{
+			bestEdge = edge;
+			bestSeparation = s;
+		}
+		else
+		{
+			break;
+		}
+	}
+
+	*edgeIndex = bestEdge;
+	return bestSeparation;
+}
+
+static void b2FindIncidentEdge(b2ClipVertex c[2],
+							 const b2PolygonShape* poly1, const b2Transform& xf1, int32 edge1,
+							 const b2PolygonShape* poly2, const b2Transform& xf2)
+{
+	const b2Vec2* normals1 = poly1->m_normals;
+
+	int32 count2 = poly2->m_vertexCount;
+	const b2Vec2* vertices2 = poly2->m_vertices;
+	const b2Vec2* normals2 = poly2->m_normals;
+
+	b2Assert(0 <= edge1 && edge1 < poly1->m_vertexCount);
+
+	// Get the normal of the reference edge in poly2's frame.
+	b2Vec2 normal1 = b2MulT(xf2.q, b2Mul(xf1.q, normals1[edge1]));
+
+	// Find the incident edge on poly2.
+	int32 index = 0;
+	float32 minDot = b2_maxFloat;
+	for (int32 i = 0; i < count2; ++i)
+	{
+		float32 dot = b2Dot(normal1, normals2[i]);
+		if (dot < minDot)
+		{
+			minDot = dot;
+			index = i;
+		}
+	}
+
+	// Build the clip vertices for the incident edge.
+	int32 i1 = index;
+	int32 i2 = i1 + 1 < count2 ? i1 + 1 : 0;
+
+	c[0].v = b2Mul(xf2, vertices2[i1]);
+	c[0].id.cf.indexA = (uint8)edge1;
+	c[0].id.cf.indexB = (uint8)i1;
+	c[0].id.cf.typeA = b2ContactFeature::e_face;
+	c[0].id.cf.typeB = b2ContactFeature::e_vertex;
+
+	c[1].v = b2Mul(xf2, vertices2[i2]);
+	c[1].id.cf.indexA = (uint8)edge1;
+	c[1].id.cf.indexB = (uint8)i2;
+	c[1].id.cf.typeA = b2ContactFeature::e_face;
+	c[1].id.cf.typeB = b2ContactFeature::e_vertex;
+}
+
+// Find edge normal of max separation on A - return if separating axis is found
+// Find edge normal of max separation on B - return if separation axis is found
+// Choose reference edge as min(minA, minB)
+// Find incident edge
+// Clip
+
+// The normal points from 1 to 2
+void b2CollidePolygons(b2Manifold* manifold,
+					  const b2PolygonShape* polyA, const b2Transform& xfA,
+					  const b2PolygonShape* polyB, const b2Transform& xfB)
+{
+	manifold->pointCount = 0;
+	float32 totalRadius = polyA->m_radius + polyB->m_radius;
+
+	int32 edgeA = 0;
+	float32 separationA = b2FindMaxSeparation(&edgeA, polyA, xfA, polyB, xfB);
+	if (separationA > totalRadius)
+		return;
+
+	int32 edgeB = 0;
+	float32 separationB = b2FindMaxSeparation(&edgeB, polyB, xfB, polyA, xfA);
+	if (separationB > totalRadius)
+		return;
+
+	const b2PolygonShape* poly1;	// reference polygon
+	const b2PolygonShape* poly2;	// incident polygon
+	b2Transform xf1, xf2;
+	int32 edge1;		// reference edge
+	uint8 flip;
+	const float32 k_relativeTol = 0.98f;
+	const float32 k_absoluteTol = 0.001f;
+
+	if (separationB > k_relativeTol * separationA + k_absoluteTol)
+	{
+		poly1 = polyB;
+		poly2 = polyA;
+		xf1 = xfB;
+		xf2 = xfA;
+		edge1 = edgeB;
+		manifold->type = b2Manifold::e_faceB;
+		flip = 1;
+	}
+	else
+	{
+		poly1 = polyA;
+		poly2 = polyB;
+		xf1 = xfA;
+		xf2 = xfB;
+		edge1 = edgeA;
+		manifold->type = b2Manifold::e_faceA;
+		flip = 0;
+	}
+
+	b2ClipVertex incidentEdge[2];
+	b2FindIncidentEdge(incidentEdge, poly1, xf1, edge1, poly2, xf2);
+
+	int32 count1 = poly1->m_vertexCount;
+	const b2Vec2* vertices1 = poly1->m_vertices;
+
+	int32 iv1 = edge1;
+	int32 iv2 = edge1 + 1 < count1 ? edge1 + 1 : 0;
+
+	b2Vec2 v11 = vertices1[iv1];
+	b2Vec2 v12 = vertices1[iv2];
+
+	b2Vec2 localTangent = v12 - v11;
+	localTangent.Normalize();
+	
+	b2Vec2 localNormal = b2Cross(localTangent, 1.0f);
+	b2Vec2 planePoint = 0.5f * (v11 + v12);
+
+	b2Vec2 tangent = b2Mul(xf1.q, localTangent);
+	b2Vec2 normal = b2Cross(tangent, 1.0f);
+	
+	v11 = b2Mul(xf1, v11);
+	v12 = b2Mul(xf1, v12);
+
+	// Face offset.
+	float32 frontOffset = b2Dot(normal, v11);
+
+	// Side offsets, extended by polytope skin thickness.
+	float32 sideOffset1 = -b2Dot(tangent, v11) + totalRadius;
+	float32 sideOffset2 = b2Dot(tangent, v12) + totalRadius;
+
+	// Clip incident edge against extruded edge1 side edges.
+	b2ClipVertex clipPoints1[2];
+	b2ClipVertex clipPoints2[2];
+	int np;
+
+	// Clip to box side 1
+	np = b2ClipSegmentToLine(clipPoints1, incidentEdge, -tangent, sideOffset1, iv1);
+
+	if (np < 2)
+		return;
+
+	// Clip to negative box side 1
+	np = b2ClipSegmentToLine(clipPoints2, clipPoints1,  tangent, sideOffset2, iv2);
+
+	if (np < 2)
+	{
+		return;
+	}
+
+	// Now clipPoints2 contains the clipped points.
+	manifold->localNormal = localNormal;
+	manifold->localPoint = planePoint;
+
+	int32 pointCount = 0;
+	for (int32 i = 0; i < b2_maxManifoldPoints; ++i)
+	{
+		float32 separation = b2Dot(normal, clipPoints2[i].v) - frontOffset;
+
+		if (separation <= totalRadius)
+		{
+			b2ManifoldPoint* cp = manifold->points + pointCount;
+			cp->localPoint = b2MulT(xf2, clipPoints2[i].v);
+			cp->id = clipPoints2[i].id;
+			if (flip)
+			{
+				// Swap features
+				b2ContactFeature cf = cp->id.cf;
+				cp->id.cf.indexA = cf.indexB;
+				cp->id.cf.indexB = cf.indexA;
+				cp->id.cf.typeA = cf.typeB;
+				cp->id.cf.typeB = cf.typeA;
+			}
+			++pointCount;
+		}
+	}
+
+	manifold->pointCount = pointCount;
+}

+ 249 - 0
src/libraries/Box2D/Collision/b2Collision.cpp

@@ -0,0 +1,249 @@
+/*
+* Copyright (c) 2007-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Collision/b2Collision.h>
+#include <Box2D/Collision/b2Distance.h>
+
+void b2WorldManifold::Initialize(const b2Manifold* manifold,
+						  const b2Transform& xfA, float32 radiusA,
+						  const b2Transform& xfB, float32 radiusB)
+{
+	if (manifold->pointCount == 0)
+	{
+		return;
+	}
+
+	switch (manifold->type)
+	{
+	case b2Manifold::e_circles:
+		{
+			normal.Set(1.0f, 0.0f);
+			b2Vec2 pointA = b2Mul(xfA, manifold->localPoint);
+			b2Vec2 pointB = b2Mul(xfB, manifold->points[0].localPoint);
+			if (b2DistanceSquared(pointA, pointB) > b2_epsilon * b2_epsilon)
+			{
+				normal = pointB - pointA;
+				normal.Normalize();
+			}
+
+			b2Vec2 cA = pointA + radiusA * normal;
+			b2Vec2 cB = pointB - radiusB * normal;
+			points[0] = 0.5f * (cA + cB);
+		}
+		break;
+
+	case b2Manifold::e_faceA:
+		{
+			normal = b2Mul(xfA.q, manifold->localNormal);
+			b2Vec2 planePoint = b2Mul(xfA, manifold->localPoint);
+			
+			for (int32 i = 0; i < manifold->pointCount; ++i)
+			{
+				b2Vec2 clipPoint = b2Mul(xfB, manifold->points[i].localPoint);
+				b2Vec2 cA = clipPoint + (radiusA - b2Dot(clipPoint - planePoint, normal)) * normal;
+				b2Vec2 cB = clipPoint - radiusB * normal;
+				points[i] = 0.5f * (cA + cB);
+			}
+		}
+		break;
+
+	case b2Manifold::e_faceB:
+		{
+			normal = b2Mul(xfB.q, manifold->localNormal);
+			b2Vec2 planePoint = b2Mul(xfB, manifold->localPoint);
+
+			for (int32 i = 0; i < manifold->pointCount; ++i)
+			{
+				b2Vec2 clipPoint = b2Mul(xfA, manifold->points[i].localPoint);
+				b2Vec2 cB = clipPoint + (radiusB - b2Dot(clipPoint - planePoint, normal)) * normal;
+				b2Vec2 cA = clipPoint - radiusA * normal;
+				points[i] = 0.5f * (cA + cB);
+			}
+
+			// Ensure normal points from A to B.
+			normal = -normal;
+		}
+		break;
+	}
+}
+
+void b2GetPointStates(b2PointState state1[b2_maxManifoldPoints], b2PointState state2[b2_maxManifoldPoints],
+					  const b2Manifold* manifold1, const b2Manifold* manifold2)
+{
+	for (int32 i = 0; i < b2_maxManifoldPoints; ++i)
+	{
+		state1[i] = b2_nullState;
+		state2[i] = b2_nullState;
+	}
+
+	// Detect persists and removes.
+	for (int32 i = 0; i < manifold1->pointCount; ++i)
+	{
+		b2ContactID id = manifold1->points[i].id;
+
+		state1[i] = b2_removeState;
+
+		for (int32 j = 0; j < manifold2->pointCount; ++j)
+		{
+			if (manifold2->points[j].id.key == id.key)
+			{
+				state1[i] = b2_persistState;
+				break;
+			}
+		}
+	}
+
+	// Detect persists and adds.
+	for (int32 i = 0; i < manifold2->pointCount; ++i)
+	{
+		b2ContactID id = manifold2->points[i].id;
+
+		state2[i] = b2_addState;
+
+		for (int32 j = 0; j < manifold1->pointCount; ++j)
+		{
+			if (manifold1->points[j].id.key == id.key)
+			{
+				state2[i] = b2_persistState;
+				break;
+			}
+		}
+	}
+}
+
+// From Real-time Collision Detection, p179.
+bool b2AABB::RayCast(b2RayCastOutput* output, const b2RayCastInput& input) const
+{
+	float32 tmin = -b2_maxFloat;
+	float32 tmax = b2_maxFloat;
+
+	b2Vec2 p = input.p1;
+	b2Vec2 d = input.p2 - input.p1;
+	b2Vec2 absD = b2Abs(d);
+
+	b2Vec2 normal;
+
+	for (int32 i = 0; i < 2; ++i)
+	{
+		if (absD(i) < b2_epsilon)
+		{
+			// Parallel.
+			if (p(i) < lowerBound(i) || upperBound(i) < p(i))
+			{
+				return false;
+			}
+		}
+		else
+		{
+			float32 inv_d = 1.0f / d(i);
+			float32 t1 = (lowerBound(i) - p(i)) * inv_d;
+			float32 t2 = (upperBound(i) - p(i)) * inv_d;
+
+			// Sign of the normal vector.
+			float32 s = -1.0f;
+
+			if (t1 > t2)
+			{
+				b2Swap(t1, t2);
+				s = 1.0f;
+			}
+
+			// Push the min up
+			if (t1 > tmin)
+			{
+				normal.SetZero();
+				normal(i) = s;
+				tmin = t1;
+			}
+
+			// Pull the max down
+			tmax = b2Min(tmax, t2);
+
+			if (tmin > tmax)
+			{
+				return false;
+			}
+		}
+	}
+
+	// Does the ray start inside the box?
+	// Does the ray intersect beyond the max fraction?
+	if (tmin < 0.0f || input.maxFraction < tmin)
+	{
+		return false;
+	}
+
+	// Intersection.
+	output->fraction = tmin;
+	output->normal = normal;
+	return true;
+}
+
+// Sutherland-Hodgman clipping.
+int32 b2ClipSegmentToLine(b2ClipVertex vOut[2], const b2ClipVertex vIn[2],
+						const b2Vec2& normal, float32 offset, int32 vertexIndexA)
+{
+	// Start with no output points
+	int32 numOut = 0;
+
+	// Calculate the distance of end points to the line
+	float32 distance0 = b2Dot(normal, vIn[0].v) - offset;
+	float32 distance1 = b2Dot(normal, vIn[1].v) - offset;
+
+	// If the points are behind the plane
+	if (distance0 <= 0.0f) vOut[numOut++] = vIn[0];
+	if (distance1 <= 0.0f) vOut[numOut++] = vIn[1];
+
+	// If the points are on different sides of the plane
+	if (distance0 * distance1 < 0.0f)
+	{
+		// Find intersection point of edge and plane
+		float32 interp = distance0 / (distance0 - distance1);
+		vOut[numOut].v = vIn[0].v + interp * (vIn[1].v - vIn[0].v);
+
+		// VertexA is hitting edgeB.
+		vOut[numOut].id.cf.indexA = vertexIndexA;
+		vOut[numOut].id.cf.indexB = vIn[0].id.cf.indexB;
+		vOut[numOut].id.cf.typeA = b2ContactFeature::e_vertex;
+		vOut[numOut].id.cf.typeB = b2ContactFeature::e_face;
+		++numOut;
+	}
+
+	return numOut;
+}
+
+bool b2TestOverlap(	const b2Shape* shapeA, int32 indexA,
+					const b2Shape* shapeB, int32 indexB,
+					const b2Transform& xfA, const b2Transform& xfB)
+{
+	b2DistanceInput input;
+	input.proxyA.Set(shapeA, indexA);
+	input.proxyB.Set(shapeB, indexB);
+	input.transformA = xfA;
+	input.transformB = xfB;
+	input.useRadii = true;
+
+	b2SimplexCache cache;
+	cache.count = 0;
+
+	b2DistanceOutput output;
+
+	b2Distance(&output, &cache, &input);
+
+	return output.distance < 10.0f * b2_epsilon;
+}

+ 276 - 0
src/libraries/Box2D/Collision/b2Collision.h

@@ -0,0 +1,276 @@
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef B2_COLLISION_H
+#define B2_COLLISION_H
+
+#include <Box2D/Common/b2Math.h>
+#include <climits>
+
+/// @file
+/// Structures and functions used for computing contact points, distance
+/// queries, and TOI queries.
+
+class b2Shape;
+class b2CircleShape;
+class b2EdgeShape;
+class b2PolygonShape;
+
+const uint8 b2_nullFeature = UCHAR_MAX;
+
+/// The features that intersect to form the contact point
+/// This must be 4 bytes or less.
+struct b2ContactFeature
+{
+	enum Type
+	{
+		e_vertex = 0,
+		e_face = 1
+	};
+
+	uint8 indexA;		///< Feature index on shapeA
+	uint8 indexB;		///< Feature index on shapeB
+	uint8 typeA;		///< The feature type on shapeA
+	uint8 typeB;		///< The feature type on shapeB
+};
+
+/// Contact ids to facilitate warm starting.
+union b2ContactID
+{
+	b2ContactFeature cf;
+	uint32 key;					///< Used to quickly compare contact ids.
+};
+
+/// A manifold point is a contact point belonging to a contact
+/// manifold. It holds details related to the geometry and dynamics
+/// of the contact points.
+/// The local point usage depends on the manifold type:
+/// -e_circles: the local center of circleB
+/// -e_faceA: the local center of cirlceB or the clip point of polygonB
+/// -e_faceB: the clip point of polygonA
+/// This structure is stored across time steps, so we keep it small.
+/// Note: the impulses are used for internal caching and may not
+/// provide reliable contact forces, especially for high speed collisions.
+struct b2ManifoldPoint
+{
+	b2Vec2 localPoint;		///< usage depends on manifold type
+	float32 normalImpulse;	///< the non-penetration impulse
+	float32 tangentImpulse;	///< the friction impulse
+	b2ContactID id;			///< uniquely identifies a contact point between two shapes
+};
+
+/// A manifold for two touching convex shapes.
+/// Box2D supports multiple types of contact:
+/// - clip point versus plane with radius
+/// - point versus point with radius (circles)
+/// The local point usage depends on the manifold type:
+/// -e_circles: the local center of circleA
+/// -e_faceA: the center of faceA
+/// -e_faceB: the center of faceB
+/// Similarly the local normal usage:
+/// -e_circles: not used
+/// -e_faceA: the normal on polygonA
+/// -e_faceB: the normal on polygonB
+/// We store contacts in this way so that position correction can
+/// account for movement, which is critical for continuous physics.
+/// All contact scenarios must be expressed in one of these types.
+/// This structure is stored across time steps, so we keep it small.
+struct b2Manifold
+{
+	enum Type
+	{
+		e_circles,
+		e_faceA,
+		e_faceB
+	};
+
+	b2ManifoldPoint points[b2_maxManifoldPoints];	///< the points of contact
+	b2Vec2 localNormal;								///< not use for Type::e_points
+	b2Vec2 localPoint;								///< usage depends on manifold type
+	Type type;
+	int32 pointCount;								///< the number of manifold points
+};
+
+/// This is used to compute the current state of a contact manifold.
+struct b2WorldManifold
+{
+	/// Evaluate the manifold with supplied transforms. This assumes
+	/// modest motion from the original state. This does not change the
+	/// point count, impulses, etc. The radii must come from the shapes
+	/// that generated the manifold.
+	void Initialize(const b2Manifold* manifold,
+					const b2Transform& xfA, float32 radiusA,
+					const b2Transform& xfB, float32 radiusB);
+
+	b2Vec2 normal;							///< world vector pointing from A to B
+	b2Vec2 points[b2_maxManifoldPoints];	///< world contact point (point of intersection)
+};
+
+/// This is used for determining the state of contact points.
+enum b2PointState
+{
+	b2_nullState,		///< point does not exist
+	b2_addState,		///< point was added in the update
+	b2_persistState,	///< point persisted across the update
+	b2_removeState		///< point was removed in the update
+};
+
+/// Compute the point states given two manifolds. The states pertain to the transition from manifold1
+/// to manifold2. So state1 is either persist or remove while state2 is either add or persist.
+void b2GetPointStates(b2PointState state1[b2_maxManifoldPoints], b2PointState state2[b2_maxManifoldPoints],
+					  const b2Manifold* manifold1, const b2Manifold* manifold2);
+
+/// Used for computing contact manifolds.
+struct b2ClipVertex
+{
+	b2Vec2 v;
+	b2ContactID id;
+};
+
+/// Ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1).
+struct b2RayCastInput
+{
+	b2Vec2 p1, p2;
+	float32 maxFraction;
+};
+
+/// Ray-cast output data. The ray hits at p1 + fraction * (p2 - p1), where p1 and p2
+/// come from b2RayCastInput.
+struct b2RayCastOutput
+{
+	b2Vec2 normal;
+	float32 fraction;
+};
+
+/// An axis aligned bounding box.
+struct b2AABB
+{
+	/// Verify that the bounds are sorted.
+	bool IsValid() const;
+
+	/// Get the center of the AABB.
+	b2Vec2 GetCenter() const
+	{
+		return 0.5f * (lowerBound + upperBound);
+	}
+
+	/// Get the extents of the AABB (half-widths).
+	b2Vec2 GetExtents() const
+	{
+		return 0.5f * (upperBound - lowerBound);
+	}
+
+	/// Get the perimeter length
+	float32 GetPerimeter() const
+	{
+		float32 wx = upperBound.x - lowerBound.x;
+		float32 wy = upperBound.y - lowerBound.y;
+		return 2.0f * (wx + wy);
+	}
+
+	/// Combine an AABB into this one.
+	void Combine(const b2AABB& aabb)
+	{
+		lowerBound = b2Min(lowerBound, aabb.lowerBound);
+		upperBound = b2Max(upperBound, aabb.upperBound);
+	}
+
+	/// Combine two AABBs into this one.
+	void Combine(const b2AABB& aabb1, const b2AABB& aabb2)
+	{
+		lowerBound = b2Min(aabb1.lowerBound, aabb2.lowerBound);
+		upperBound = b2Max(aabb1.upperBound, aabb2.upperBound);
+	}
+
+	/// Does this aabb contain the provided AABB.
+	bool Contains(const b2AABB& aabb) const
+	{
+		bool result = true;
+		result = result && lowerBound.x <= aabb.lowerBound.x;
+		result = result && lowerBound.y <= aabb.lowerBound.y;
+		result = result && aabb.upperBound.x <= upperBound.x;
+		result = result && aabb.upperBound.y <= upperBound.y;
+		return result;
+	}
+
+	bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input) const;
+
+	b2Vec2 lowerBound;	///< the lower vertex
+	b2Vec2 upperBound;	///< the upper vertex
+};
+
+/// Compute the collision manifold between two circles.
+void b2CollideCircles(b2Manifold* manifold,
+					  const b2CircleShape* circleA, const b2Transform& xfA,
+					  const b2CircleShape* circleB, const b2Transform& xfB);
+
+/// Compute the collision manifold between a polygon and a circle.
+void b2CollidePolygonAndCircle(b2Manifold* manifold,
+							   const b2PolygonShape* polygonA, const b2Transform& xfA,
+							   const b2CircleShape* circleB, const b2Transform& xfB);
+
+/// Compute the collision manifold between two polygons.
+void b2CollidePolygons(b2Manifold* manifold,
+					   const b2PolygonShape* polygonA, const b2Transform& xfA,
+					   const b2PolygonShape* polygonB, const b2Transform& xfB);
+
+/// Compute the collision manifold between an edge and a circle.
+void b2CollideEdgeAndCircle(b2Manifold* manifold,
+							   const b2EdgeShape* polygonA, const b2Transform& xfA,
+							   const b2CircleShape* circleB, const b2Transform& xfB);
+
+/// Compute the collision manifold between an edge and a circle.
+void b2CollideEdgeAndPolygon(b2Manifold* manifold,
+							   const b2EdgeShape* edgeA, const b2Transform& xfA,
+							   const b2PolygonShape* circleB, const b2Transform& xfB);
+
+/// Clipping for contact manifolds.
+int32 b2ClipSegmentToLine(b2ClipVertex vOut[2], const b2ClipVertex vIn[2],
+							const b2Vec2& normal, float32 offset, int32 vertexIndexA);
+
+/// Determine if two generic shapes overlap.
+bool b2TestOverlap(	const b2Shape* shapeA, int32 indexA,
+					const b2Shape* shapeB, int32 indexB,
+					const b2Transform& xfA, const b2Transform& xfB);
+
+// ---------------- Inline Functions ------------------------------------------
+
+inline bool b2AABB::IsValid() const
+{
+	b2Vec2 d = upperBound - lowerBound;
+	bool valid = d.x >= 0.0f && d.y >= 0.0f;
+	valid = valid && lowerBound.IsValid() && upperBound.IsValid();
+	return valid;
+}
+
+inline bool b2TestOverlap(const b2AABB& a, const b2AABB& b)
+{
+	b2Vec2 d1, d2;
+	d1 = b.lowerBound - a.upperBound;
+	d2 = a.lowerBound - b.upperBound;
+
+	if (d1.x > 0.0f || d1.y > 0.0f)
+		return false;
+
+	if (d2.x > 0.0f || d2.y > 0.0f)
+		return false;
+
+	return true;
+}
+
+#endif

+ 603 - 0
src/libraries/Box2D/Collision/b2Distance.cpp

@@ -0,0 +1,603 @@
+/*
+* Copyright (c) 2007-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Collision/b2Distance.h>
+#include <Box2D/Collision/Shapes/b2CircleShape.h>
+#include <Box2D/Collision/Shapes/b2EdgeShape.h>
+#include <Box2D/Collision/Shapes/b2ChainShape.h>
+#include <Box2D/Collision/Shapes/b2PolygonShape.h>
+
+// GJK using Voronoi regions (Christer Ericson) and Barycentric coordinates.
+int32 b2_gjkCalls, b2_gjkIters, b2_gjkMaxIters;
+
+void b2DistanceProxy::Set(const b2Shape* shape, int32 index)
+{
+	switch (shape->GetType())
+	{
+	case b2Shape::e_circle:
+		{
+			const b2CircleShape* circle = (b2CircleShape*)shape;
+			m_vertices = &circle->m_p;
+			m_count = 1;
+			m_radius = circle->m_radius;
+		}
+		break;
+
+	case b2Shape::e_polygon:
+		{
+			const b2PolygonShape* polygon = (b2PolygonShape*)shape;
+			m_vertices = polygon->m_vertices;
+			m_count = polygon->m_vertexCount;
+			m_radius = polygon->m_radius;
+		}
+		break;
+
+	case b2Shape::e_chain:
+		{
+			const b2ChainShape* chain = (b2ChainShape*)shape;
+			b2Assert(0 <= index && index < chain->m_count);
+
+			m_buffer[0] = chain->m_vertices[index];
+			if (index + 1 < chain->m_count)
+			{
+				m_buffer[1] = chain->m_vertices[index + 1];
+			}
+			else
+			{
+				m_buffer[1] = chain->m_vertices[0];
+			}
+
+			m_vertices = m_buffer;
+			m_count = 2;
+			m_radius = chain->m_radius;
+		}
+		break;
+
+	case b2Shape::e_edge:
+		{
+			const b2EdgeShape* edge = (b2EdgeShape*)shape;
+			m_vertices = &edge->m_vertex1;
+			m_count = 2;
+			m_radius = edge->m_radius;
+		}
+		break;
+
+	default:
+		b2Assert(false);
+	}
+}
+
+
+struct b2SimplexVertex
+{
+	b2Vec2 wA;		// support point in proxyA
+	b2Vec2 wB;		// support point in proxyB
+	b2Vec2 w;		// wB - wA
+	float32 a;		// barycentric coordinate for closest point
+	int32 indexA;	// wA index
+	int32 indexB;	// wB index
+};
+
+struct b2Simplex
+{
+	void ReadCache(	const b2SimplexCache* cache,
+					const b2DistanceProxy* proxyA, const b2Transform& transformA,
+					const b2DistanceProxy* proxyB, const b2Transform& transformB)
+	{
+		b2Assert(cache->count <= 3);
+		
+		// Copy data from cache.
+		m_count = cache->count;
+		b2SimplexVertex* vertices = &m_v1;
+		for (int32 i = 0; i < m_count; ++i)
+		{
+			b2SimplexVertex* v = vertices + i;
+			v->indexA = cache->indexA[i];
+			v->indexB = cache->indexB[i];
+			b2Vec2 wALocal = proxyA->GetVertex(v->indexA);
+			b2Vec2 wBLocal = proxyB->GetVertex(v->indexB);
+			v->wA = b2Mul(transformA, wALocal);
+			v->wB = b2Mul(transformB, wBLocal);
+			v->w = v->wB - v->wA;
+			v->a = 0.0f;
+		}
+
+		// Compute the new simplex metric, if it is substantially different than
+		// old metric then flush the simplex.
+		if (m_count > 1)
+		{
+			float32 metric1 = cache->metric;
+			float32 metric2 = GetMetric();
+			if (metric2 < 0.5f * metric1 || 2.0f * metric1 < metric2 || metric2 < b2_epsilon)
+			{
+				// Reset the simplex.
+				m_count = 0;
+			}
+		}
+
+		// If the cache is empty or invalid ...
+		if (m_count == 0)
+		{
+			b2SimplexVertex* v = vertices + 0;
+			v->indexA = 0;
+			v->indexB = 0;
+			b2Vec2 wALocal = proxyA->GetVertex(0);
+			b2Vec2 wBLocal = proxyB->GetVertex(0);
+			v->wA = b2Mul(transformA, wALocal);
+			v->wB = b2Mul(transformB, wBLocal);
+			v->w = v->wB - v->wA;
+			m_count = 1;
+		}
+	}
+
+	void WriteCache(b2SimplexCache* cache) const
+	{
+		cache->metric = GetMetric();
+		cache->count = uint16(m_count);
+		const b2SimplexVertex* vertices = &m_v1;
+		for (int32 i = 0; i < m_count; ++i)
+		{
+			cache->indexA[i] = uint8(vertices[i].indexA);
+			cache->indexB[i] = uint8(vertices[i].indexB);
+		}
+	}
+
+	b2Vec2 GetSearchDirection() const
+	{
+		switch (m_count)
+		{
+		case 1:
+			return -m_v1.w;
+
+		case 2:
+			{
+				b2Vec2 e12 = m_v2.w - m_v1.w;
+				float32 sgn = b2Cross(e12, -m_v1.w);
+				if (sgn > 0.0f)
+				{
+					// Origin is left of e12.
+					return b2Cross(1.0f, e12);
+				}
+				else
+				{
+					// Origin is right of e12.
+					return b2Cross(e12, 1.0f);
+				}
+			}
+
+		default:
+			b2Assert(false);
+			return b2Vec2_zero;
+		}
+	}
+
+	b2Vec2 GetClosestPoint() const
+	{
+		switch (m_count)
+		{
+		case 0:
+			b2Assert(false);
+			return b2Vec2_zero;
+
+		case 1:
+			return m_v1.w;
+
+		case 2:
+			return m_v1.a * m_v1.w + m_v2.a * m_v2.w;
+
+		case 3:
+			return b2Vec2_zero;
+
+		default:
+			b2Assert(false);
+			return b2Vec2_zero;
+		}
+	}
+
+	void GetWitnessPoints(b2Vec2* pA, b2Vec2* pB) const
+	{
+		switch (m_count)
+		{
+		case 0:
+			b2Assert(false);
+			break;
+
+		case 1:
+			*pA = m_v1.wA;
+			*pB = m_v1.wB;
+			break;
+
+		case 2:
+			*pA = m_v1.a * m_v1.wA + m_v2.a * m_v2.wA;
+			*pB = m_v1.a * m_v1.wB + m_v2.a * m_v2.wB;
+			break;
+
+		case 3:
+			*pA = m_v1.a * m_v1.wA + m_v2.a * m_v2.wA + m_v3.a * m_v3.wA;
+			*pB = *pA;
+			break;
+
+		default:
+			b2Assert(false);
+			break;
+		}
+	}
+
+	float32 GetMetric() const
+	{
+		switch (m_count)
+		{
+		case 0:
+			b2Assert(false);
+			return 0.0;
+
+		case 1:
+			return 0.0f;
+
+		case 2:
+			return b2Distance(m_v1.w, m_v2.w);
+
+		case 3:
+			return b2Cross(m_v2.w - m_v1.w, m_v3.w - m_v1.w);
+
+		default:
+			b2Assert(false);
+			return 0.0f;
+		}
+	}
+
+	void Solve2();
+	void Solve3();
+
+	b2SimplexVertex m_v1, m_v2, m_v3;
+	int32 m_count;
+};
+
+
+// Solve a line segment using barycentric coordinates.
+//
+// p = a1 * w1 + a2 * w2
+// a1 + a2 = 1
+//
+// The vector from the origin to the closest point on the line is
+// perpendicular to the line.
+// e12 = w2 - w1
+// dot(p, e) = 0
+// a1 * dot(w1, e) + a2 * dot(w2, e) = 0
+//
+// 2-by-2 linear system
+// [1      1     ][a1] = [1]
+// [w1.e12 w2.e12][a2] = [0]
+//
+// Define
+// d12_1 =  dot(w2, e12)
+// d12_2 = -dot(w1, e12)
+// d12 = d12_1 + d12_2
+//
+// Solution
+// a1 = d12_1 / d12
+// a2 = d12_2 / d12
+void b2Simplex::Solve2()
+{
+	b2Vec2 w1 = m_v1.w;
+	b2Vec2 w2 = m_v2.w;
+	b2Vec2 e12 = w2 - w1;
+
+	// w1 region
+	float32 d12_2 = -b2Dot(w1, e12);
+	if (d12_2 <= 0.0f)
+	{
+		// a2 <= 0, so we clamp it to 0
+		m_v1.a = 1.0f;
+		m_count = 1;
+		return;
+	}
+
+	// w2 region
+	float32 d12_1 = b2Dot(w2, e12);
+	if (d12_1 <= 0.0f)
+	{
+		// a1 <= 0, so we clamp it to 0
+		m_v2.a = 1.0f;
+		m_count = 1;
+		m_v1 = m_v2;
+		return;
+	}
+
+	// Must be in e12 region.
+	float32 inv_d12 = 1.0f / (d12_1 + d12_2);
+	m_v1.a = d12_1 * inv_d12;
+	m_v2.a = d12_2 * inv_d12;
+	m_count = 2;
+}
+
+// Possible regions:
+// - points[2]
+// - edge points[0]-points[2]
+// - edge points[1]-points[2]
+// - inside the triangle
+void b2Simplex::Solve3()
+{
+	b2Vec2 w1 = m_v1.w;
+	b2Vec2 w2 = m_v2.w;
+	b2Vec2 w3 = m_v3.w;
+
+	// Edge12
+	// [1      1     ][a1] = [1]
+	// [w1.e12 w2.e12][a2] = [0]
+	// a3 = 0
+	b2Vec2 e12 = w2 - w1;
+	float32 w1e12 = b2Dot(w1, e12);
+	float32 w2e12 = b2Dot(w2, e12);
+	float32 d12_1 = w2e12;
+	float32 d12_2 = -w1e12;
+
+	// Edge13
+	// [1      1     ][a1] = [1]
+	// [w1.e13 w3.e13][a3] = [0]
+	// a2 = 0
+	b2Vec2 e13 = w3 - w1;
+	float32 w1e13 = b2Dot(w1, e13);
+	float32 w3e13 = b2Dot(w3, e13);
+	float32 d13_1 = w3e13;
+	float32 d13_2 = -w1e13;
+
+	// Edge23
+	// [1      1     ][a2] = [1]
+	// [w2.e23 w3.e23][a3] = [0]
+	// a1 = 0
+	b2Vec2 e23 = w3 - w2;
+	float32 w2e23 = b2Dot(w2, e23);
+	float32 w3e23 = b2Dot(w3, e23);
+	float32 d23_1 = w3e23;
+	float32 d23_2 = -w2e23;
+	
+	// Triangle123
+	float32 n123 = b2Cross(e12, e13);
+
+	float32 d123_1 = n123 * b2Cross(w2, w3);
+	float32 d123_2 = n123 * b2Cross(w3, w1);
+	float32 d123_3 = n123 * b2Cross(w1, w2);
+
+	// w1 region
+	if (d12_2 <= 0.0f && d13_2 <= 0.0f)
+	{
+		m_v1.a = 1.0f;
+		m_count = 1;
+		return;
+	}
+
+	// e12
+	if (d12_1 > 0.0f && d12_2 > 0.0f && d123_3 <= 0.0f)
+	{
+		float32 inv_d12 = 1.0f / (d12_1 + d12_2);
+		m_v1.a = d12_1 * inv_d12;
+		m_v2.a = d12_2 * inv_d12;
+		m_count = 2;
+		return;
+	}
+
+	// e13
+	if (d13_1 > 0.0f && d13_2 > 0.0f && d123_2 <= 0.0f)
+	{
+		float32 inv_d13 = 1.0f / (d13_1 + d13_2);
+		m_v1.a = d13_1 * inv_d13;
+		m_v3.a = d13_2 * inv_d13;
+		m_count = 2;
+		m_v2 = m_v3;
+		return;
+	}
+
+	// w2 region
+	if (d12_1 <= 0.0f && d23_2 <= 0.0f)
+	{
+		m_v2.a = 1.0f;
+		m_count = 1;
+		m_v1 = m_v2;
+		return;
+	}
+
+	// w3 region
+	if (d13_1 <= 0.0f && d23_1 <= 0.0f)
+	{
+		m_v3.a = 1.0f;
+		m_count = 1;
+		m_v1 = m_v3;
+		return;
+	}
+
+	// e23
+	if (d23_1 > 0.0f && d23_2 > 0.0f && d123_1 <= 0.0f)
+	{
+		float32 inv_d23 = 1.0f / (d23_1 + d23_2);
+		m_v2.a = d23_1 * inv_d23;
+		m_v3.a = d23_2 * inv_d23;
+		m_count = 2;
+		m_v1 = m_v3;
+		return;
+	}
+
+	// Must be in triangle123
+	float32 inv_d123 = 1.0f / (d123_1 + d123_2 + d123_3);
+	m_v1.a = d123_1 * inv_d123;
+	m_v2.a = d123_2 * inv_d123;
+	m_v3.a = d123_3 * inv_d123;
+	m_count = 3;
+}
+
+void b2Distance(b2DistanceOutput* output,
+				b2SimplexCache* cache,
+				const b2DistanceInput* input)
+{
+	++b2_gjkCalls;
+
+	const b2DistanceProxy* proxyA = &input->proxyA;
+	const b2DistanceProxy* proxyB = &input->proxyB;
+
+	b2Transform transformA = input->transformA;
+	b2Transform transformB = input->transformB;
+
+	// Initialize the simplex.
+	b2Simplex simplex;
+	simplex.ReadCache(cache, proxyA, transformA, proxyB, transformB);
+
+	// Get simplex vertices as an array.
+	b2SimplexVertex* vertices = &simplex.m_v1;
+	const int32 k_maxIters = 20;
+
+	// These store the vertices of the last simplex so that we
+	// can check for duplicates and prevent cycling.
+	int32 saveA[3], saveB[3];
+	int32 saveCount = 0;
+
+	b2Vec2 closestPoint = simplex.GetClosestPoint();
+	float32 distanceSqr1 = closestPoint.LengthSquared();
+	float32 distanceSqr2 = distanceSqr1;
+
+	// Main iteration loop.
+	int32 iter = 0;
+	while (iter < k_maxIters)
+	{
+		// Copy simplex so we can identify duplicates.
+		saveCount = simplex.m_count;
+		for (int32 i = 0; i < saveCount; ++i)
+		{
+			saveA[i] = vertices[i].indexA;
+			saveB[i] = vertices[i].indexB;
+		}
+
+		switch (simplex.m_count)
+		{
+		case 1:
+			break;
+
+		case 2:
+			simplex.Solve2();
+			break;
+
+		case 3:
+			simplex.Solve3();
+			break;
+
+		default:
+			b2Assert(false);
+		}
+
+		// If we have 3 points, then the origin is in the corresponding triangle.
+		if (simplex.m_count == 3)
+		{
+			break;
+		}
+
+		// Compute closest point.
+		b2Vec2 p = simplex.GetClosestPoint();
+		distanceSqr2 = p.LengthSquared();
+
+		// Ensure progress
+		if (distanceSqr2 >= distanceSqr1)
+		{
+			//break;
+		}
+		distanceSqr1 = distanceSqr2;
+
+		// Get search direction.
+		b2Vec2 d = simplex.GetSearchDirection();
+
+		// Ensure the search direction is numerically fit.
+		if (d.LengthSquared() < b2_epsilon * b2_epsilon)
+		{
+			// The origin is probably contained by a line segment
+			// or triangle. Thus the shapes are overlapped.
+
+			// We can't return zero here even though there may be overlap.
+			// In case the simplex is a point, segment, or triangle it is difficult
+			// to determine if the origin is contained in the CSO or very close to it.
+			break;
+		}
+
+		// Compute a tentative new simplex vertex using support points.
+		b2SimplexVertex* vertex = vertices + simplex.m_count;
+		vertex->indexA = proxyA->GetSupport(b2MulT(transformA.q, -d));
+		vertex->wA = b2Mul(transformA, proxyA->GetVertex(vertex->indexA));
+		b2Vec2 wBLocal;
+		vertex->indexB = proxyB->GetSupport(b2MulT(transformB.q, d));
+		vertex->wB = b2Mul(transformB, proxyB->GetVertex(vertex->indexB));
+		vertex->w = vertex->wB - vertex->wA;
+
+		// Iteration count is equated to the number of support point calls.
+		++iter;
+		++b2_gjkIters;
+
+		// Check for duplicate support points. This is the main termination criteria.
+		bool duplicate = false;
+		for (int32 i = 0; i < saveCount; ++i)
+		{
+			if (vertex->indexA == saveA[i] && vertex->indexB == saveB[i])
+			{
+				duplicate = true;
+				break;
+			}
+		}
+
+		// If we found a duplicate support point we must exit to avoid cycling.
+		if (duplicate)
+		{
+			break;
+		}
+
+		// New vertex is ok and needed.
+		++simplex.m_count;
+	}
+
+	b2_gjkMaxIters = b2Max(b2_gjkMaxIters, iter);
+
+	// Prepare output.
+	simplex.GetWitnessPoints(&output->pointA, &output->pointB);
+	output->distance = b2Distance(output->pointA, output->pointB);
+	output->iterations = iter;
+
+	// Cache the simplex.
+	simplex.WriteCache(cache);
+
+	// Apply radii if requested.
+	if (input->useRadii)
+	{
+		float32 rA = proxyA->m_radius;
+		float32 rB = proxyB->m_radius;
+
+		if (output->distance > rA + rB && output->distance > b2_epsilon)
+		{
+			// Shapes are still no overlapped.
+			// Move the witness points to the outer surface.
+			output->distance -= rA + rB;
+			b2Vec2 normal = output->pointB - output->pointA;
+			normal.Normalize();
+			output->pointA += rA * normal;
+			output->pointB -= rB * normal;
+		}
+		else
+		{
+			// Shapes are overlapped when radii are considered.
+			// Move the witness points to the middle.
+			b2Vec2 p = 0.5f * (output->pointA + output->pointB);
+			output->pointA = p;
+			output->pointB = p;
+			output->distance = 0.0f;
+		}
+	}
+}

+ 141 - 0
src/libraries/Box2D/Collision/b2Distance.h

@@ -0,0 +1,141 @@
+
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef B2_DISTANCE_H
+#define B2_DISTANCE_H
+
+#include <Box2D/Common/b2Math.h>
+
+class b2Shape;
+
+/// A distance proxy is used by the GJK algorithm.
+/// It encapsulates any shape.
+struct b2DistanceProxy
+{
+	b2DistanceProxy() : m_vertices(NULL), m_count(0), m_radius(0.0f) {}
+
+	/// Initialize the proxy using the given shape. The shape
+	/// must remain in scope while the proxy is in use.
+	void Set(const b2Shape* shape, int32 index);
+
+	/// Get the supporting vertex index in the given direction.
+	int32 GetSupport(const b2Vec2& d) const;
+
+	/// Get the supporting vertex in the given direction.
+	const b2Vec2& GetSupportVertex(const b2Vec2& d) const;
+
+	/// Get the vertex count.
+	int32 GetVertexCount() const;
+
+	/// Get a vertex by index. Used by b2Distance.
+	const b2Vec2& GetVertex(int32 index) const;
+
+	b2Vec2 m_buffer[2];
+	const b2Vec2* m_vertices;
+	int32 m_count;
+	float32 m_radius;
+};
+
+/// Used to warm start b2Distance.
+/// Set count to zero on first call.
+struct b2SimplexCache
+{
+	float32 metric;		///< length or area
+	uint16 count;
+	uint8 indexA[3];	///< vertices on shape A
+	uint8 indexB[3];	///< vertices on shape B
+};
+
+/// Input for b2Distance.
+/// You have to option to use the shape radii
+/// in the computation. Even 
+struct b2DistanceInput
+{
+	b2DistanceProxy proxyA;
+	b2DistanceProxy proxyB;
+	b2Transform transformA;
+	b2Transform transformB;
+	bool useRadii;
+};
+
+/// Output for b2Distance.
+struct b2DistanceOutput
+{
+	b2Vec2 pointA;		///< closest point on shapeA
+	b2Vec2 pointB;		///< closest point on shapeB
+	float32 distance;
+	int32 iterations;	///< number of GJK iterations used
+};
+
+/// Compute the closest points between two shapes. Supports any combination of:
+/// b2CircleShape, b2PolygonShape, b2EdgeShape. The simplex cache is input/output.
+/// On the first call set b2SimplexCache.count to zero.
+void b2Distance(b2DistanceOutput* output,
+				b2SimplexCache* cache, 
+				const b2DistanceInput* input);
+
+
+//////////////////////////////////////////////////////////////////////////
+
+inline int32 b2DistanceProxy::GetVertexCount() const
+{
+	return m_count;
+}
+
+inline const b2Vec2& b2DistanceProxy::GetVertex(int32 index) const
+{
+	b2Assert(0 <= index && index < m_count);
+	return m_vertices[index];
+}
+
+inline int32 b2DistanceProxy::GetSupport(const b2Vec2& d) const
+{
+	int32 bestIndex = 0;
+	float32 bestValue = b2Dot(m_vertices[0], d);
+	for (int32 i = 1; i < m_count; ++i)
+	{
+		float32 value = b2Dot(m_vertices[i], d);
+		if (value > bestValue)
+		{
+			bestIndex = i;
+			bestValue = value;
+		}
+	}
+
+	return bestIndex;
+}
+
+inline const b2Vec2& b2DistanceProxy::GetSupportVertex(const b2Vec2& d) const
+{
+	int32 bestIndex = 0;
+	float32 bestValue = b2Dot(m_vertices[0], d);
+	for (int32 i = 1; i < m_count; ++i)
+	{
+		float32 value = b2Dot(m_vertices[i], d);
+		if (value > bestValue)
+		{
+			bestIndex = i;
+			bestValue = value;
+		}
+	}
+
+	return m_vertices[bestIndex];
+}
+
+#endif

+ 771 - 0
src/libraries/Box2D/Collision/b2DynamicTree.cpp

@@ -0,0 +1,771 @@
+/*
+* Copyright (c) 2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Collision/b2DynamicTree.h>
+#include <cstring>
+#include <cfloat>
+using namespace std;
+
+
+b2DynamicTree::b2DynamicTree()
+{
+	m_root = b2_nullNode;
+
+	m_nodeCapacity = 16;
+	m_nodeCount = 0;
+	m_nodes = (b2TreeNode*)b2Alloc(m_nodeCapacity * sizeof(b2TreeNode));
+	memset(m_nodes, 0, m_nodeCapacity * sizeof(b2TreeNode));
+
+	// Build a linked list for the free list.
+	for (int32 i = 0; i < m_nodeCapacity - 1; ++i)
+	{
+		m_nodes[i].next = i + 1;
+		m_nodes[i].height = -1;
+	}
+	m_nodes[m_nodeCapacity-1].next = b2_nullNode;
+	m_nodes[m_nodeCapacity-1].height = -1;
+	m_freeList = 0;
+
+	m_path = 0;
+
+	m_insertionCount = 0;
+}
+
+b2DynamicTree::~b2DynamicTree()
+{
+	// This frees the entire tree in one shot.
+	b2Free(m_nodes);
+}
+
+// Allocate a node from the pool. Grow the pool if necessary.
+int32 b2DynamicTree::AllocateNode()
+{
+	// Expand the node pool as needed.
+	if (m_freeList == b2_nullNode)
+	{
+		b2Assert(m_nodeCount == m_nodeCapacity);
+
+		// The free list is empty. Rebuild a bigger pool.
+		b2TreeNode* oldNodes = m_nodes;
+		m_nodeCapacity *= 2;
+		m_nodes = (b2TreeNode*)b2Alloc(m_nodeCapacity * sizeof(b2TreeNode));
+		memcpy(m_nodes, oldNodes, m_nodeCount * sizeof(b2TreeNode));
+		b2Free(oldNodes);
+
+		// Build a linked list for the free list. The parent
+		// pointer becomes the "next" pointer.
+		for (int32 i = m_nodeCount; i < m_nodeCapacity - 1; ++i)
+		{
+			m_nodes[i].next = i + 1;
+			m_nodes[i].height = -1;
+		}
+		m_nodes[m_nodeCapacity-1].next = b2_nullNode;
+		m_nodes[m_nodeCapacity-1].height = -1;
+		m_freeList = m_nodeCount;
+	}
+
+	// Peel a node off the free list.
+	int32 nodeId = m_freeList;
+	m_freeList = m_nodes[nodeId].next;
+	m_nodes[nodeId].parent = b2_nullNode;
+	m_nodes[nodeId].child1 = b2_nullNode;
+	m_nodes[nodeId].child2 = b2_nullNode;
+	m_nodes[nodeId].height = 0;
+	m_nodes[nodeId].userData = NULL;
+	++m_nodeCount;
+	return nodeId;
+}
+
+// Return a node to the pool.
+void b2DynamicTree::FreeNode(int32 nodeId)
+{
+	b2Assert(0 <= nodeId && nodeId < m_nodeCapacity);
+	b2Assert(0 < m_nodeCount);
+	m_nodes[nodeId].next = m_freeList;
+	m_nodes[nodeId].height = -1;
+	m_freeList = nodeId;
+	--m_nodeCount;
+}
+
+// Create a proxy in the tree as a leaf node. We return the index
+// of the node instead of a pointer so that we can grow
+// the node pool.
+int32 b2DynamicTree::CreateProxy(const b2AABB& aabb, void* userData)
+{
+	int32 proxyId = AllocateNode();
+
+	// Fatten the aabb.
+	b2Vec2 r(b2_aabbExtension, b2_aabbExtension);
+	m_nodes[proxyId].aabb.lowerBound = aabb.lowerBound - r;
+	m_nodes[proxyId].aabb.upperBound = aabb.upperBound + r;
+	m_nodes[proxyId].userData = userData;
+	m_nodes[proxyId].height = 0;
+
+	InsertLeaf(proxyId);
+
+	return proxyId;
+}
+
+void b2DynamicTree::DestroyProxy(int32 proxyId)
+{
+	b2Assert(0 <= proxyId && proxyId < m_nodeCapacity);
+	b2Assert(m_nodes[proxyId].IsLeaf());
+
+	RemoveLeaf(proxyId);
+	FreeNode(proxyId);
+}
+
+bool b2DynamicTree::MoveProxy(int32 proxyId, const b2AABB& aabb, const b2Vec2& displacement)
+{
+	b2Assert(0 <= proxyId && proxyId < m_nodeCapacity);
+
+	b2Assert(m_nodes[proxyId].IsLeaf());
+
+	if (m_nodes[proxyId].aabb.Contains(aabb))
+	{
+		return false;
+	}
+
+	RemoveLeaf(proxyId);
+
+	// Extend AABB.
+	b2AABB b = aabb;
+	b2Vec2 r(b2_aabbExtension, b2_aabbExtension);
+	b.lowerBound = b.lowerBound - r;
+	b.upperBound = b.upperBound + r;
+
+	// Predict AABB displacement.
+	b2Vec2 d = b2_aabbMultiplier * displacement;
+
+	if (d.x < 0.0f)
+	{
+		b.lowerBound.x += d.x;
+	}
+	else
+	{
+		b.upperBound.x += d.x;
+	}
+
+	if (d.y < 0.0f)
+	{
+		b.lowerBound.y += d.y;
+	}
+	else
+	{
+		b.upperBound.y += d.y;
+	}
+
+	m_nodes[proxyId].aabb = b;
+
+	InsertLeaf(proxyId);
+	return true;
+}
+
+void b2DynamicTree::InsertLeaf(int32 leaf)
+{
+	++m_insertionCount;
+
+	if (m_root == b2_nullNode)
+	{
+		m_root = leaf;
+		m_nodes[m_root].parent = b2_nullNode;
+		return;
+	}
+
+	// Find the best sibling for this node
+	b2AABB leafAABB = m_nodes[leaf].aabb;
+	int32 index = m_root;
+	while (m_nodes[index].IsLeaf() == false)
+	{
+		int32 child1 = m_nodes[index].child1;
+		int32 child2 = m_nodes[index].child2;
+
+		float32 area = m_nodes[index].aabb.GetPerimeter();
+
+		b2AABB combinedAABB;
+		combinedAABB.Combine(m_nodes[index].aabb, leafAABB);
+		float32 combinedArea = combinedAABB.GetPerimeter();
+
+		// Cost of creating a new parent for this node and the new leaf
+		float32 cost = 2.0f * combinedArea;
+
+		// Minimum cost of pushing the leaf further down the tree
+		float32 inheritanceCost = 2.0f * (combinedArea - area);
+
+		// Cost of descending into child1
+		float32 cost1;
+		if (m_nodes[child1].IsLeaf())
+		{
+			b2AABB aabb;
+			aabb.Combine(leafAABB, m_nodes[child1].aabb);
+			cost1 = aabb.GetPerimeter() + inheritanceCost;
+		}
+		else
+		{
+			b2AABB aabb;
+			aabb.Combine(leafAABB, m_nodes[child1].aabb);
+			float32 oldArea = m_nodes[child1].aabb.GetPerimeter();
+			float32 newArea = aabb.GetPerimeter();
+			cost1 = (newArea - oldArea) + inheritanceCost;
+		}
+
+		// Cost of descending into child2
+		float32 cost2;
+		if (m_nodes[child2].IsLeaf())
+		{
+			b2AABB aabb;
+			aabb.Combine(leafAABB, m_nodes[child2].aabb);
+			cost2 = aabb.GetPerimeter() + inheritanceCost;
+		}
+		else
+		{
+			b2AABB aabb;
+			aabb.Combine(leafAABB, m_nodes[child2].aabb);
+			float32 oldArea = m_nodes[child2].aabb.GetPerimeter();
+			float32 newArea = aabb.GetPerimeter();
+			cost2 = newArea - oldArea + inheritanceCost;
+		}
+
+		// Descend according to the minimum cost.
+		if (cost < cost1 && cost < cost2)
+		{
+			break;
+		}
+
+		// Descend
+		if (cost1 < cost2)
+		{
+			index = child1;
+		}
+		else
+		{
+			index = child2;
+		}
+	}
+
+	int32 sibling = index;
+
+	// Create a new parent.
+	int32 oldParent = m_nodes[sibling].parent;
+	int32 newParent = AllocateNode();
+	m_nodes[newParent].parent = oldParent;
+	m_nodes[newParent].userData = NULL;
+	m_nodes[newParent].aabb.Combine(leafAABB, m_nodes[sibling].aabb);
+	m_nodes[newParent].height = m_nodes[sibling].height + 1;
+
+	if (oldParent != b2_nullNode)
+	{
+		// The sibling was not the root.
+		if (m_nodes[oldParent].child1 == sibling)
+		{
+			m_nodes[oldParent].child1 = newParent;
+		}
+		else
+		{
+			m_nodes[oldParent].child2 = newParent;
+		}
+
+		m_nodes[newParent].child1 = sibling;
+		m_nodes[newParent].child2 = leaf;
+		m_nodes[sibling].parent = newParent;
+		m_nodes[leaf].parent = newParent;
+	}
+	else
+	{
+		// The sibling was the root.
+		m_nodes[newParent].child1 = sibling;
+		m_nodes[newParent].child2 = leaf;
+		m_nodes[sibling].parent = newParent;
+		m_nodes[leaf].parent = newParent;
+		m_root = newParent;
+	}
+
+	// Walk back up the tree fixing heights and AABBs
+	index = m_nodes[leaf].parent;
+	while (index != b2_nullNode)
+	{
+		index = Balance(index);
+
+		int32 child1 = m_nodes[index].child1;
+		int32 child2 = m_nodes[index].child2;
+
+		b2Assert(child1 != b2_nullNode);
+		b2Assert(child2 != b2_nullNode);
+
+		m_nodes[index].height = 1 + b2Max(m_nodes[child1].height, m_nodes[child2].height);
+		m_nodes[index].aabb.Combine(m_nodes[child1].aabb, m_nodes[child2].aabb);
+
+		index = m_nodes[index].parent;
+	}
+
+	//Validate();
+}
+
+void b2DynamicTree::RemoveLeaf(int32 leaf)
+{
+	if (leaf == m_root)
+	{
+		m_root = b2_nullNode;
+		return;
+	}
+
+	int32 parent = m_nodes[leaf].parent;
+	int32 grandParent = m_nodes[parent].parent;
+	int32 sibling;
+	if (m_nodes[parent].child1 == leaf)
+	{
+		sibling = m_nodes[parent].child2;
+	}
+	else
+	{
+		sibling = m_nodes[parent].child1;
+	}
+
+	if (grandParent != b2_nullNode)
+	{
+		// Destroy parent and connect sibling to grandParent.
+		if (m_nodes[grandParent].child1 == parent)
+		{
+			m_nodes[grandParent].child1 = sibling;
+		}
+		else
+		{
+			m_nodes[grandParent].child2 = sibling;
+		}
+		m_nodes[sibling].parent = grandParent;
+		FreeNode(parent);
+
+		// Adjust ancestor bounds.
+		int32 index = grandParent;
+		while (index != b2_nullNode)
+		{
+			index = Balance(index);
+
+			int32 child1 = m_nodes[index].child1;
+			int32 child2 = m_nodes[index].child2;
+
+			m_nodes[index].aabb.Combine(m_nodes[child1].aabb, m_nodes[child2].aabb);
+			m_nodes[index].height = 1 + b2Max(m_nodes[child1].height, m_nodes[child2].height);
+
+			index = m_nodes[index].parent;
+		}
+	}
+	else
+	{
+		m_root = sibling;
+		m_nodes[sibling].parent = b2_nullNode;
+		FreeNode(parent);
+	}
+
+	//Validate();
+}
+
+// Perform a left or right rotation if node A is imbalanced.
+// Returns the new root index.
+int32 b2DynamicTree::Balance(int32 iA)
+{
+	b2Assert(iA != b2_nullNode);
+
+	b2TreeNode* A = m_nodes + iA;
+	if (A->IsLeaf() || A->height < 2)
+	{
+		return iA;
+	}
+
+	int32 iB = A->child1;
+	int32 iC = A->child2;
+	b2Assert(0 <= iB && iB < m_nodeCapacity);
+	b2Assert(0 <= iC && iC < m_nodeCapacity);
+
+	b2TreeNode* B = m_nodes + iB;
+	b2TreeNode* C = m_nodes + iC;
+
+	int32 balance = C->height - B->height;
+
+	// Rotate C up
+	if (balance > 1)
+	{
+		int32 iF = C->child1;
+		int32 iG = C->child2;
+		b2TreeNode* F = m_nodes + iF;
+		b2TreeNode* G = m_nodes + iG;
+		b2Assert(0 <= iF && iF < m_nodeCapacity);
+		b2Assert(0 <= iG && iG < m_nodeCapacity);
+
+		// Swap A and C
+		C->child1 = iA;
+		C->parent = A->parent;
+		A->parent = iC;
+
+		// A's old parent should point to C
+		if (C->parent != b2_nullNode)
+		{
+			if (m_nodes[C->parent].child1 == iA)
+			{
+				m_nodes[C->parent].child1 = iC;
+			}
+			else
+			{
+				b2Assert(m_nodes[C->parent].child2 == iA);
+				m_nodes[C->parent].child2 = iC;
+			}
+		}
+		else
+		{
+			m_root = iC;
+		}
+
+		// Rotate
+		if (F->height > G->height)
+		{
+			C->child2 = iF;
+			A->child2 = iG;
+			G->parent = iA;
+			A->aabb.Combine(B->aabb, G->aabb);
+			C->aabb.Combine(A->aabb, F->aabb);
+
+			A->height = 1 + b2Max(B->height, G->height);
+			C->height = 1 + b2Max(A->height, F->height);
+		}
+		else
+		{
+			C->child2 = iG;
+			A->child2 = iF;
+			F->parent = iA;
+			A->aabb.Combine(B->aabb, F->aabb);
+			C->aabb.Combine(A->aabb, G->aabb);
+
+			A->height = 1 + b2Max(B->height, F->height);
+			C->height = 1 + b2Max(A->height, G->height);
+		}
+
+		return iC;
+	}
+	
+	// Rotate B up
+	if (balance < -1)
+	{
+		int32 iD = B->child1;
+		int32 iE = B->child2;
+		b2TreeNode* D = m_nodes + iD;
+		b2TreeNode* E = m_nodes + iE;
+		b2Assert(0 <= iD && iD < m_nodeCapacity);
+		b2Assert(0 <= iE && iE < m_nodeCapacity);
+
+		// Swap A and B
+		B->child1 = iA;
+		B->parent = A->parent;
+		A->parent = iB;
+
+		// A's old parent should point to B
+		if (B->parent != b2_nullNode)
+		{
+			if (m_nodes[B->parent].child1 == iA)
+			{
+				m_nodes[B->parent].child1 = iB;
+			}
+			else
+			{
+				b2Assert(m_nodes[B->parent].child2 == iA);
+				m_nodes[B->parent].child2 = iB;
+			}
+		}
+		else
+		{
+			m_root = iB;
+		}
+
+		// Rotate
+		if (D->height > E->height)
+		{
+			B->child2 = iD;
+			A->child1 = iE;
+			E->parent = iA;
+			A->aabb.Combine(C->aabb, E->aabb);
+			B->aabb.Combine(A->aabb, D->aabb);
+
+			A->height = 1 + b2Max(C->height, E->height);
+			B->height = 1 + b2Max(A->height, D->height);
+		}
+		else
+		{
+			B->child2 = iE;
+			A->child1 = iD;
+			D->parent = iA;
+			A->aabb.Combine(C->aabb, D->aabb);
+			B->aabb.Combine(A->aabb, E->aabb);
+
+			A->height = 1 + b2Max(C->height, D->height);
+			B->height = 1 + b2Max(A->height, E->height);
+		}
+
+		return iB;
+	}
+
+	return iA;
+}
+
+int32 b2DynamicTree::GetHeight() const
+{
+	if (m_root == b2_nullNode)
+	{
+		return 0;
+	}
+
+	return m_nodes[m_root].height;
+}
+
+//
+float32 b2DynamicTree::GetAreaRatio() const
+{
+	if (m_root == b2_nullNode)
+	{
+		return 0.0f;
+	}
+
+	const b2TreeNode* root = m_nodes + m_root;
+	float32 rootArea = root->aabb.GetPerimeter();
+
+	float32 totalArea = 0.0f;
+	for (int32 i = 0; i < m_nodeCapacity; ++i)
+	{
+		const b2TreeNode* node = m_nodes + i;
+		if (node->height < 0)
+		{
+			// Free node in pool
+			continue;
+		}
+
+		totalArea += node->aabb.GetPerimeter();
+	}
+
+	return totalArea / rootArea;
+}
+
+// Compute the height of a sub-tree.
+int32 b2DynamicTree::ComputeHeight(int32 nodeId) const
+{
+	b2Assert(0 <= nodeId && nodeId < m_nodeCapacity);
+	b2TreeNode* node = m_nodes + nodeId;
+
+	if (node->IsLeaf())
+	{
+		return 0;
+	}
+
+	int32 height1 = ComputeHeight(node->child1);
+	int32 height2 = ComputeHeight(node->child2);
+	return 1 + b2Max(height1, height2);
+}
+
+int32 b2DynamicTree::ComputeHeight() const
+{
+	int32 height = ComputeHeight(m_root);
+	return height;
+}
+
+void b2DynamicTree::ValidateStructure(int32 index) const
+{
+	if (index == b2_nullNode)
+	{
+		return;
+	}
+
+	if (index == m_root)
+	{
+		b2Assert(m_nodes[index].parent == b2_nullNode);
+	}
+
+	const b2TreeNode* node = m_nodes + index;
+
+	int32 child1 = node->child1;
+	int32 child2 = node->child2;
+
+	if (node->IsLeaf())
+	{
+		b2Assert(child1 == b2_nullNode);
+		b2Assert(child2 == b2_nullNode);
+		b2Assert(node->height == 0);
+		return;
+	}
+
+	b2Assert(0 <= child1 && child1 < m_nodeCapacity);
+	b2Assert(0 <= child2 && child2 < m_nodeCapacity);
+
+	b2Assert(m_nodes[child1].parent == index);
+	b2Assert(m_nodes[child2].parent == index);
+
+	ValidateStructure(child1);
+	ValidateStructure(child2);
+}
+
+void b2DynamicTree::ValidateMetrics(int32 index) const
+{
+	if (index == b2_nullNode)
+	{
+		return;
+	}
+
+	const b2TreeNode* node = m_nodes + index;
+
+	int32 child1 = node->child1;
+	int32 child2 = node->child2;
+
+	if (node->IsLeaf())
+	{
+		b2Assert(child1 == b2_nullNode);
+		b2Assert(child2 == b2_nullNode);
+		b2Assert(node->height == 0);
+		return;
+	}
+
+	b2Assert(0 <= child1 && child1 < m_nodeCapacity);
+	b2Assert(0 <= child2 && child2 < m_nodeCapacity);
+
+	int32 height1 = m_nodes[child1].height;
+	int32 height2 = m_nodes[child2].height;
+	int32 height;
+	height = 1 + b2Max(height1, height2);
+	b2Assert(node->height == height);
+
+	b2AABB aabb;
+	aabb.Combine(m_nodes[child1].aabb, m_nodes[child2].aabb);
+
+	b2Assert(aabb.lowerBound == node->aabb.lowerBound);
+	b2Assert(aabb.upperBound == node->aabb.upperBound);
+
+	ValidateMetrics(child1);
+	ValidateMetrics(child2);
+}
+
+void b2DynamicTree::Validate() const
+{
+	ValidateStructure(m_root);
+	ValidateMetrics(m_root);
+
+	int32 freeCount = 0;
+	int32 freeIndex = m_freeList;
+	while (freeIndex != b2_nullNode)
+	{
+		b2Assert(0 <= freeIndex && freeIndex < m_nodeCapacity);
+		freeIndex = m_nodes[freeIndex].next;
+		++freeCount;
+	}
+
+	b2Assert(GetHeight() == ComputeHeight());
+
+	b2Assert(m_nodeCount + freeCount == m_nodeCapacity);
+}
+
+int32 b2DynamicTree::GetMaxBalance() const
+{
+	int32 maxBalance = 0;
+	for (int32 i = 0; i < m_nodeCapacity; ++i)
+	{
+		const b2TreeNode* node = m_nodes + i;
+		if (node->height <= 1)
+		{
+			continue;
+		}
+
+		b2Assert(node->IsLeaf() == false);
+
+		int32 child1 = node->child1;
+		int32 child2 = node->child2;
+		int32 balance = b2Abs(m_nodes[child2].height - m_nodes[child1].height);
+		maxBalance = b2Max(maxBalance, balance);
+	}
+
+	return maxBalance;
+}
+
+void b2DynamicTree::RebuildBottomUp()
+{
+	int32* nodes = (int32*)b2Alloc(m_nodeCount * sizeof(int32));
+	int32 count = 0;
+
+	// Build array of leaves. Free the rest.
+	for (int32 i = 0; i < m_nodeCapacity; ++i)
+	{
+		if (m_nodes[i].height < 0)
+		{
+			// free node in pool
+			continue;
+		}
+
+		if (m_nodes[i].IsLeaf())
+		{
+			m_nodes[i].parent = b2_nullNode;
+			nodes[count] = i;
+			++count;
+		}
+		else
+		{
+			FreeNode(i);
+		}
+	}
+
+	while (count > 1)
+	{
+		float32 minCost = b2_maxFloat;
+		int32 iMin = -1, jMin = -1;
+		for (int32 i = 0; i < count; ++i)
+		{
+			b2AABB aabbi = m_nodes[nodes[i]].aabb;
+
+			for (int32 j = i + 1; j < count; ++j)
+			{
+				b2AABB aabbj = m_nodes[nodes[j]].aabb;
+				b2AABB b;
+				b.Combine(aabbi, aabbj);
+				float32 cost = b.GetPerimeter();
+				if (cost < minCost)
+				{
+					iMin = i;
+					jMin = j;
+					minCost = cost;
+				}
+			}
+		}
+
+		int32 index1 = nodes[iMin];
+		int32 index2 = nodes[jMin];
+		b2TreeNode* child1 = m_nodes + index1;
+		b2TreeNode* child2 = m_nodes + index2;
+
+		int32 parentIndex = AllocateNode();
+		b2TreeNode* parent = m_nodes + parentIndex;
+		parent->child1 = index1;
+		parent->child2 = index2;
+		parent->height = 1 + b2Max(child1->height, child2->height);
+		parent->aabb.Combine(child1->aabb, child2->aabb);
+		parent->parent = b2_nullNode;
+
+		child1->parent = parentIndex;
+		child2->parent = parentIndex;
+
+		nodes[jMin] = nodes[count-1];
+		nodes[iMin] = parentIndex;
+		--count;
+	}
+
+	m_root = nodes[0];
+	b2Free(nodes);
+
+	Validate();
+}

+ 284 - 0
src/libraries/Box2D/Collision/b2DynamicTree.h

@@ -0,0 +1,284 @@
+/*
+* Copyright (c) 2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef B2_DYNAMIC_TREE_H
+#define B2_DYNAMIC_TREE_H
+
+#include <Box2D/Collision/b2Collision.h>
+#include <Box2D/Common/b2GrowableStack.h>
+
+#define b2_nullNode (-1)
+
+/// A node in the dynamic tree. The client does not interact with this directly.
+struct b2TreeNode
+{
+	bool IsLeaf() const
+	{
+		return child1 == b2_nullNode;
+	}
+
+	/// Enlarged AABB
+	b2AABB aabb;
+
+	void* userData;
+
+	union
+	{
+		int32 parent;
+		int32 next;
+	};
+
+	int32 child1;
+	int32 child2;
+
+	// leaf = 0, free node = -1
+	int32 height;
+};
+
+/// A dynamic AABB tree broad-phase, inspired by Nathanael Presson's btDbvt.
+/// A dynamic tree arranges data in a binary tree to accelerate
+/// queries such as volume queries and ray casts. Leafs are proxies
+/// with an AABB. In the tree we expand the proxy AABB by b2_fatAABBFactor
+/// so that the proxy AABB is bigger than the client object. This allows the client
+/// object to move by small amounts without triggering a tree update.
+///
+/// Nodes are pooled and relocatable, so we use node indices rather than pointers.
+class b2DynamicTree
+{
+public:
+	/// Constructing the tree initializes the node pool.
+	b2DynamicTree();
+
+	/// Destroy the tree, freeing the node pool.
+	~b2DynamicTree();
+
+	/// Create a proxy. Provide a tight fitting AABB and a userData pointer.
+	int32 CreateProxy(const b2AABB& aabb, void* userData);
+
+	/// Destroy a proxy. This asserts if the id is invalid.
+	void DestroyProxy(int32 proxyId);
+
+	/// Move a proxy with a swepted AABB. If the proxy has moved outside of its fattened AABB,
+	/// then the proxy is removed from the tree and re-inserted. Otherwise
+	/// the function returns immediately.
+	/// @return true if the proxy was re-inserted.
+	bool MoveProxy(int32 proxyId, const b2AABB& aabb1, const b2Vec2& displacement);
+
+	/// Get proxy user data.
+	/// @return the proxy user data or 0 if the id is invalid.
+	void* GetUserData(int32 proxyId) const;
+
+	/// Get the fat AABB for a proxy.
+	const b2AABB& GetFatAABB(int32 proxyId) const;
+
+	/// Query an AABB for overlapping proxies. The callback class
+	/// is called for each proxy that overlaps the supplied AABB.
+	template <typename T>
+	void Query(T* callback, const b2AABB& aabb) const;
+
+	/// Ray-cast against the proxies in the tree. This relies on the callback
+	/// to perform a exact ray-cast in the case were the proxy contains a shape.
+	/// The callback also performs the any collision filtering. This has performance
+	/// roughly equal to k * log(n), where k is the number of collisions and n is the
+	/// number of proxies in the tree.
+	/// @param input the ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1).
+	/// @param callback a callback class that is called for each proxy that is hit by the ray.
+	template <typename T>
+	void RayCast(T* callback, const b2RayCastInput& input) const;
+
+	/// Validate this tree. For testing.
+	void Validate() const;
+
+	/// Compute the height of the binary tree in O(N) time. Should not be
+	/// called often.
+	int32 GetHeight() const;
+
+	/// Get the maximum balance of an node in the tree. The balance is the difference
+	/// in height of the two children of a node.
+	int32 GetMaxBalance() const;
+
+	/// Get the ratio of the sum of the node areas to the root area.
+	float32 GetAreaRatio() const;
+
+	/// Build an optimal tree. Very expensive. For testing.
+	void RebuildBottomUp();
+
+private:
+
+	int32 AllocateNode();
+	void FreeNode(int32 node);
+
+	void InsertLeaf(int32 node);
+	void RemoveLeaf(int32 node);
+
+	int32 Balance(int32 index);
+
+	int32 ComputeHeight() const;
+	int32 ComputeHeight(int32 nodeId) const;
+
+	void ValidateStructure(int32 index) const;
+	void ValidateMetrics(int32 index) const;
+
+	int32 m_root;
+
+	b2TreeNode* m_nodes;
+	int32 m_nodeCount;
+	int32 m_nodeCapacity;
+
+	int32 m_freeList;
+
+	/// This is used to incrementally traverse the tree for re-balancing.
+	uint32 m_path;
+
+	int32 m_insertionCount;
+};
+
+inline void* b2DynamicTree::GetUserData(int32 proxyId) const
+{
+	b2Assert(0 <= proxyId && proxyId < m_nodeCapacity);
+	return m_nodes[proxyId].userData;
+}
+
+inline const b2AABB& b2DynamicTree::GetFatAABB(int32 proxyId) const
+{
+	b2Assert(0 <= proxyId && proxyId < m_nodeCapacity);
+	return m_nodes[proxyId].aabb;
+}
+
+template <typename T>
+inline void b2DynamicTree::Query(T* callback, const b2AABB& aabb) const
+{
+	b2GrowableStack<int32, 256> stack;
+	stack.Push(m_root);
+
+	while (stack.GetCount() > 0)
+	{
+		int32 nodeId = stack.Pop();
+		if (nodeId == b2_nullNode)
+		{
+			continue;
+		}
+
+		const b2TreeNode* node = m_nodes + nodeId;
+
+		if (b2TestOverlap(node->aabb, aabb))
+		{
+			if (node->IsLeaf())
+			{
+				bool proceed = callback->QueryCallback(nodeId);
+				if (proceed == false)
+				{
+					return;
+				}
+			}
+			else
+			{
+				stack.Push(node->child1);
+				stack.Push(node->child2);
+			}
+		}
+	}
+}
+
+template <typename T>
+inline void b2DynamicTree::RayCast(T* callback, const b2RayCastInput& input) const
+{
+	b2Vec2 p1 = input.p1;
+	b2Vec2 p2 = input.p2;
+	b2Vec2 r = p2 - p1;
+	b2Assert(r.LengthSquared() > 0.0f);
+	r.Normalize();
+
+	// v is perpendicular to the segment.
+	b2Vec2 v = b2Cross(1.0f, r);
+	b2Vec2 abs_v = b2Abs(v);
+
+	// Separating axis for segment (Gino, p80).
+	// |dot(v, p1 - c)| > dot(|v|, h)
+
+	float32 maxFraction = input.maxFraction;
+
+	// Build a bounding box for the segment.
+	b2AABB segmentAABB;
+	{
+		b2Vec2 t = p1 + maxFraction * (p2 - p1);
+		segmentAABB.lowerBound = b2Min(p1, t);
+		segmentAABB.upperBound = b2Max(p1, t);
+	}
+
+	b2GrowableStack<int32, 256> stack;
+	stack.Push(m_root);
+
+	while (stack.GetCount() > 0)
+	{
+		int32 nodeId = stack.Pop();
+		if (nodeId == b2_nullNode)
+		{
+			continue;
+		}
+
+		const b2TreeNode* node = m_nodes + nodeId;
+
+		if (b2TestOverlap(node->aabb, segmentAABB) == false)
+		{
+			continue;
+		}
+
+		// Separating axis for segment (Gino, p80).
+		// |dot(v, p1 - c)| > dot(|v|, h)
+		b2Vec2 c = node->aabb.GetCenter();
+		b2Vec2 h = node->aabb.GetExtents();
+		float32 separation = b2Abs(b2Dot(v, p1 - c)) - b2Dot(abs_v, h);
+		if (separation > 0.0f)
+		{
+			continue;
+		}
+
+		if (node->IsLeaf())
+		{
+			b2RayCastInput subInput;
+			subInput.p1 = input.p1;
+			subInput.p2 = input.p2;
+			subInput.maxFraction = maxFraction;
+
+			float32 value = callback->RayCastCallback(subInput, nodeId);
+
+			if (value == 0.0f)
+			{
+				// The client has terminated the ray cast.
+				return;
+			}
+
+			if (value > 0.0f)
+			{
+				// Update segment bounding box.
+				maxFraction = value;
+				b2Vec2 t = p1 + maxFraction * (p2 - p1);
+				segmentAABB.lowerBound = b2Min(p1, t);
+				segmentAABB.upperBound = b2Max(p1, t);
+			}
+		}
+		else
+		{
+			stack.Push(node->child1);
+			stack.Push(node->child2);
+		}
+	}
+}
+
+#endif

+ 483 - 0
src/libraries/Box2D/Collision/b2TimeOfImpact.cpp

@@ -0,0 +1,483 @@
+/*
+* Copyright (c) 2007-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Collision/b2Collision.h>
+#include <Box2D/Collision/b2Distance.h>
+#include <Box2D/Collision/b2TimeOfImpact.h>
+#include <Box2D/Collision/Shapes/b2CircleShape.h>
+#include <Box2D/Collision/Shapes/b2PolygonShape.h>
+
+#include <cstdio>
+using namespace std;
+
+int32 b2_toiCalls, b2_toiIters, b2_toiMaxIters;
+int32 b2_toiRootIters, b2_toiMaxRootIters;
+
+struct b2SeparationFunction
+{
+	enum Type
+	{
+		e_points,
+		e_faceA,
+		e_faceB
+	};
+
+	// TODO_ERIN might not need to return the separation
+
+	float32 Initialize(const b2SimplexCache* cache,
+		const b2DistanceProxy* proxyA, const b2Sweep& sweepA,
+		const b2DistanceProxy* proxyB, const b2Sweep& sweepB,
+		float32 t1)
+	{
+		m_proxyA = proxyA;
+		m_proxyB = proxyB;
+		int32 count = cache->count;
+		b2Assert(0 < count && count < 3);
+
+		m_sweepA = sweepA;
+		m_sweepB = sweepB;
+
+		b2Transform xfA, xfB;
+		m_sweepA.GetTransform(&xfA, t1);
+		m_sweepB.GetTransform(&xfB, t1);
+
+		if (count == 1)
+		{
+			m_type = e_points;
+			b2Vec2 localPointA = m_proxyA->GetVertex(cache->indexA[0]);
+			b2Vec2 localPointB = m_proxyB->GetVertex(cache->indexB[0]);
+			b2Vec2 pointA = b2Mul(xfA, localPointA);
+			b2Vec2 pointB = b2Mul(xfB, localPointB);
+			m_axis = pointB - pointA;
+			float32 s = m_axis.Normalize();
+			return s;
+		}
+		else if (cache->indexA[0] == cache->indexA[1])
+		{
+			// Two points on B and one on A.
+			m_type = e_faceB;
+			b2Vec2 localPointB1 = proxyB->GetVertex(cache->indexB[0]);
+			b2Vec2 localPointB2 = proxyB->GetVertex(cache->indexB[1]);
+
+			m_axis = b2Cross(localPointB2 - localPointB1, 1.0f);
+			m_axis.Normalize();
+			b2Vec2 normal = b2Mul(xfB.q, m_axis);
+
+			m_localPoint = 0.5f * (localPointB1 + localPointB2);
+			b2Vec2 pointB = b2Mul(xfB, m_localPoint);
+
+			b2Vec2 localPointA = proxyA->GetVertex(cache->indexA[0]);
+			b2Vec2 pointA = b2Mul(xfA, localPointA);
+
+			float32 s = b2Dot(pointA - pointB, normal);
+			if (s < 0.0f)
+			{
+				m_axis = -m_axis;
+				s = -s;
+			}
+			return s;
+		}
+		else
+		{
+			// Two points on A and one or two points on B.
+			m_type = e_faceA;
+			b2Vec2 localPointA1 = m_proxyA->GetVertex(cache->indexA[0]);
+			b2Vec2 localPointA2 = m_proxyA->GetVertex(cache->indexA[1]);
+			
+			m_axis = b2Cross(localPointA2 - localPointA1, 1.0f);
+			m_axis.Normalize();
+			b2Vec2 normal = b2Mul(xfA.q, m_axis);
+
+			m_localPoint = 0.5f * (localPointA1 + localPointA2);
+			b2Vec2 pointA = b2Mul(xfA, m_localPoint);
+
+			b2Vec2 localPointB = m_proxyB->GetVertex(cache->indexB[0]);
+			b2Vec2 pointB = b2Mul(xfB, localPointB);
+
+			float32 s = b2Dot(pointB - pointA, normal);
+			if (s < 0.0f)
+			{
+				m_axis = -m_axis;
+				s = -s;
+			}
+			return s;
+		}
+	}
+
+	float32 FindMinSeparation(int32* indexA, int32* indexB, float32 t) const
+	{
+		b2Transform xfA, xfB;
+		m_sweepA.GetTransform(&xfA, t);
+		m_sweepB.GetTransform(&xfB, t);
+
+		switch (m_type)
+		{
+		case e_points:
+			{
+				b2Vec2 axisA = b2MulT(xfA.q,  m_axis);
+				b2Vec2 axisB = b2MulT(xfB.q, -m_axis);
+
+				*indexA = m_proxyA->GetSupport(axisA);
+				*indexB = m_proxyB->GetSupport(axisB);
+
+				b2Vec2 localPointA = m_proxyA->GetVertex(*indexA);
+				b2Vec2 localPointB = m_proxyB->GetVertex(*indexB);
+				
+				b2Vec2 pointA = b2Mul(xfA, localPointA);
+				b2Vec2 pointB = b2Mul(xfB, localPointB);
+
+				float32 separation = b2Dot(pointB - pointA, m_axis);
+				return separation;
+			}
+
+		case e_faceA:
+			{
+				b2Vec2 normal = b2Mul(xfA.q, m_axis);
+				b2Vec2 pointA = b2Mul(xfA, m_localPoint);
+
+				b2Vec2 axisB = b2MulT(xfB.q, -normal);
+				
+				*indexA = -1;
+				*indexB = m_proxyB->GetSupport(axisB);
+
+				b2Vec2 localPointB = m_proxyB->GetVertex(*indexB);
+				b2Vec2 pointB = b2Mul(xfB, localPointB);
+
+				float32 separation = b2Dot(pointB - pointA, normal);
+				return separation;
+			}
+
+		case e_faceB:
+			{
+				b2Vec2 normal = b2Mul(xfB.q, m_axis);
+				b2Vec2 pointB = b2Mul(xfB, m_localPoint);
+
+				b2Vec2 axisA = b2MulT(xfA.q, -normal);
+
+				*indexB = -1;
+				*indexA = m_proxyA->GetSupport(axisA);
+
+				b2Vec2 localPointA = m_proxyA->GetVertex(*indexA);
+				b2Vec2 pointA = b2Mul(xfA, localPointA);
+
+				float32 separation = b2Dot(pointA - pointB, normal);
+				return separation;
+			}
+
+		default:
+			b2Assert(false);
+			*indexA = -1;
+			*indexB = -1;
+			return 0.0f;
+		}
+	}
+
+	float32 Evaluate(int32 indexA, int32 indexB, float32 t) const
+	{
+		b2Transform xfA, xfB;
+		m_sweepA.GetTransform(&xfA, t);
+		m_sweepB.GetTransform(&xfB, t);
+
+		switch (m_type)
+		{
+		case e_points:
+			{
+				b2Vec2 axisA = b2MulT(xfA.q,  m_axis);
+				b2Vec2 axisB = b2MulT(xfB.q, -m_axis);
+
+				b2Vec2 localPointA = m_proxyA->GetVertex(indexA);
+				b2Vec2 localPointB = m_proxyB->GetVertex(indexB);
+
+				b2Vec2 pointA = b2Mul(xfA, localPointA);
+				b2Vec2 pointB = b2Mul(xfB, localPointB);
+				float32 separation = b2Dot(pointB - pointA, m_axis);
+
+				return separation;
+			}
+
+		case e_faceA:
+			{
+				b2Vec2 normal = b2Mul(xfA.q, m_axis);
+				b2Vec2 pointA = b2Mul(xfA, m_localPoint);
+
+				b2Vec2 axisB = b2MulT(xfB.q, -normal);
+
+				b2Vec2 localPointB = m_proxyB->GetVertex(indexB);
+				b2Vec2 pointB = b2Mul(xfB, localPointB);
+
+				float32 separation = b2Dot(pointB - pointA, normal);
+				return separation;
+			}
+
+		case e_faceB:
+			{
+				b2Vec2 normal = b2Mul(xfB.q, m_axis);
+				b2Vec2 pointB = b2Mul(xfB, m_localPoint);
+
+				b2Vec2 axisA = b2MulT(xfA.q, -normal);
+
+				b2Vec2 localPointA = m_proxyA->GetVertex(indexA);
+				b2Vec2 pointA = b2Mul(xfA, localPointA);
+
+				float32 separation = b2Dot(pointA - pointB, normal);
+				return separation;
+			}
+
+		default:
+			b2Assert(false);
+			return 0.0f;
+		}
+	}
+
+	const b2DistanceProxy* m_proxyA;
+	const b2DistanceProxy* m_proxyB;
+	b2Sweep m_sweepA, m_sweepB;
+	Type m_type;
+	b2Vec2 m_localPoint;
+	b2Vec2 m_axis;
+};
+
+// CCD via the local separating axis method. This seeks progression
+// by computing the largest time at which separation is maintained.
+void b2TimeOfImpact(b2TOIOutput* output, const b2TOIInput* input)
+{
+	++b2_toiCalls;
+
+	output->state = b2TOIOutput::e_unknown;
+	output->t = input->tMax;
+
+	const b2DistanceProxy* proxyA = &input->proxyA;
+	const b2DistanceProxy* proxyB = &input->proxyB;
+
+	b2Sweep sweepA = input->sweepA;
+	b2Sweep sweepB = input->sweepB;
+
+	// Large rotations can make the root finder fail, so we normalize the
+	// sweep angles.
+	sweepA.Normalize();
+	sweepB.Normalize();
+
+	float32 tMax = input->tMax;
+
+	float32 totalRadius = proxyA->m_radius + proxyB->m_radius;
+	float32 target = b2Max(b2_linearSlop, totalRadius - 3.0f * b2_linearSlop);
+	float32 tolerance = 0.25f * b2_linearSlop;
+	b2Assert(target > tolerance);
+
+	float32 t1 = 0.0f;
+	const int32 k_maxIterations = 20;	// TODO_ERIN b2Settings
+	int32 iter = 0;
+
+	// Prepare input for distance query.
+	b2SimplexCache cache;
+	cache.count = 0;
+	b2DistanceInput distanceInput;
+	distanceInput.proxyA = input->proxyA;
+	distanceInput.proxyB = input->proxyB;
+	distanceInput.useRadii = false;
+
+	// The outer loop progressively attempts to compute new separating axes.
+	// This loop terminates when an axis is repeated (no progress is made).
+	for(;;)
+	{
+		b2Transform xfA, xfB;
+		sweepA.GetTransform(&xfA, t1);
+		sweepB.GetTransform(&xfB, t1);
+
+		// Get the distance between shapes. We can also use the results
+		// to get a separating axis.
+		distanceInput.transformA = xfA;
+		distanceInput.transformB = xfB;
+		b2DistanceOutput distanceOutput;
+		b2Distance(&distanceOutput, &cache, &distanceInput);
+
+		// If the shapes are overlapped, we give up on continuous collision.
+		if (distanceOutput.distance <= 0.0f)
+		{
+			// Failure!
+			output->state = b2TOIOutput::e_overlapped;
+			output->t = 0.0f;
+			break;
+		}
+
+		if (distanceOutput.distance < target + tolerance)
+		{
+			// Victory!
+			output->state = b2TOIOutput::e_touching;
+			output->t = t1;
+			break;
+		}
+
+		// Initialize the separating axis.
+		b2SeparationFunction fcn;
+		fcn.Initialize(&cache, proxyA, sweepA, proxyB, sweepB, t1);
+#if 0
+		// Dump the curve seen by the root finder
+		{
+			const int32 N = 100;
+			float32 dx = 1.0f / N;
+			float32 xs[N+1];
+			float32 fs[N+1];
+
+			float32 x = 0.0f;
+
+			for (int32 i = 0; i <= N; ++i)
+			{
+				sweepA.GetTransform(&xfA, x);
+				sweepB.GetTransform(&xfB, x);
+				float32 f = fcn.Evaluate(xfA, xfB) - target;
+
+				printf("%g %g\n", x, f);
+
+				xs[i] = x;
+				fs[i] = f;
+
+				x += dx;
+			}
+		}
+#endif
+
+		// Compute the TOI on the separating axis. We do this by successively
+		// resolving the deepest point. This loop is bounded by the number of vertices.
+		bool done = false;
+		float32 t2 = tMax;
+		int32 pushBackIter = 0;
+		for (;;)
+		{
+			// Find the deepest point at t2. Store the witness point indices.
+			int32 indexA, indexB;
+			float32 s2 = fcn.FindMinSeparation(&indexA, &indexB, t2);
+
+			// Is the final configuration separated?
+			if (s2 > target + tolerance)
+			{
+				// Victory!
+				output->state = b2TOIOutput::e_separated;
+				output->t = tMax;
+				done = true;
+				break;
+			}
+
+			// Has the separation reached tolerance?
+			if (s2 > target - tolerance)
+			{
+				// Advance the sweeps
+				t1 = t2;
+				break;
+			}
+
+			// Compute the initial separation of the witness points.
+			float32 s1 = fcn.Evaluate(indexA, indexB, t1);
+
+			// Check for initial overlap. This might happen if the root finder
+			// runs out of iterations.
+			if (s1 < target - tolerance)
+			{
+				output->state = b2TOIOutput::e_failed;
+				output->t = t1;
+				done = true;
+				break;
+			}
+
+			// Check for touching
+			if (s1 <= target + tolerance)
+			{
+				// Victory! t1 should hold the TOI (could be 0.0).
+				output->state = b2TOIOutput::e_touching;
+				output->t = t1;
+				done = true;
+				break;
+			}
+
+			// Compute 1D root of: f(x) - target = 0
+			int32 rootIterCount = 0;
+			float32 a1 = t1, a2 = t2;
+			for (;;)
+			{
+				// Use a mix of the secant rule and bisection.
+				float32 t;
+				if (rootIterCount & 1)
+				{
+					// Secant rule to improve convergence.
+					t = a1 + (target - s1) * (a2 - a1) / (s2 - s1);
+				}
+				else
+				{
+					// Bisection to guarantee progress.
+					t = 0.5f * (a1 + a2);
+				}
+
+				float32 s = fcn.Evaluate(indexA, indexB, t);
+
+				if (b2Abs(s - target) < tolerance)
+				{
+					// t2 holds a tentative value for t1
+					t2 = t;
+					break;
+				}
+
+				// Ensure we continue to bracket the root.
+				if (s > target)
+				{
+					a1 = t;
+					s1 = s;
+				}
+				else
+				{
+					a2 = t;
+					s2 = s;
+				}
+
+				++rootIterCount;
+				++b2_toiRootIters;
+
+				if (rootIterCount == 50)
+				{
+					break;
+				}
+			}
+
+			b2_toiMaxRootIters = b2Max(b2_toiMaxRootIters, rootIterCount);
+
+			++pushBackIter;
+
+			if (pushBackIter == b2_maxPolygonVertices)
+			{
+				break;
+			}
+		}
+
+		++iter;
+		++b2_toiIters;
+
+		if (done)
+		{
+			break;
+		}
+
+		if (iter == k_maxIterations)
+		{
+			// Root finder got stuck. Semi-victory.
+			output->state = b2TOIOutput::e_failed;
+			output->t = t1;
+			break;
+		}
+	}
+
+	b2_toiMaxIters = b2Max(b2_toiMaxIters, iter);
+}

+ 58 - 0
src/libraries/Box2D/Collision/b2TimeOfImpact.h

@@ -0,0 +1,58 @@
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef B2_TIME_OF_IMPACT_H
+#define B2_TIME_OF_IMPACT_H
+
+#include <Box2D/Common/b2Math.h>
+#include <Box2D/Collision/b2Distance.h>
+
+/// Input parameters for b2TimeOfImpact
+struct b2TOIInput
+{
+	b2DistanceProxy proxyA;
+	b2DistanceProxy proxyB;
+	b2Sweep sweepA;
+	b2Sweep sweepB;
+	float32 tMax;		// defines sweep interval [0, tMax]
+};
+
+// Output parameters for b2TimeOfImpact.
+struct b2TOIOutput
+{
+	enum State
+	{
+		e_unknown,
+		e_failed,
+		e_overlapped,
+		e_touching,
+		e_separated
+	};
+
+	State state;
+	float32 t;
+};
+
+/// Compute the upper bound on time before two shapes penetrate. Time is represented as
+/// a fraction between [0,tMax]. This uses a swept separating axis and may miss some intermediate,
+/// non-tunneling collision. If you change the time interval, you should call this function
+/// again.
+/// Note: use b2Distance to compute the contact point and normal at the time of impact.
+void b2TimeOfImpact(b2TOIOutput* output, const b2TOIInput* input);
+
+#endif

+ 19 - 8
src/modules/physics/box2d/Source/Common/b2BlockAllocator.cpp → src/libraries/Box2D/Common/b2BlockAllocator.cpp

@@ -1,5 +1,5 @@
 /*
 /*
-* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
 *
 *
 * This software is provided 'as-is', without any express or implied
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * warranty.  In no event will the authors be held liable for any damages
@@ -16,11 +16,12 @@
 * 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.
 */
 */
 
 
-#include "b2BlockAllocator.h"
+#include <Box2D/Common/b2BlockAllocator.h>
 #include <cstdlib>
 #include <cstdlib>
-#include <memory>
 #include <climits>
 #include <climits>
-#include <string.h>
+#include <cstring>
+#include <memory>
+using namespace std;
 
 
 int32 b2BlockAllocator::s_blockSizes[b2_blockSizes] = 
 int32 b2BlockAllocator::s_blockSizes[b2_blockSizes] = 
 {
 {
@@ -100,7 +101,12 @@ void* b2BlockAllocator::Allocate(int32 size)
 	if (size == 0)
 	if (size == 0)
 		return NULL;
 		return NULL;
 
 
-	b2Assert(0 < size && size <= b2_maxBlockSize);
+	b2Assert(0 < size);
+
+	if (size > b2_maxBlockSize)
+	{
+		return b2Alloc(size);
+	}
 
 
 	int32 index = s_blockSizeLookup[size];
 	int32 index = s_blockSizeLookup[size];
 	b2Assert(0 <= index && index < b2_blockSizes);
 	b2Assert(0 <= index && index < b2_blockSizes);
@@ -155,7 +161,13 @@ void b2BlockAllocator::Free(void* p, int32 size)
 		return;
 		return;
 	}
 	}
 
 
-	b2Assert(0 < size && size <= b2_maxBlockSize);
+	b2Assert(0 < size);
+
+	if (size > b2_maxBlockSize)
+	{
+		b2Free(p);
+		return;
+	}
 
 
 	int32 index = s_blockSizeLookup[size];
 	int32 index = s_blockSizeLookup[size];
 	b2Assert(0 <= index && index < b2_blockSizes);
 	b2Assert(0 <= index && index < b2_blockSizes);
@@ -164,14 +176,13 @@ void b2BlockAllocator::Free(void* p, int32 size)
 	// Verify the memory address and size is valid.
 	// Verify the memory address and size is valid.
 	int32 blockSize = s_blockSizes[index];
 	int32 blockSize = s_blockSizes[index];
 	bool found = false;
 	bool found = false;
-	int32 gap = (int32)((int8*)&m_chunks->blocks - (int8*)m_chunks);
 	for (int32 i = 0; i < m_chunkCount; ++i)
 	for (int32 i = 0; i < m_chunkCount; ++i)
 	{
 	{
 		b2Chunk* chunk = m_chunks + i;
 		b2Chunk* chunk = m_chunks + i;
 		if (chunk->blockSize != blockSize)
 		if (chunk->blockSize != blockSize)
 		{
 		{
 			b2Assert(	(int8*)p + blockSize <= (int8*)chunk->blocks ||
 			b2Assert(	(int8*)p + blockSize <= (int8*)chunk->blocks ||
-						(int8*)chunk->blocks + b2_chunkSize + gap <= (int8*)p);
+						(int8*)chunk->blocks + b2_chunkSize <= (int8*)p);
 		}
 		}
 		else
 		else
 		{
 		{

+ 9 - 6
src/modules/physics/box2d/Source/Common/b2BlockAllocator.h → src/libraries/Box2D/Common/b2BlockAllocator.h

@@ -1,5 +1,5 @@
 /*
 /*
-* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
 *
 *
 * This software is provided 'as-is', without any express or implied
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * warranty.  In no event will the authors be held liable for any damages
@@ -19,9 +19,9 @@
 #ifndef B2_BLOCK_ALLOCATOR_H
 #ifndef B2_BLOCK_ALLOCATOR_H
 #define B2_BLOCK_ALLOCATOR_H
 #define B2_BLOCK_ALLOCATOR_H
 
 
-#include "b2Settings.h"
+#include <Box2D/Common/b2Settings.h>
 
 
-const int32 b2_chunkSize = 4096;
+const int32 b2_chunkSize = 16 * 1024;
 const int32 b2_maxBlockSize = 640;
 const int32 b2_maxBlockSize = 640;
 const int32 b2_blockSizes = 14;
 const int32 b2_blockSizes = 14;
 const int32 b2_chunkArrayIncrement = 128;
 const int32 b2_chunkArrayIncrement = 128;
@@ -29,16 +29,19 @@ const int32 b2_chunkArrayIncrement = 128;
 struct b2Block;
 struct b2Block;
 struct b2Chunk;
 struct b2Chunk;
 
 
-// This is a small object allocator used for allocating small
-// objects that persist for more than one time step.
-// See: http://www.codeproject.com/useritems/Small_Block_Allocator.asp
+/// This is a small object allocator used for allocating small
+/// objects that persist for more than one time step.
+/// See: http://www.codeproject.com/useritems/Small_Block_Allocator.asp
 class b2BlockAllocator
 class b2BlockAllocator
 {
 {
 public:
 public:
 	b2BlockAllocator();
 	b2BlockAllocator();
 	~b2BlockAllocator();
 	~b2BlockAllocator();
 
 
+	/// Allocate memory. This will use b2Alloc if the size is larger than b2_maxBlockSize.
 	void* Allocate(int32 size);
 	void* Allocate(int32 size);
+
+	/// Free memory. This will use b2Free if the size is larger than b2_maxBlockSize.
 	void Free(void* p, int32 size);
 	void Free(void* p, int32 size);
 
 
 	void Clear();
 	void Clear();

+ 23 - 12
src/modules/physics/box2d/Source/Dynamics/Contacts/b2NullContact.h → src/libraries/Box2D/Common/b2Draw.cpp

@@ -1,5 +1,5 @@
 /*
 /*
-* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
+* Copyright (c) 2011 Erin Catto http://box2d.org
 *
 *
 * This software is provided 'as-is', without any express or implied
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * warranty.  In no event will the authors be held liable for any damages
@@ -16,18 +16,29 @@
 * 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.
 */
 */
 
 
-#ifndef B2_NULL_CONTACT_H
-#define B2_NULL_CONTACT_H
+#include <Box2D/Common/b2Draw.h>
 
 
-#include "../../Common/b2Math.h"
-#include "b2Contact.h"
+b2Draw::b2Draw()
+{
+	m_drawFlags = 0;
+}
+
+void b2Draw::SetFlags(uint32 flags)
+{
+	m_drawFlags = flags;
+}
 
 
-class b2NullContact : public b2Contact
+uint32 b2Draw::GetFlags() const
 {
 {
-public:
-	b2NullContact() {}
-	void Evaluate(b2ContactListener*) {}
-	b2Manifold* GetManifolds() { return NULL; }
-};
+	return m_drawFlags;
+}
 
 
-#endif
+void b2Draw::AppendFlags(uint32 flags)
+{
+	m_drawFlags |= flags;
+}
+
+void b2Draw::ClearFlags(uint32 flags)
+{
+	m_drawFlags &= ~flags;
+}

+ 81 - 0
src/libraries/Box2D/Common/b2Draw.h

@@ -0,0 +1,81 @@
+/*
+* Copyright (c) 2011 Erin Catto http://box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Common/b2Math.h>
+
+/// Color for debug drawing. Each value has the range [0,1].
+struct b2Color
+{
+	b2Color() {}
+	b2Color(float32 r, float32 g, float32 b) : r(r), g(g), b(b) {}
+	void Set(float32 ri, float32 gi, float32 bi) { r = ri; g = gi; b = bi; }
+	float32 r, g, b;
+};
+
+/// Implement and register this class with a b2World to provide debug drawing of physics
+/// entities in your game.
+class b2Draw
+{
+public:
+	b2Draw();
+
+	virtual ~b2Draw() {}
+
+	enum
+	{
+		e_shapeBit				= 0x0001,	///< draw shapes
+		e_jointBit				= 0x0002,	///< draw joint connections
+		e_aabbBit				= 0x0004,	///< draw axis aligned bounding boxes
+		e_pairBit				= 0x0008,	///< draw broad-phase pairs
+		e_centerOfMassBit		= 0x0010	///< draw center of mass frame
+	};
+
+	/// Set the drawing flags.
+	void SetFlags(uint32 flags);
+
+	/// Get the drawing flags.
+	uint32 GetFlags() const;
+	
+	/// Append flags to the current flags.
+	void AppendFlags(uint32 flags);
+
+	/// Clear flags from the current flags.
+	void ClearFlags(uint32 flags);
+
+	/// Draw a closed polygon provided in CCW order.
+	virtual void DrawPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) = 0;
+
+	/// Draw a solid closed polygon provided in CCW order.
+	virtual void DrawSolidPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) = 0;
+
+	/// Draw a circle.
+	virtual void DrawCircle(const b2Vec2& center, float32 radius, const b2Color& color) = 0;
+	
+	/// Draw a solid circle.
+	virtual void DrawSolidCircle(const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color) = 0;
+	
+	/// Draw a line segment.
+	virtual void DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color) = 0;
+
+	/// Draw a transform. Choose your own length scale.
+	/// @param xf a transform.
+	virtual void DrawTransform(const b2Transform& xf) = 0;
+
+protected:
+	uint32 m_drawFlags;
+};

+ 85 - 0
src/libraries/Box2D/Common/b2GrowableStack.h

@@ -0,0 +1,85 @@
+/*
+* Copyright (c) 2010 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef B2_GROWABLE_STACK_H
+#define B2_GROWABLE_STACK_H
+#include <Box2D/Common/b2Settings.h>
+#include <cstring>
+
+/// This is a growable LIFO stack with an initial capacity of N.
+/// If the stack size exceeds the initial capacity, the heap is used
+/// to increase the size of the stack.
+template <typename T, int32 N>
+class b2GrowableStack
+{
+public:
+	b2GrowableStack()
+	{
+		m_stack = m_array;
+		m_count = 0;
+		m_capacity = N;
+	}
+
+	~b2GrowableStack()
+	{
+		if (m_stack != m_array)
+		{
+			b2Free(m_stack);
+			m_stack = NULL;
+		}
+	}
+
+	void Push(const T& element)
+	{
+		if (m_count == m_capacity)
+		{
+			T* old = m_stack;
+			m_capacity *= 2;
+			m_stack = (T*)b2Alloc(m_capacity * sizeof(T));
+			std::memcpy(m_stack, old, m_count * sizeof(T));
+			if (old != m_array)
+			{
+				b2Free(old);
+			}
+		}
+
+		m_stack[m_count] = element;
+		++m_count;
+	}
+
+	T Pop()
+	{
+		b2Assert(m_count > 0);
+		--m_count;
+		return m_stack[m_count];
+	}
+
+	int32 GetCount()
+	{
+		return m_count;
+	}
+
+private:
+	T* m_stack;
+	T m_array[N];
+	int32 m_count;
+	int32 m_capacity;
+};
+
+
+#endif

+ 94 - 0
src/libraries/Box2D/Common/b2Math.cpp

@@ -0,0 +1,94 @@
+/*
+* Copyright (c) 2007-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Common/b2Math.h>
+
+const b2Vec2 b2Vec2_zero(0.0f, 0.0f);
+
+/// Solve A * x = b, where b is a column vector. This is more efficient
+/// than computing the inverse in one-shot cases.
+b2Vec3 b2Mat33::Solve33(const b2Vec3& b) const
+{
+	float32 det = b2Dot(ex, b2Cross(ey, ez));
+	if (det != 0.0f)
+	{
+		det = 1.0f / det;
+	}
+	b2Vec3 x;
+	x.x = det * b2Dot(b, b2Cross(ey, ez));
+	x.y = det * b2Dot(ex, b2Cross(b, ez));
+	x.z = det * b2Dot(ex, b2Cross(ey, b));
+	return x;
+}
+
+/// Solve A * x = b, where b is a column vector. This is more efficient
+/// than computing the inverse in one-shot cases.
+b2Vec2 b2Mat33::Solve22(const b2Vec2& b) const
+{
+	float32 a11 = ex.x, a12 = ey.x, a21 = ex.y, a22 = ey.y;
+	float32 det = a11 * a22 - a12 * a21;
+	if (det != 0.0f)
+	{
+		det = 1.0f / det;
+	}
+	b2Vec2 x;
+	x.x = det * (a22 * b.x - a12 * b.y);
+	x.y = det * (a11 * b.y - a21 * b.x);
+	return x;
+}
+
+///
+void b2Mat33::GetInverse22(b2Mat33* M) const
+{
+	float32 a = ex.x, b = ey.x, c = ex.y, d = ey.y;
+	float32 det = a * d - b * c;
+	if (det != 0.0f)
+	{
+		det = 1.0f / det;
+	}
+
+	M->ex.x =  det * d;	M->ey.x = -det * b; M->ex.z = 0.0f;
+	M->ex.y = -det * c;	M->ey.y =  det * a; M->ey.z = 0.0f;
+	M->ez.x = 0.0f; M->ez.y = 0.0f; M->ez.z = 0.0f;
+}
+
+/// Returns the zero matrix if singular.
+void b2Mat33::GetSymInverse33(b2Mat33* M) const
+{
+	float32 det = b2Dot(ex, b2Cross(ey, ez));
+	if (det != 0.0f)
+	{
+		det = 1.0f / det;
+	}
+
+	float32 a11 = ex.x, a12 = ey.x, a13 = ez.x;
+	float32 a22 = ey.y, a23 = ez.y;
+	float32 a33 = ez.z;
+
+	M->ex.x = det * (a22 * a33 - a23 * a23);
+	M->ex.y = det * (a13 * a23 - a12 * a33);
+	M->ex.z = det * (a12 * a23 - a13 * a22);
+
+	M->ey.x = M->ex.y;
+	M->ey.y = det * (a11 * a33 - a13 * a13);
+	M->ey.z = det * (a13 * a12 - a11 * a23);
+
+	M->ez.x = M->ex.z;
+	M->ez.y = M->ey.z;
+	M->ez.z = det * (a11 * a22 - a12 * a12);
+}

+ 731 - 0
src/libraries/Box2D/Common/b2Math.h

@@ -0,0 +1,731 @@
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef B2_MATH_H
+#define B2_MATH_H
+
+#include <Box2D/Common/b2Settings.h>
+
+#include <cmath>
+#include <cfloat>
+#include <cstddef>
+#include <limits>
+
+/// This function is used to ensure that a floating point number is
+/// not a NaN or infinity.
+inline bool b2IsValid(float32 x)
+{
+	if (x != x)
+	{
+		// NaN.
+		return false;
+	}
+
+	float32 infinity = std::numeric_limits<float32>::infinity();
+	return -infinity < x && x < infinity;
+}
+
+/// This is a approximate yet fast inverse square-root.
+inline float32 b2InvSqrt(float32 x)
+{
+	union
+	{
+		float32 x;
+		int32 i;
+	} convert;
+
+	convert.x = x;
+	float32 xhalf = 0.5f * x;
+	convert.i = 0x5f3759df - (convert.i >> 1);
+	x = convert.x;
+	x = x * (1.5f - xhalf * x * x);
+	return x;
+}
+
+#define	b2Sqrt(x)	std::sqrt(x)
+#define	b2Atan2(y, x)	std::atan2(y, x)
+
+/// A 2D column vector.
+struct b2Vec2
+{
+	/// Default constructor does nothing (for performance).
+	b2Vec2() {}
+
+	/// Construct using coordinates.
+	b2Vec2(float32 x, float32 y) : x(x), y(y) {}
+
+	/// Set this vector to all zeros.
+	void SetZero() { x = 0.0f; y = 0.0f; }
+
+	/// Set this vector to some specified coordinates.
+	void Set(float32 x_, float32 y_) { x = x_; y = y_; }
+
+	/// Negate this vector.
+	b2Vec2 operator -() const { b2Vec2 v; v.Set(-x, -y); return v; }
+	
+	/// Read from and indexed element.
+	float32 operator () (int32 i) const
+	{
+		return (&x)[i];
+	}
+
+	/// Write to an indexed element.
+	float32& operator () (int32 i)
+	{
+		return (&x)[i];
+	}
+
+	/// Add a vector to this vector.
+	void operator += (const b2Vec2& v)
+	{
+		x += v.x; y += v.y;
+	}
+	
+	/// Subtract a vector from this vector.
+	void operator -= (const b2Vec2& v)
+	{
+		x -= v.x; y -= v.y;
+	}
+
+	/// Multiply this vector by a scalar.
+	void operator *= (float32 a)
+	{
+		x *= a; y *= a;
+	}
+
+	/// Get the length of this vector (the norm).
+	float32 Length() const
+	{
+		return b2Sqrt(x * x + y * y);
+	}
+
+	/// Get the length squared. For performance, use this instead of
+	/// b2Vec2::Length (if possible).
+	float32 LengthSquared() const
+	{
+		return x * x + y * y;
+	}
+
+	/// Convert this vector into a unit vector. Returns the length.
+	float32 Normalize()
+	{
+		float32 length = Length();
+		if (length < b2_epsilon)
+		{
+			return 0.0f;
+		}
+		float32 invLength = 1.0f / length;
+		x *= invLength;
+		y *= invLength;
+
+		return length;
+	}
+
+	/// Does this vector contain finite coordinates?
+	bool IsValid() const
+	{
+		return b2IsValid(x) && b2IsValid(y);
+	}
+
+	/// Get the skew vector such that dot(skew_vec, other) == cross(vec, other)
+	b2Vec2 Skew() const
+	{
+		return b2Vec2(-y, x);
+	}
+
+	float32 x, y;
+};
+
+/// A 2D column vector with 3 elements.
+struct b2Vec3
+{
+	/// Default constructor does nothing (for performance).
+	b2Vec3() {}
+
+	/// Construct using coordinates.
+	b2Vec3(float32 x, float32 y, float32 z) : x(x), y(y), z(z) {}
+
+	/// Set this vector to all zeros.
+	void SetZero() { x = 0.0f; y = 0.0f; z = 0.0f; }
+
+	/// Set this vector to some specified coordinates.
+	void Set(float32 x_, float32 y_, float32 z_) { x = x_; y = y_; z = z_; }
+
+	/// Negate this vector.
+	b2Vec3 operator -() const { b2Vec3 v; v.Set(-x, -y, -z); return v; }
+
+	/// Add a vector to this vector.
+	void operator += (const b2Vec3& v)
+	{
+		x += v.x; y += v.y; z += v.z;
+	}
+
+	/// Subtract a vector from this vector.
+	void operator -= (const b2Vec3& v)
+	{
+		x -= v.x; y -= v.y; z -= v.z;
+	}
+
+	/// Multiply this vector by a scalar.
+	void operator *= (float32 s)
+	{
+		x *= s; y *= s; z *= s;
+	}
+
+	float32 x, y, z;
+};
+
+/// A 2-by-2 matrix. Stored in column-major order.
+struct b2Mat22
+{
+	/// The default constructor does nothing (for performance).
+	b2Mat22() {}
+
+	/// Construct this matrix using columns.
+	b2Mat22(const b2Vec2& c1, const b2Vec2& c2)
+	{
+		ex = c1;
+		ey = c2;
+	}
+
+	/// Construct this matrix using scalars.
+	b2Mat22(float32 a11, float32 a12, float32 a21, float32 a22)
+	{
+		ex.x = a11; ex.y = a21;
+		ey.x = a12; ey.y = a22;
+	}
+
+	/// Initialize this matrix using columns.
+	void Set(const b2Vec2& c1, const b2Vec2& c2)
+	{
+		ex = c1;
+		ey = c2;
+	}
+
+	/// Set this to the identity matrix.
+	void SetIdentity()
+	{
+		ex.x = 1.0f; ey.x = 0.0f;
+		ex.y = 0.0f; ey.y = 1.0f;
+	}
+
+	/// Set this matrix to all zeros.
+	void SetZero()
+	{
+		ex.x = 0.0f; ey.x = 0.0f;
+		ex.y = 0.0f; ey.y = 0.0f;
+	}
+
+	b2Mat22 GetInverse() const
+	{
+		float32 a = ex.x, b = ey.x, c = ex.y, d = ey.y;
+		b2Mat22 B;
+		float32 det = a * d - b * c;
+		if (det != 0.0f)
+		{
+			det = 1.0f / det;
+		}
+		B.ex.x =  det * d;	B.ey.x = -det * b;
+		B.ex.y = -det * c;	B.ey.y =  det * a;
+		return B;
+	}
+
+	/// Solve A * x = b, where b is a column vector. This is more efficient
+	/// than computing the inverse in one-shot cases.
+	b2Vec2 Solve(const b2Vec2& b) const
+	{
+		float32 a11 = ex.x, a12 = ey.x, a21 = ex.y, a22 = ey.y;
+		float32 det = a11 * a22 - a12 * a21;
+		if (det != 0.0f)
+		{
+			det = 1.0f / det;
+		}
+		b2Vec2 x;
+		x.x = det * (a22 * b.x - a12 * b.y);
+		x.y = det * (a11 * b.y - a21 * b.x);
+		return x;
+	}
+
+	b2Vec2 ex, ey;
+};
+
+/// A 3-by-3 matrix. Stored in column-major order.
+struct b2Mat33
+{
+	/// The default constructor does nothing (for performance).
+	b2Mat33() {}
+
+	/// Construct this matrix using columns.
+	b2Mat33(const b2Vec3& c1, const b2Vec3& c2, const b2Vec3& c3)
+	{
+		ex = c1;
+		ey = c2;
+		ez = c3;
+	}
+
+	/// Set this matrix to all zeros.
+	void SetZero()
+	{
+		ex.SetZero();
+		ey.SetZero();
+		ez.SetZero();
+	}
+
+	/// Solve A * x = b, where b is a column vector. This is more efficient
+	/// than computing the inverse in one-shot cases.
+	b2Vec3 Solve33(const b2Vec3& b) const;
+
+	/// Solve A * x = b, where b is a column vector. This is more efficient
+	/// than computing the inverse in one-shot cases. Solve only the upper
+	/// 2-by-2 matrix equation.
+	b2Vec2 Solve22(const b2Vec2& b) const;
+
+	/// Get the inverse of this matrix as a 2-by-2.
+	/// Returns the zero matrix if singular.
+	void GetInverse22(b2Mat33* M) const;
+
+	/// Get the symmetric inverse of this matrix as a 3-by-3.
+	/// Returns the zero matrix if singular.
+	void GetSymInverse33(b2Mat33* M) const;
+
+	b2Vec3 ex, ey, ez;
+};
+
+/// Rotation
+struct b2Rot
+{
+	b2Rot() {}
+
+	/// Initialize from an angle in radians
+	explicit b2Rot(float32 angle)
+	{
+		/// TODO_ERIN optimize
+		s = sinf(angle);
+		c = cosf(angle);
+	}
+
+	/// Set using an angle in radians.
+	void Set(float32 angle)
+	{
+		/// TODO_ERIN optimize
+		s = sinf(angle);
+		c = cosf(angle);
+	}
+
+	/// Set to the identity rotation
+	void SetIdentity()
+	{
+		s = 0.0f;
+		c = 1.0f;
+	}
+
+	/// Get the angle in radians
+	float32 GetAngle() const
+	{
+		return b2Atan2(s, c);
+	}
+
+	/// Get the x-axis
+	b2Vec2 GetXAxis() const
+	{
+		return b2Vec2(c, s);
+	}
+
+	/// Get the u-axis
+	b2Vec2 GetYAxis() const
+	{
+		return b2Vec2(-s, c);
+	}
+
+	/// Sine and cosine
+	float32 s, c;
+};
+
+/// A transform contains translation and rotation. It is used to represent
+/// the position and orientation of rigid frames.
+struct b2Transform
+{
+	/// The default constructor does nothing.
+	b2Transform() {}
+
+	/// Initialize using a position vector and a rotation.
+	b2Transform(const b2Vec2& position, const b2Rot& rotation) : p(position), q(rotation) {}
+
+	/// Set this to the identity transform.
+	void SetIdentity()
+	{
+		p.SetZero();
+		q.SetIdentity();
+	}
+
+	/// Set this based on the position and angle.
+	void Set(const b2Vec2& position, float32 angle)
+	{
+		p = position;
+		q.Set(angle);
+	}
+
+	b2Vec2 p;
+	b2Rot q;
+};
+
+/// This describes the motion of a body/shape for TOI computation.
+/// Shapes are defined with respect to the body origin, which may
+/// no coincide with the center of mass. However, to support dynamics
+/// we must interpolate the center of mass position.
+struct b2Sweep
+{
+	/// Get the interpolated transform at a specific time.
+	/// @param beta is a factor in [0,1], where 0 indicates alpha0.
+	void GetTransform(b2Transform* xfb, float32 beta) const;
+
+	/// Advance the sweep forward, yielding a new initial state.
+	/// @param alpha the new initial time.
+	void Advance(float32 alpha);
+
+	/// Normalize the angles.
+	void Normalize();
+
+	b2Vec2 localCenter;	///< local center of mass position
+	b2Vec2 c0, c;		///< center world positions
+	float32 a0, a;		///< world angles
+
+	/// Fraction of the current time step in the range [0,1]
+	/// c0 and a0 are the positions at alpha0.
+	float32 alpha0;
+};
+
+/// Useful constant
+extern const b2Vec2 b2Vec2_zero;
+
+/// Perform the dot product on two vectors.
+inline float32 b2Dot(const b2Vec2& a, const b2Vec2& b)
+{
+	return a.x * b.x + a.y * b.y;
+}
+
+/// Perform the cross product on two vectors. In 2D this produces a scalar.
+inline float32 b2Cross(const b2Vec2& a, const b2Vec2& b)
+{
+	return a.x * b.y - a.y * b.x;
+}
+
+/// Perform the cross product on a vector and a scalar. In 2D this produces
+/// a vector.
+inline b2Vec2 b2Cross(const b2Vec2& a, float32 s)
+{
+	return b2Vec2(s * a.y, -s * a.x);
+}
+
+/// Perform the cross product on a scalar and a vector. In 2D this produces
+/// a vector.
+inline b2Vec2 b2Cross(float32 s, const b2Vec2& a)
+{
+	return b2Vec2(-s * a.y, s * a.x);
+}
+
+/// Multiply a matrix times a vector. If a rotation matrix is provided,
+/// then this transforms the vector from one frame to another.
+inline b2Vec2 b2Mul(const b2Mat22& A, const b2Vec2& v)
+{
+	return b2Vec2(A.ex.x * v.x + A.ey.x * v.y, A.ex.y * v.x + A.ey.y * v.y);
+}
+
+/// Multiply a matrix transpose times a vector. If a rotation matrix is provided,
+/// then this transforms the vector from one frame to another (inverse transform).
+inline b2Vec2 b2MulT(const b2Mat22& A, const b2Vec2& v)
+{
+	return b2Vec2(b2Dot(v, A.ex), b2Dot(v, A.ey));
+}
+
+/// Add two vectors component-wise.
+inline b2Vec2 operator + (const b2Vec2& a, const b2Vec2& b)
+{
+	return b2Vec2(a.x + b.x, a.y + b.y);
+}
+
+/// Subtract two vectors component-wise.
+inline b2Vec2 operator - (const b2Vec2& a, const b2Vec2& b)
+{
+	return b2Vec2(a.x - b.x, a.y - b.y);
+}
+
+inline b2Vec2 operator * (float32 s, const b2Vec2& a)
+{
+	return b2Vec2(s * a.x, s * a.y);
+}
+
+inline bool operator == (const b2Vec2& a, const b2Vec2& b)
+{
+	return a.x == b.x && a.y == b.y;
+}
+
+inline float32 b2Distance(const b2Vec2& a, const b2Vec2& b)
+{
+	b2Vec2 c = a - b;
+	return c.Length();
+}
+
+inline float32 b2DistanceSquared(const b2Vec2& a, const b2Vec2& b)
+{
+	b2Vec2 c = a - b;
+	return b2Dot(c, c);
+}
+
+inline b2Vec3 operator * (float32 s, const b2Vec3& a)
+{
+	return b2Vec3(s * a.x, s * a.y, s * a.z);
+}
+
+/// Add two vectors component-wise.
+inline b2Vec3 operator + (const b2Vec3& a, const b2Vec3& b)
+{
+	return b2Vec3(a.x + b.x, a.y + b.y, a.z + b.z);
+}
+
+/// Subtract two vectors component-wise.
+inline b2Vec3 operator - (const b2Vec3& a, const b2Vec3& b)
+{
+	return b2Vec3(a.x - b.x, a.y - b.y, a.z - b.z);
+}
+
+/// Perform the dot product on two vectors.
+inline float32 b2Dot(const b2Vec3& a, const b2Vec3& b)
+{
+	return a.x * b.x + a.y * b.y + a.z * b.z;
+}
+
+/// Perform the cross product on two vectors.
+inline b2Vec3 b2Cross(const b2Vec3& a, const b2Vec3& b)
+{
+	return b2Vec3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x);
+}
+
+inline b2Mat22 operator + (const b2Mat22& A, const b2Mat22& B)
+{
+	return b2Mat22(A.ex + B.ex, A.ey + B.ey);
+}
+
+// A * B
+inline b2Mat22 b2Mul(const b2Mat22& A, const b2Mat22& B)
+{
+	return b2Mat22(b2Mul(A, B.ex), b2Mul(A, B.ey));
+}
+
+// A^T * B
+inline b2Mat22 b2MulT(const b2Mat22& A, const b2Mat22& B)
+{
+	b2Vec2 c1(b2Dot(A.ex, B.ex), b2Dot(A.ey, B.ex));
+	b2Vec2 c2(b2Dot(A.ex, B.ey), b2Dot(A.ey, B.ey));
+	return b2Mat22(c1, c2);
+}
+
+/// Multiply a matrix times a vector.
+inline b2Vec3 b2Mul(const b2Mat33& A, const b2Vec3& v)
+{
+	return v.x * A.ex + v.y * A.ey + v.z * A.ez;
+}
+
+/// Multiply a matrix times a vector.
+inline b2Vec2 b2Mul22(const b2Mat33& A, const b2Vec2& v)
+{
+	return b2Vec2(A.ex.x * v.x + A.ey.x * v.y, A.ex.y * v.x + A.ey.y * v.y);
+}
+
+/// Multiply two rotations: q * r
+inline b2Rot b2Mul(const b2Rot& q, const b2Rot& r)
+{
+	// [qc -qs] * [rc -rs] = [qc*rc-qs*rs -qc*rs-qs*rc]
+	// [qs  qc]   [rs  rc]   [qs*rc+qc*rs -qs*rs+qc*rc]
+	// s = qs * rc + qc * rs
+	// c = qc * rc - qs * rs
+	b2Rot qr;
+	qr.s = q.s * r.c + q.c * r.s;
+	qr.c = q.c * r.c - q.s * r.s;
+	return qr;
+}
+
+/// Transpose multiply two rotations: qT * r
+inline b2Rot b2MulT(const b2Rot& q, const b2Rot& r)
+{
+	// [ qc qs] * [rc -rs] = [qc*rc+qs*rs -qc*rs+qs*rc]
+	// [-qs qc]   [rs  rc]   [-qs*rc+qc*rs qs*rs+qc*rc]
+	// s = qc * rs - qs * rc
+	// c = qc * rc + qs * rs
+	b2Rot qr;
+	qr.s = q.c * r.s - q.s * r.c;
+	qr.c = q.c * r.c + q.s * r.s;
+	return qr;
+}
+
+/// Rotate a vector
+inline b2Vec2 b2Mul(const b2Rot& q, const b2Vec2& v)
+{
+	return b2Vec2(q.c * v.x - q.s * v.y, q.s * v.x + q.c * v.y);
+}
+
+/// Inverse rotate a vector
+inline b2Vec2 b2MulT(const b2Rot& q, const b2Vec2& v)
+{
+	return b2Vec2(q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y);
+}
+
+inline b2Vec2 b2Mul(const b2Transform& T, const b2Vec2& v)
+{
+	float32 x = (T.q.c * v.x - T.q.s * v.y) + T.p.x;
+	float32 y = (T.q.s * v.x + T.q.c * v.y) + T.p.y;
+
+	return b2Vec2(x, y);
+}
+
+inline b2Vec2 b2MulT(const b2Transform& T, const b2Vec2& v)
+{
+	float32 px = v.x - T.p.x;
+	float32 py = v.y - T.p.y;
+	float32 x = (T.q.c * px + T.q.s * py);
+	float32 y = (-T.q.s * px + T.q.c * py);
+
+	return b2Vec2(x, y);
+}
+
+// v2 = A.q.Rot(B.q.Rot(v1) + B.p) + A.p
+//    = (A.q * B.q).Rot(v1) + A.q.Rot(B.p) + A.p
+inline b2Transform b2Mul(const b2Transform& A, const b2Transform& B)
+{
+	b2Transform C;
+	C.q = b2Mul(A.q, B.q);
+	C.p = b2Mul(A.q, B.p) + A.p;
+	return C;
+}
+
+// v2 = A.q' * (B.q * v1 + B.p - A.p)
+//    = A.q' * B.q * v1 + A.q' * (B.p - A.p)
+inline b2Transform b2MulT(const b2Transform& A, const b2Transform& B)
+{
+	b2Transform C;
+	C.q = b2MulT(A.q, B.q);
+	C.p = b2MulT(A.q, B.p - A.p);
+	return C;
+}
+
+template <typename T>
+inline T b2Abs(T a)
+{
+	return a > T(0) ? a : -a;
+}
+
+inline b2Vec2 b2Abs(const b2Vec2& a)
+{
+	return b2Vec2(b2Abs(a.x), b2Abs(a.y));
+}
+
+inline b2Mat22 b2Abs(const b2Mat22& A)
+{
+	return b2Mat22(b2Abs(A.ex), b2Abs(A.ey));
+}
+
+template <typename T>
+inline T b2Min(T a, T b)
+{
+	return a < b ? a : b;
+}
+
+inline b2Vec2 b2Min(const b2Vec2& a, const b2Vec2& b)
+{
+	return b2Vec2(b2Min(a.x, b.x), b2Min(a.y, b.y));
+}
+
+template <typename T>
+inline T b2Max(T a, T b)
+{
+	return a > b ? a : b;
+}
+
+inline b2Vec2 b2Max(const b2Vec2& a, const b2Vec2& b)
+{
+	return b2Vec2(b2Max(a.x, b.x), b2Max(a.y, b.y));
+}
+
+template <typename T>
+inline T b2Clamp(T a, T low, T high)
+{
+	return b2Max(low, b2Min(a, high));
+}
+
+inline b2Vec2 b2Clamp(const b2Vec2& a, const b2Vec2& low, const b2Vec2& high)
+{
+	return b2Max(low, b2Min(a, high));
+}
+
+template<typename T> inline void b2Swap(T& a, T& b)
+{
+	T tmp = a;
+	a = b;
+	b = tmp;
+}
+
+/// "Next Largest Power of 2
+/// Given a binary integer value x, the next largest power of 2 can be computed by a SWAR algorithm
+/// that recursively "folds" the upper bits into the lower bits. This process yields a bit vector with
+/// the same most significant 1 as x, but all 1's below it. Adding 1 to that value yields the next
+/// largest power of 2. For a 32-bit value:"
+inline uint32 b2NextPowerOfTwo(uint32 x)
+{
+	x |= (x >> 1);
+	x |= (x >> 2);
+	x |= (x >> 4);
+	x |= (x >> 8);
+	x |= (x >> 16);
+	return x + 1;
+}
+
+inline bool b2IsPowerOfTwo(uint32 x)
+{
+	bool result = x > 0 && (x & (x - 1)) == 0;
+	return result;
+}
+
+inline void b2Sweep::GetTransform(b2Transform* xf, float32 beta) const
+{
+	xf->p = (1.0f - beta) * c0 + beta * c;
+	float32 angle = (1.0f - beta) * a0 + beta * a;
+	xf->q.Set(angle);
+
+	// Shift to origin
+	xf->p -= b2Mul(xf->q, localCenter);
+}
+
+inline void b2Sweep::Advance(float32 alpha)
+{
+	b2Assert(alpha0 < 1.0f);
+	float32 beta = (alpha - alpha0) / (1.0f - alpha0);
+	c0 = (1.0f - beta) * c0 + beta * c;
+	a0 = (1.0f - beta) * a0 + beta * a;
+	alpha0 = alpha;
+}
+
+/// Normalize an angle in radians to be between -pi and pi
+inline void b2Sweep::Normalize()
+{
+	float32 twoPi = 2.0f * b2_pi;
+	float32 d =  twoPi * floorf(a0 / twoPi);
+	a0 -= d;
+	a -= d;
+}
+
+#endif

+ 22 - 21
src/modules/physics/box2d/Source/Common/b2Settings.cpp → src/libraries/Box2D/Common/b2Settings.cpp

@@ -1,5 +1,5 @@
 /*
 /*
-* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
 *
 *
 * This software is provided 'as-is', without any express or implied
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * warranty.  In no event will the authors be held liable for any damages
@@ -16,36 +16,37 @@
 * 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.
 */
 */
 
 
-#include "b2Settings.h"
+#include <Box2D/Common/b2Settings.h>
 #include <cstdlib>
 #include <cstdlib>
+#include <cstdio>
+#include <cstdarg>
 
 
-b2Version b2_version = {2, 0, 1};
-
-int32 b2_byteCount = 0;
-
+#include "common/Exception.h"
 
 
+b2Version b2_version = {2, 2, 1};
 
 
 // Memory allocators. Modify these to use your own allocator.
 // Memory allocators. Modify these to use your own allocator.
 void* b2Alloc(int32 size)
 void* b2Alloc(int32 size)
 {
 {
-	size += 4;
-	b2_byteCount += size;
-	char* bytes = (char*)malloc(size);
-	*(int32*)bytes = size;
-	return bytes + 4;
+	return malloc(size);
 }
 }
 
 
 void b2Free(void* mem)
 void b2Free(void* mem)
 {
 {
-	if (mem == NULL)
-	{
-		return;
-	}
+	free(mem);
+}
 
 
-	char* bytes = (char*)mem;
-	bytes -= 4;
-	int32 size = *(int32*)bytes;
-	b2Assert(b2_byteCount >= size);
-	b2_byteCount -= size;
-	free(bytes);
+// You can modify this to use your logging facility.
+void b2Log(const char* string, ...)
+{
+	va_list args;
+	va_start(args, string);
+	vprintf(string, args);
+	va_end(args);
+}
+
+void loveAssert(bool test, const char *teststr)
+{
+	if (!test)
+		throw love::Exception("Box2D error: %s", teststr);
 }
 }

+ 57 - 82
src/modules/physics/box2d/Source/Common/b2Settings.h → src/libraries/Box2D/Common/b2Settings.h

@@ -1,5 +1,5 @@
 /*
 /*
-* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
 *
 *
 * This software is provided 'as-is', without any express or implied
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * warranty.  In no event will the authors be held liable for any damages
@@ -19,23 +19,14 @@
 #ifndef B2_SETTINGS_H
 #ifndef B2_SETTINGS_H
 #define B2_SETTINGS_H
 #define B2_SETTINGS_H
 
 
-#include <assert.h>
-//#include <common/Exception.h>
+#include <cassert>
 #include <cmath>
 #include <cmath>
 
 
-#define B2_NOT_USED(x) x
-#define b2Assert(A) assert(A)
-//#define b2Assert(A) {if(!(A)) throw love::Exception("Box2D error: " #A);}
+void loveAssert(bool test, const char *teststr);
 
 
-
-// need to include NDS jtypes.h instead of
-// usual typedefs because NDS jtypes defines
-// them slightly differently, oh well.
-#ifdef TARGET_IS_NDS
-
-#include "jtypes.h"
-
-#else
+#define B2_NOT_USED(x) ((void)(x))
+//#define b2Assert(A) assert(A)
+#define b2Assert(A) loveAssert((A), #A)
 
 
 typedef signed char	int8;
 typedef signed char	int8;
 typedef signed short int16;
 typedef signed short int16;
@@ -43,114 +34,110 @@ typedef signed int int32;
 typedef unsigned char uint8;
 typedef unsigned char uint8;
 typedef unsigned short uint16;
 typedef unsigned short uint16;
 typedef unsigned int uint32;
 typedef unsigned int uint32;
-
-#endif
-
-#ifdef	TARGET_FLOAT32_IS_FIXED
-
-#include "Fixed.h"
-
-typedef Fixed float32;
-#define	B2_FLT_MAX	FIXED_MAX
-#define	B2_FLT_EPSILON	FIXED_EPSILON
-#define	B2FORCE_SCALE(x)	((x)<<7)
-#define	B2FORCE_INV_SCALE(x)	((x)>>7)
-
-#else
-
 typedef float float32;
 typedef float float32;
-#define	B2_FLT_MAX	FLT_MAX
-#define	B2_FLT_EPSILON	FLT_EPSILON
-#define	B2FORCE_SCALE(x)	(x)
-#define	B2FORCE_INV_SCALE(x)	(x)
-
-#endif
+typedef double float64;
 
 
-const float32 b2_pi = 3.14159265359f;
+#define	b2_maxFloat		FLT_MAX
+#define	b2_epsilon		FLT_EPSILON
+#define b2_pi			3.14159265359f
 
 
 /// @file
 /// @file
 /// Global tuning constants based on meters-kilograms-seconds (MKS) units.
 /// Global tuning constants based on meters-kilograms-seconds (MKS) units.
 ///
 ///
 
 
 // Collision
 // Collision
-const int32 b2_maxManifoldPoints = 2;
-const int32 b2_maxPolygonVertices = 8;
-const int32 b2_maxProxies = 2048;				// this must be a power of two
-const int32 b2_maxPairs = 8 * b2_maxProxies;	// this must be a power of two
 
 
-// Dynamics
+/// The maximum number of contact points between two convex shapes. Do
+/// not change this value.
+#define b2_maxManifoldPoints	2
+
+/// The maximum number of vertices on a convex polygon. You cannot increase
+/// this too much because b2BlockAllocator has a maximum object size.
+#define b2_maxPolygonVertices	8
+
+/// This is used to fatten AABBs in the dynamic tree. This allows proxies
+/// to move by a small amount without triggering a tree adjustment.
+/// This is in meters.
+#define b2_aabbExtension		0.1f
+
+/// This is used to fatten AABBs in the dynamic tree. This is used to predict
+/// the future position based on the current displacement.
+/// This is a dimensionless multiplier.
+#define b2_aabbMultiplier		2.0f
 
 
 /// A small length used as a collision and constraint tolerance. Usually it is
 /// A small length used as a collision and constraint tolerance. Usually it is
 /// chosen to be numerically significant, but visually insignificant.
 /// chosen to be numerically significant, but visually insignificant.
-const float32 b2_linearSlop = 0.005f;	// 0.5 cm
+#define b2_linearSlop			0.005f
 
 
 /// A small angle used as a collision and constraint tolerance. Usually it is
 /// A small angle used as a collision and constraint tolerance. Usually it is
 /// chosen to be numerically significant, but visually insignificant.
 /// chosen to be numerically significant, but visually insignificant.
-const float32 b2_angularSlop = 2.0f / 180.0f * b2_pi;			// 2 degrees
+#define b2_angularSlop			(2.0f / 180.0f * b2_pi)
+
+/// The radius of the polygon/edge shape skin. This should not be modified. Making
+/// this smaller means polygons will have an insufficient buffer for continuous collision.
+/// Making it larger may create artifacts for vertex collision.
+#define b2_polygonRadius		(2.0f * b2_linearSlop)
 
 
-/// Continuous collision detection (CCD) works with core, shrunken shapes. This is the
-/// amount by which shapes are automatically shrunk to work with CCD. This must be
-/// larger than b2_linearSlop.
-const float32 b2_toiSlop = 8.0f * b2_linearSlop;
+/// Maximum number of sub-steps per contact in continuous physics simulation.
+#define b2_maxSubSteps			8
 
 
-/// Maximum number of contacts to be handled to solve a TOI island.
-const int32 b2_maxTOIContactsPerIsland = 32;
+
+// Dynamics
+
+/// Maximum number of contacts to be handled to solve a TOI impact.
+#define b2_maxTOIContacts			32
 
 
 /// A velocity threshold for elastic collisions. Any collision with a relative linear
 /// A velocity threshold for elastic collisions. Any collision with a relative linear
 /// velocity below this threshold will be treated as inelastic.
 /// velocity below this threshold will be treated as inelastic.
-const float32 b2_velocityThreshold = 1.0f;		// 1 m/s
+#define b2_velocityThreshold		1.0f
 
 
 /// The maximum linear position correction used when solving constraints. This helps to
 /// The maximum linear position correction used when solving constraints. This helps to
 /// prevent overshoot.
 /// prevent overshoot.
-const float32 b2_maxLinearCorrection = 0.2f;	// 20 cm
+#define b2_maxLinearCorrection		0.2f
 
 
 /// The maximum angular position correction used when solving constraints. This helps to
 /// The maximum angular position correction used when solving constraints. This helps to
 /// prevent overshoot.
 /// prevent overshoot.
-const float32 b2_maxAngularCorrection = 8.0f / 180.0f * b2_pi;			// 8 degrees
+#define b2_maxAngularCorrection		(8.0f / 180.0f * b2_pi)
 
 
 /// The maximum linear velocity of a body. This limit is very large and is used
 /// The maximum linear velocity of a body. This limit is very large and is used
 /// to prevent numerical problems. You shouldn't need to adjust this.
 /// to prevent numerical problems. You shouldn't need to adjust this.
-#ifdef TARGET_FLOAT32_IS_FIXED
-const float32 b2_maxLinearVelocity = 100.0f;
-#else
-const float32 b2_maxLinearVelocity = 200.0f;
-const float32 b2_maxLinearVelocitySquared = b2_maxLinearVelocity * b2_maxLinearVelocity;
-#endif
+#define b2_maxTranslation			2.0f
+#define b2_maxTranslationSquared	(b2_maxTranslation * b2_maxTranslation)
 
 
 /// The maximum angular velocity of a body. This limit is very large and is used
 /// The maximum angular velocity of a body. This limit is very large and is used
 /// to prevent numerical problems. You shouldn't need to adjust this.
 /// to prevent numerical problems. You shouldn't need to adjust this.
-const float32 b2_maxAngularVelocity = 250.0f;
-#ifndef TARGET_FLOAT32_IS_FIXED
-const float32 b2_maxAngularVelocitySquared = b2_maxAngularVelocity * b2_maxAngularVelocity;
-#endif
+#define b2_maxRotation				(0.5f * b2_pi)
+#define b2_maxRotationSquared		(b2_maxRotation * b2_maxRotation)
 
 
 /// This scale factor controls how fast overlap is resolved. Ideally this would be 1 so
 /// This scale factor controls how fast overlap is resolved. Ideally this would be 1 so
 /// that overlap is removed in one time step. However using values close to 1 often lead
 /// that overlap is removed in one time step. However using values close to 1 often lead
 /// to overshoot.
 /// to overshoot.
-const float32 b2_contactBaumgarte = 0.2f;
+#define b2_baumgarte				0.2f
+#define b2_toiBaugarte				0.75f
+
 
 
 // Sleep
 // Sleep
 
 
 /// The time that a body must be still before it will go to sleep.
 /// The time that a body must be still before it will go to sleep.
-const float32 b2_timeToSleep = 0.5f;									// half a second
+#define b2_timeToSleep				0.5f
 
 
 /// A body cannot sleep if its linear velocity is above this tolerance.
 /// A body cannot sleep if its linear velocity is above this tolerance.
-const float32 b2_linearSleepTolerance = 0.01f;		// 1 cm/s
+#define b2_linearSleepTolerance		0.01f
 
 
 /// A body cannot sleep if its angular velocity is above this tolerance.
 /// A body cannot sleep if its angular velocity is above this tolerance.
-const float32 b2_angularSleepTolerance = 2.0f / 180.0f;		// 2 degrees/s
+#define b2_angularSleepTolerance	(2.0f / 180.0f * b2_pi)
 
 
 // Memory Allocation
 // Memory Allocation
 
 
-/// The current number of bytes allocated through b2Alloc.
-extern int32 b2_byteCount;
-
 /// Implement this function to use your own memory allocator.
 /// Implement this function to use your own memory allocator.
 void* b2Alloc(int32 size);
 void* b2Alloc(int32 size);
 
 
 /// If you implement b2Alloc, you should also implement this function.
 /// If you implement b2Alloc, you should also implement this function.
 void b2Free(void* mem);
 void b2Free(void* mem);
 
 
+/// Logging function.
+void b2Log(const char* string, ...);
+
 /// Version numbering scheme.
 /// Version numbering scheme.
 /// See http://en.wikipedia.org/wiki/Software_versioning
 /// See http://en.wikipedia.org/wiki/Software_versioning
 struct b2Version
 struct b2Version
@@ -163,16 +150,4 @@ struct b2Version
 /// Current version.
 /// Current version.
 extern b2Version b2_version;
 extern b2Version b2_version;
 
 
-/// Friction mixing law. Feel free to customize this.
-inline float32 b2MixFriction(float32 friction1, float32 friction2)
-{
-	return sqrtf(friction1 * friction2);
-}
-
-/// Restitution mixing law. Feel free to customize this.
-inline float32 b2MixRestitution(float32 restitution1, float32 restitution2)
-{
-	return restitution1 > restitution2 ? restitution1 : restitution2;
-}
-
 #endif
 #endif

+ 3 - 3
src/modules/physics/box2d/Source/Common/b2StackAllocator.cpp → src/libraries/Box2D/Common/b2StackAllocator.cpp

@@ -1,5 +1,5 @@
 /*
 /*
-* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
 *
 *
 * This software is provided 'as-is', without any express or implied
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * warranty.  In no event will the authors be held liable for any damages
@@ -16,8 +16,8 @@
 * 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.
 */
 */
 
 
-#include "b2StackAllocator.h"
-#include "b2Math.h"
+#include <Box2D/Common/b2StackAllocator.h>
+#include <Box2D/Common/b2Math.h>
 
 
 b2StackAllocator::b2StackAllocator()
 b2StackAllocator::b2StackAllocator()
 {
 {

+ 2 - 2
src/modules/physics/box2d/Source/Common/b2StackAllocator.h → src/libraries/Box2D/Common/b2StackAllocator.h

@@ -1,5 +1,5 @@
 /*
 /*
-* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
 *
 *
 * This software is provided 'as-is', without any express or implied
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * warranty.  In no event will the authors be held liable for any damages
@@ -19,7 +19,7 @@
 #ifndef B2_STACK_ALLOCATOR_H
 #ifndef B2_STACK_ALLOCATOR_H
 #define B2_STACK_ALLOCATOR_H
 #define B2_STACK_ALLOCATOR_H
 
 
-#include "b2Settings.h"
+#include <Box2D/Common/b2Settings.h>
 
 
 const int32 b2_stackSize = 100 * 1024;	// 100k
 const int32 b2_stackSize = 100 * 1024;	// 100k
 const int32 b2_maxStackEntries = 32;
 const int32 b2_maxStackEntries = 32;

+ 100 - 0
src/libraries/Box2D/Common/b2Timer.cpp

@@ -0,0 +1,100 @@
+/*
+* Copyright (c) 2011 Erin Catto http://box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Common/b2Timer.h>
+
+#if defined(_WIN32)
+
+float64 b2Timer::s_invFrequency = 0.0f;
+
+#include <windows.h>
+
+b2Timer::b2Timer()
+{
+	LARGE_INTEGER largeInteger;
+
+	if (s_invFrequency == 0.0f)
+	{
+		QueryPerformanceFrequency(&largeInteger);
+		s_invFrequency = float64(largeInteger.QuadPart);
+		if (s_invFrequency > 0.0f)
+		{
+			s_invFrequency = 1000.0f / s_invFrequency;
+		}
+	}
+
+	QueryPerformanceCounter(&largeInteger);
+	m_start = float64(largeInteger.QuadPart);
+}
+
+void b2Timer::Reset()
+{
+	LARGE_INTEGER largeInteger;
+	QueryPerformanceCounter(&largeInteger);
+	m_start = float64(largeInteger.QuadPart);
+}
+
+float32 b2Timer::GetMilliseconds() const
+{
+	LARGE_INTEGER largeInteger;
+	QueryPerformanceCounter(&largeInteger);
+	float64 count = float64(largeInteger.QuadPart);
+	float32 ms = float32(s_invFrequency * (count - m_start));
+	return ms;
+}
+
+#elif defined(__linux__) || defined (__APPLE__)
+
+#include <sys/time.h>
+
+b2Timer::b2Timer()
+{
+    Reset();
+}
+
+void b2Timer::Reset()
+{
+    timeval t;
+    gettimeofday(&t, 0);
+    m_start_sec = t.tv_sec;
+    m_start_msec = t.tv_usec * 0.001f;
+}
+
+float32 b2Timer::GetMilliseconds() const
+{
+    timeval t;
+    gettimeofday(&t, 0);
+    return (t.tv_sec - m_start_sec) * 1000 + t.tv_usec * 0.001f - m_start_msec;
+}
+
+#else
+
+b2Timer::b2Timer()
+{
+}
+
+void b2Timer::Reset()
+{
+}
+
+float32 b2Timer::GetMilliseconds() const
+{
+	return 0.0f;
+}
+
+#endif

+ 45 - 0
src/libraries/Box2D/Common/b2Timer.h

@@ -0,0 +1,45 @@
+/*
+* Copyright (c) 2011 Erin Catto http://box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Common/b2Settings.h>
+
+/// Timer for profiling. This has platform specific code and may
+/// not work on every platform.
+class b2Timer
+{
+public:
+
+	/// Constructor
+	b2Timer();
+
+	/// Reset the timer.
+	void Reset();
+
+	/// Get the time since construction or the last reset.
+	float32 GetMilliseconds() const;
+
+private:
+
+#if defined(_WIN32)
+	float64 m_start;
+	static float64 s_invFrequency;
+#elif defined(__linux__) || defined (__APPLE__)
+	unsigned long m_start_sec;
+	unsigned long m_start_msec;
+#endif
+};

+ 54 - 0
src/libraries/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.cpp

@@ -0,0 +1,54 @@
+/*
+* Copyright (c) 2006-2010 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Dynamics/Contacts/b2ChainAndCircleContact.h>
+#include <Box2D/Common/b2BlockAllocator.h>
+#include <Box2D/Dynamics/b2Fixture.h>
+#include <Box2D/Collision/Shapes/b2ChainShape.h>
+#include <Box2D/Collision/Shapes/b2EdgeShape.h>
+
+#include <new>
+using namespace std;
+
+b2Contact* b2ChainAndCircleContact::Create(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator)
+{
+	void* mem = allocator->Allocate(sizeof(b2ChainAndCircleContact));
+	return new (mem) b2ChainAndCircleContact(fixtureA, indexA, fixtureB, indexB);
+}
+
+void b2ChainAndCircleContact::Destroy(b2Contact* contact, b2BlockAllocator* allocator)
+{
+	((b2ChainAndCircleContact*)contact)->~b2ChainAndCircleContact();
+	allocator->Free(contact, sizeof(b2ChainAndCircleContact));
+}
+
+b2ChainAndCircleContact::b2ChainAndCircleContact(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB)
+: b2Contact(fixtureA, indexA, fixtureB, indexB)
+{
+	b2Assert(m_fixtureA->GetType() == b2Shape::e_chain);
+	b2Assert(m_fixtureB->GetType() == b2Shape::e_circle);
+}
+
+void b2ChainAndCircleContact::Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB)
+{
+	b2ChainShape* chain = (b2ChainShape*)m_fixtureA->GetShape();
+	b2EdgeShape edge;
+	chain->GetChildEdge(&edge, m_indexA);
+	b2CollideEdgeAndCircle(	manifold, &edge, xfA,
+							(b2CircleShape*)m_fixtureB->GetShape(), xfB);
+}

+ 39 - 0
src/libraries/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.h

@@ -0,0 +1,39 @@
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef B2_CHAIN_AND_CIRCLE_CONTACT_H
+#define B2_CHAIN_AND_CIRCLE_CONTACT_H
+
+#include <Box2D/Dynamics/Contacts/b2Contact.h>
+
+class b2BlockAllocator;
+
+class b2ChainAndCircleContact : public b2Contact
+{
+public:
+	static b2Contact* Create(	b2Fixture* fixtureA, int32 indexA,
+								b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator);
+	static void Destroy(b2Contact* contact, b2BlockAllocator* allocator);
+
+	b2ChainAndCircleContact(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB);
+	~b2ChainAndCircleContact() {}
+
+	void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB);
+};
+
+#endif

+ 54 - 0
src/libraries/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.cpp

@@ -0,0 +1,54 @@
+/*
+* Copyright (c) 2006-2010 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.h>
+#include <Box2D/Common/b2BlockAllocator.h>
+#include <Box2D/Dynamics/b2Fixture.h>
+#include <Box2D/Collision/Shapes/b2ChainShape.h>
+#include <Box2D/Collision/Shapes/b2EdgeShape.h>
+
+#include <new>
+using namespace std;
+
+b2Contact* b2ChainAndPolygonContact::Create(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator)
+{
+	void* mem = allocator->Allocate(sizeof(b2ChainAndPolygonContact));
+	return new (mem) b2ChainAndPolygonContact(fixtureA, indexA, fixtureB, indexB);
+}
+
+void b2ChainAndPolygonContact::Destroy(b2Contact* contact, b2BlockAllocator* allocator)
+{
+	((b2ChainAndPolygonContact*)contact)->~b2ChainAndPolygonContact();
+	allocator->Free(contact, sizeof(b2ChainAndPolygonContact));
+}
+
+b2ChainAndPolygonContact::b2ChainAndPolygonContact(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB)
+: b2Contact(fixtureA, indexA, fixtureB, indexB)
+{
+	b2Assert(m_fixtureA->GetType() == b2Shape::e_chain);
+	b2Assert(m_fixtureB->GetType() == b2Shape::e_polygon);
+}
+
+void b2ChainAndPolygonContact::Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB)
+{
+	b2ChainShape* chain = (b2ChainShape*)m_fixtureA->GetShape();
+	b2EdgeShape edge;
+	chain->GetChildEdge(&edge, m_indexA);
+	b2CollideEdgeAndPolygon(	manifold, &edge, xfA,
+								(b2PolygonShape*)m_fixtureB->GetShape(), xfB);
+}

+ 39 - 0
src/libraries/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.h

@@ -0,0 +1,39 @@
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef B2_CHAIN_AND_POLYGON_CONTACT_H
+#define B2_CHAIN_AND_POLYGON_CONTACT_H
+
+#include <Box2D/Dynamics/Contacts/b2Contact.h>
+
+class b2BlockAllocator;
+
+class b2ChainAndPolygonContact : public b2Contact
+{
+public:
+	static b2Contact* Create(	b2Fixture* fixtureA, int32 indexA,
+								b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator);
+	static void Destroy(b2Contact* contact, b2BlockAllocator* allocator);
+
+	b2ChainAndPolygonContact(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB);
+	~b2ChainAndPolygonContact() {}
+
+	void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB);
+};
+
+#endif

+ 53 - 0
src/libraries/Box2D/Dynamics/Contacts/b2CircleContact.cpp

@@ -0,0 +1,53 @@
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Dynamics/Contacts/b2CircleContact.h>
+#include <Box2D/Dynamics/b2Body.h>
+#include <Box2D/Dynamics/b2Fixture.h>
+#include <Box2D/Dynamics/b2WorldCallbacks.h>
+#include <Box2D/Common/b2BlockAllocator.h>
+#include <Box2D/Collision/b2TimeOfImpact.h>
+
+#include <new>
+using namespace std;
+
+b2Contact* b2CircleContact::Create(b2Fixture* fixtureA, int32, b2Fixture* fixtureB, int32, b2BlockAllocator* allocator)
+{
+	void* mem = allocator->Allocate(sizeof(b2CircleContact));
+	return new (mem) b2CircleContact(fixtureA, fixtureB);
+}
+
+void b2CircleContact::Destroy(b2Contact* contact, b2BlockAllocator* allocator)
+{
+	((b2CircleContact*)contact)->~b2CircleContact();
+	allocator->Free(contact, sizeof(b2CircleContact));
+}
+
+b2CircleContact::b2CircleContact(b2Fixture* fixtureA, b2Fixture* fixtureB)
+	: b2Contact(fixtureA, 0, fixtureB, 0)
+{
+	b2Assert(m_fixtureA->GetType() == b2Shape::e_circle);
+	b2Assert(m_fixtureB->GetType() == b2Shape::e_circle);
+}
+
+void b2CircleContact::Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB)
+{
+	b2CollideCircles(manifold,
+					(b2CircleShape*)m_fixtureA->GetShape(), xfA,
+					(b2CircleShape*)m_fixtureB->GetShape(), xfB);
+}

+ 8 - 15
src/modules/physics/box2d/Source/Dynamics/Contacts/b2CircleContact.h → src/libraries/Box2D/Dynamics/Contacts/b2CircleContact.h

@@ -1,5 +1,5 @@
 /*
 /*
-* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
 *
 *
 * This software is provided 'as-is', without any express or implied
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * warranty.  In no event will the authors be held liable for any damages
@@ -16,31 +16,24 @@
 * 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.
 */
 */
 
 
-#ifndef CIRCLE_CONTACT_H
-#define CIRCLE_CONTACT_H
+#ifndef B2_CIRCLE_CONTACT_H
+#define B2_CIRCLE_CONTACT_H
 
 
-#include "../../Common/b2Math.h"
-#include "../../Collision/b2Collision.h"
-#include "b2Contact.h"
+#include <Box2D/Dynamics/Contacts/b2Contact.h>
 
 
 class b2BlockAllocator;
 class b2BlockAllocator;
 
 
 class b2CircleContact : public b2Contact
 class b2CircleContact : public b2Contact
 {
 {
 public:
 public:
-	static b2Contact* Create(b2Shape* shape1, b2Shape* shape2, b2BlockAllocator* allocator);
+	static b2Contact* Create(	b2Fixture* fixtureA, int32 indexA,
+								b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator);
 	static void Destroy(b2Contact* contact, b2BlockAllocator* allocator);
 	static void Destroy(b2Contact* contact, b2BlockAllocator* allocator);
 
 
-	b2CircleContact(b2Shape* shape1, b2Shape* shape2);
+	b2CircleContact(b2Fixture* fixtureA, b2Fixture* fixtureB);
 	~b2CircleContact() {}
 	~b2CircleContact() {}
 
 
-	void Evaluate(b2ContactListener* listener);
-	b2Manifold* GetManifolds()
-	{
-		return &m_manifold;
-	}
-
-	b2Manifold m_manifold;
+	void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB);
 };
 };
 
 
 #endif
 #endif

+ 240 - 0
src/libraries/Box2D/Dynamics/Contacts/b2Contact.cpp

@@ -0,0 +1,240 @@
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Dynamics/Contacts/b2Contact.h>
+#include <Box2D/Dynamics/Contacts/b2CircleContact.h>
+#include <Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.h>
+#include <Box2D/Dynamics/Contacts/b2PolygonContact.h>
+#include <Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.h>
+#include <Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.h>
+#include <Box2D/Dynamics/Contacts/b2ChainAndCircleContact.h>
+#include <Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.h>
+#include <Box2D/Dynamics/Contacts/b2ContactSolver.h>
+
+#include <Box2D/Collision/b2Collision.h>
+#include <Box2D/Collision/b2TimeOfImpact.h>
+#include <Box2D/Collision/Shapes/b2Shape.h>
+#include <Box2D/Common/b2BlockAllocator.h>
+#include <Box2D/Dynamics/b2Body.h>
+#include <Box2D/Dynamics/b2Fixture.h>
+#include <Box2D/Dynamics/b2World.h>
+
+b2ContactRegister b2Contact::s_registers[b2Shape::e_typeCount][b2Shape::e_typeCount];
+bool b2Contact::s_initialized = false;
+
+void b2Contact::InitializeRegisters()
+{
+	AddType(b2CircleContact::Create, b2CircleContact::Destroy, b2Shape::e_circle, b2Shape::e_circle);
+	AddType(b2PolygonAndCircleContact::Create, b2PolygonAndCircleContact::Destroy, b2Shape::e_polygon, b2Shape::e_circle);
+	AddType(b2PolygonContact::Create, b2PolygonContact::Destroy, b2Shape::e_polygon, b2Shape::e_polygon);
+	AddType(b2EdgeAndCircleContact::Create, b2EdgeAndCircleContact::Destroy, b2Shape::e_edge, b2Shape::e_circle);
+	AddType(b2EdgeAndPolygonContact::Create, b2EdgeAndPolygonContact::Destroy, b2Shape::e_edge, b2Shape::e_polygon);
+	AddType(b2ChainAndCircleContact::Create, b2ChainAndCircleContact::Destroy, b2Shape::e_chain, b2Shape::e_circle);
+	AddType(b2ChainAndPolygonContact::Create, b2ChainAndPolygonContact::Destroy, b2Shape::e_chain, b2Shape::e_polygon);
+}
+
+void b2Contact::AddType(b2ContactCreateFcn* createFcn, b2ContactDestroyFcn* destoryFcn,
+						b2Shape::Type type1, b2Shape::Type type2)
+{
+	b2Assert(0 <= type1 && type1 < b2Shape::e_typeCount);
+	b2Assert(0 <= type2 && type2 < b2Shape::e_typeCount);
+	
+	s_registers[type1][type2].createFcn = createFcn;
+	s_registers[type1][type2].destroyFcn = destoryFcn;
+	s_registers[type1][type2].primary = true;
+
+	if (type1 != type2)
+	{
+		s_registers[type2][type1].createFcn = createFcn;
+		s_registers[type2][type1].destroyFcn = destoryFcn;
+		s_registers[type2][type1].primary = false;
+	}
+}
+
+b2Contact* b2Contact::Create(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator)
+{
+	if (s_initialized == false)
+	{
+		InitializeRegisters();
+		s_initialized = true;
+	}
+
+	b2Shape::Type type1 = fixtureA->GetType();
+	b2Shape::Type type2 = fixtureB->GetType();
+
+	b2Assert(0 <= type1 && type1 < b2Shape::e_typeCount);
+	b2Assert(0 <= type2 && type2 < b2Shape::e_typeCount);
+	
+	b2ContactCreateFcn* createFcn = s_registers[type1][type2].createFcn;
+	if (createFcn)
+	{
+		if (s_registers[type1][type2].primary)
+		{
+			return createFcn(fixtureA, indexA, fixtureB, indexB, allocator);
+		}
+		else
+		{
+			return createFcn(fixtureB, indexB, fixtureA, indexA, allocator);
+		}
+	}
+	else
+	{
+		return NULL;
+	}
+}
+
+void b2Contact::Destroy(b2Contact* contact, b2BlockAllocator* allocator)
+{
+	b2Assert(s_initialized == true);
+
+	if (contact->m_manifold.pointCount > 0)
+	{
+		contact->GetFixtureA()->GetBody()->SetAwake(true);
+		contact->GetFixtureB()->GetBody()->SetAwake(true);
+	}
+
+	b2Shape::Type typeA = contact->GetFixtureA()->GetType();
+	b2Shape::Type typeB = contact->GetFixtureB()->GetType();
+
+	b2Assert(0 <= typeA && typeB < b2Shape::e_typeCount);
+	b2Assert(0 <= typeA && typeB < b2Shape::e_typeCount);
+
+	b2ContactDestroyFcn* destroyFcn = s_registers[typeA][typeB].destroyFcn;
+	destroyFcn(contact, allocator);
+}
+
+b2Contact::b2Contact(b2Fixture* fA, int32 indexA, b2Fixture* fB, int32 indexB)
+{
+	m_flags = e_enabledFlag;
+
+	m_fixtureA = fA;
+	m_fixtureB = fB;
+
+	m_indexA = indexA;
+	m_indexB = indexB;
+
+	m_manifold.pointCount = 0;
+
+	m_prev = NULL;
+	m_next = NULL;
+
+	m_nodeA.contact = NULL;
+	m_nodeA.prev = NULL;
+	m_nodeA.next = NULL;
+	m_nodeA.other = NULL;
+
+	m_nodeB.contact = NULL;
+	m_nodeB.prev = NULL;
+	m_nodeB.next = NULL;
+	m_nodeB.other = NULL;
+
+	m_toiCount = 0;
+
+	m_friction = b2MixFriction(m_fixtureA->m_friction, m_fixtureB->m_friction);
+	m_restitution = b2MixRestitution(m_fixtureA->m_restitution, m_fixtureB->m_restitution);
+}
+
+// Update the contact manifold and touching status.
+// Note: do not assume the fixture AABBs are overlapping or are valid.
+void b2Contact::Update(b2ContactListener* listener)
+{
+	b2Manifold oldManifold = m_manifold;
+
+	// Re-enable this contact.
+	m_flags |= e_enabledFlag;
+
+	bool touching = false;
+	bool wasTouching = (m_flags & e_touchingFlag) == e_touchingFlag;
+
+	bool sensorA = m_fixtureA->IsSensor();
+	bool sensorB = m_fixtureB->IsSensor();
+	bool sensor = sensorA || sensorB;
+
+	b2Body* bodyA = m_fixtureA->GetBody();
+	b2Body* bodyB = m_fixtureB->GetBody();
+	const b2Transform& xfA = bodyA->GetTransform();
+	const b2Transform& xfB = bodyB->GetTransform();
+
+	// Is this contact a sensor?
+	if (sensor)
+	{
+		const b2Shape* shapeA = m_fixtureA->GetShape();
+		const b2Shape* shapeB = m_fixtureB->GetShape();
+		touching = b2TestOverlap(shapeA, m_indexA, shapeB, m_indexB, xfA, xfB);
+
+		// Sensors don't generate manifolds.
+		m_manifold.pointCount = 0;
+	}
+	else
+	{
+		Evaluate(&m_manifold, xfA, xfB);
+		touching = m_manifold.pointCount > 0;
+
+		// Match old contact ids to new contact ids and copy the
+		// stored impulses to warm start the solver.
+		for (int32 i = 0; i < m_manifold.pointCount; ++i)
+		{
+			b2ManifoldPoint* mp2 = m_manifold.points + i;
+			mp2->normalImpulse = 0.0f;
+			mp2->tangentImpulse = 0.0f;
+			b2ContactID id2 = mp2->id;
+
+			for (int32 j = 0; j < oldManifold.pointCount; ++j)
+			{
+				b2ManifoldPoint* mp1 = oldManifold.points + j;
+
+				if (mp1->id.key == id2.key)
+				{
+					mp2->normalImpulse = mp1->normalImpulse;
+					mp2->tangentImpulse = mp1->tangentImpulse;
+					break;
+				}
+			}
+		}
+
+		if (touching != wasTouching)
+		{
+			bodyA->SetAwake(true);
+			bodyB->SetAwake(true);
+		}
+	}
+
+	if (touching)
+	{
+		m_flags |= e_touchingFlag;
+	}
+	else
+	{
+		m_flags &= ~e_touchingFlag;
+	}
+
+	if (wasTouching == false && touching == true && listener)
+	{
+		listener->BeginContact(this);
+	}
+
+	if (wasTouching == true && touching == false && listener)
+	{
+		listener->EndContact(this);
+	}
+
+	if (sensor == false && touching && listener)
+	{
+		listener->PreSolve(this, &oldManifold);
+	}
+}

+ 331 - 0
src/libraries/Box2D/Dynamics/Contacts/b2Contact.h

@@ -0,0 +1,331 @@
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef B2_CONTACT_H
+#define B2_CONTACT_H
+
+#include <Box2D/Common/b2Math.h>
+#include <Box2D/Collision/b2Collision.h>
+#include <Box2D/Collision/Shapes/b2Shape.h>
+#include <Box2D/Dynamics/b2Fixture.h>
+
+class b2Body;
+class b2Contact;
+class b2Fixture;
+class b2World;
+class b2BlockAllocator;
+class b2StackAllocator;
+class b2ContactListener;
+
+/// Friction mixing law. The idea is to allow either fixture to drive the restitution to zero.
+/// For example, anything slides on ice.
+inline float32 b2MixFriction(float32 friction1, float32 friction2)
+{
+	return std::sqrt(friction1 * friction2);
+}
+
+/// Restitution mixing law. The idea is allow for anything to bounce off an inelastic surface.
+/// For example, a superball bounces on anything.
+inline float32 b2MixRestitution(float32 restitution1, float32 restitution2)
+{
+	return restitution1 > restitution2 ? restitution1 : restitution2;
+}
+
+typedef b2Contact* b2ContactCreateFcn(	b2Fixture* fixtureA, int32 indexA,
+										b2Fixture* fixtureB, int32 indexB,
+										b2BlockAllocator* allocator);
+typedef void b2ContactDestroyFcn(b2Contact* contact, b2BlockAllocator* allocator);
+
+struct b2ContactRegister
+{
+	b2ContactCreateFcn* createFcn;
+	b2ContactDestroyFcn* destroyFcn;
+	bool primary;
+};
+
+/// A contact edge is used to connect bodies and contacts together
+/// in a contact graph where each body is a node and each contact
+/// is an edge. A contact edge belongs to a doubly linked list
+/// maintained in each attached body. Each contact has two contact
+/// nodes, one for each attached body.
+struct b2ContactEdge
+{
+	b2Body* other;			///< provides quick access to the other body attached.
+	b2Contact* contact;		///< the contact
+	b2ContactEdge* prev;	///< the previous contact edge in the body's contact list
+	b2ContactEdge* next;	///< the next contact edge in the body's contact list
+};
+
+/// The class manages contact between two shapes. A contact exists for each overlapping
+/// AABB in the broad-phase (except if filtered). Therefore a contact object may exist
+/// that has no contact points.
+class b2Contact
+{
+public:
+
+	/// Get the contact manifold. Do not modify the manifold unless you understand the
+	/// internals of Box2D.
+	b2Manifold* GetManifold();
+	const b2Manifold* GetManifold() const;
+
+	/// Get the world manifold.
+	void GetWorldManifold(b2WorldManifold* worldManifold) const;
+
+	/// Is this contact touching?
+	bool IsTouching() const;
+
+	/// Enable/disable this contact. This can be used inside the pre-solve
+	/// contact listener. The contact is only disabled for the current
+	/// time step (or sub-step in continuous collisions).
+	void SetEnabled(bool flag);
+
+	/// Has this contact been disabled?
+	bool IsEnabled() const;
+
+	/// Get the next contact in the world's contact list.
+	b2Contact* GetNext();
+	const b2Contact* GetNext() const;
+
+	/// Get fixture A in this contact.
+	b2Fixture* GetFixtureA();
+	const b2Fixture* GetFixtureA() const;
+
+	/// Get the child primitive index for fixture A.
+	int32 GetChildIndexA() const;
+
+	/// Get fixture B in this contact.
+	b2Fixture* GetFixtureB();
+	const b2Fixture* GetFixtureB() const;
+
+	/// Get the child primitive index for fixture B.
+	int32 GetChildIndexB() const;
+
+	/// Override the default friction mixture. You can call this in b2ContactListener::PreSolve.
+	/// This value persists until set or reset.
+	void SetFriction(float32 friction);
+
+	/// Get the friction.
+	float32 GetFriction() const;
+
+	/// Reset the friction mixture to the default value.
+	void ResetFriction();
+
+	/// Override the default restitution mixture. You can call this in b2ContactListener::PreSolve.
+	/// The value persists until you set or reset.
+	void SetRestitution(float32 restitution);
+
+	/// Get the restitution.
+	float32 GetRestitution() const;
+
+	/// Reset the restitution to the default value.
+	void ResetRestitution();
+
+	/// Evaluate this contact with your own manifold and transforms.
+	virtual void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) = 0;
+
+protected:
+	friend class b2ContactManager;
+	friend class b2World;
+	friend class b2ContactSolver;
+	friend class b2Body;
+	friend class b2Fixture;
+
+	// Flags stored in m_flags
+	enum
+	{
+		// Used when crawling contact graph when forming islands.
+		e_islandFlag		= 0x0001,
+
+        // Set when the shapes are touching.
+		e_touchingFlag		= 0x0002,
+
+		// This contact can be disabled (by user)
+		e_enabledFlag		= 0x0004,
+
+		// This contact needs filtering because a fixture filter was changed.
+		e_filterFlag		= 0x0008,
+
+		// This bullet contact had a TOI event
+		e_bulletHitFlag		= 0x0010,
+
+		// This contact has a valid TOI in m_toi
+		e_toiFlag			= 0x0020
+	};
+
+	/// Flag this contact for filtering. Filtering will occur the next time step.
+	void FlagForFiltering();
+
+	static void AddType(b2ContactCreateFcn* createFcn, b2ContactDestroyFcn* destroyFcn,
+						b2Shape::Type typeA, b2Shape::Type typeB);
+	static void InitializeRegisters();
+	static b2Contact* Create(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator);
+	static void Destroy(b2Contact* contact, b2Shape::Type typeA, b2Shape::Type typeB, b2BlockAllocator* allocator);
+	static void Destroy(b2Contact* contact, b2BlockAllocator* allocator);
+
+	b2Contact() : m_fixtureA(NULL), m_fixtureB(NULL) {}
+	b2Contact(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB);
+	virtual ~b2Contact() {}
+
+	void Update(b2ContactListener* listener);
+
+	static b2ContactRegister s_registers[b2Shape::e_typeCount][b2Shape::e_typeCount];
+	static bool s_initialized;
+
+	uint32 m_flags;
+
+	// World pool and list pointers.
+	b2Contact* m_prev;
+	b2Contact* m_next;
+
+	// Nodes for connecting bodies.
+	b2ContactEdge m_nodeA;
+	b2ContactEdge m_nodeB;
+
+	b2Fixture* m_fixtureA;
+	b2Fixture* m_fixtureB;
+
+	int32 m_indexA;
+	int32 m_indexB;
+
+	b2Manifold m_manifold;
+
+	int32 m_toiCount;
+	float32 m_toi;
+
+	float32 m_friction;
+	float32 m_restitution;
+};
+
+inline b2Manifold* b2Contact::GetManifold()
+{
+	return &m_manifold;
+}
+
+inline const b2Manifold* b2Contact::GetManifold() const
+{
+	return &m_manifold;
+}
+
+inline void b2Contact::GetWorldManifold(b2WorldManifold* worldManifold) const
+{
+	const b2Body* bodyA = m_fixtureA->GetBody();
+	const b2Body* bodyB = m_fixtureB->GetBody();
+	const b2Shape* shapeA = m_fixtureA->GetShape();
+	const b2Shape* shapeB = m_fixtureB->GetShape();
+
+	worldManifold->Initialize(&m_manifold, bodyA->GetTransform(), shapeA->m_radius, bodyB->GetTransform(), shapeB->m_radius);
+}
+
+inline void b2Contact::SetEnabled(bool flag)
+{
+	if (flag)
+	{
+		m_flags |= e_enabledFlag;
+	}
+	else
+	{
+		m_flags &= ~e_enabledFlag;
+	}
+}
+
+inline bool b2Contact::IsEnabled() const
+{
+	return (m_flags & e_enabledFlag) == e_enabledFlag;
+}
+
+inline bool b2Contact::IsTouching() const
+{
+	return (m_flags & e_touchingFlag) == e_touchingFlag;
+}
+
+inline b2Contact* b2Contact::GetNext()
+{
+	return m_next;
+}
+
+inline const b2Contact* b2Contact::GetNext() const
+{
+	return m_next;
+}
+
+inline b2Fixture* b2Contact::GetFixtureA()
+{
+	return m_fixtureA;
+}
+
+inline const b2Fixture* b2Contact::GetFixtureA() const
+{
+	return m_fixtureA;
+}
+
+inline b2Fixture* b2Contact::GetFixtureB()
+{
+	return m_fixtureB;
+}
+
+inline int32 b2Contact::GetChildIndexA() const
+{
+	return m_indexA;
+}
+
+inline const b2Fixture* b2Contact::GetFixtureB() const
+{
+	return m_fixtureB;
+}
+
+inline int32 b2Contact::GetChildIndexB() const
+{
+	return m_indexB;
+}
+
+inline void b2Contact::FlagForFiltering()
+{
+	m_flags |= e_filterFlag;
+}
+
+inline void b2Contact::SetFriction(float32 friction)
+{
+	m_friction = friction;
+}
+
+inline float32 b2Contact::GetFriction() const
+{
+	return m_friction;
+}
+
+inline void b2Contact::ResetFriction()
+{
+	m_friction = b2MixFriction(m_fixtureA->m_friction, m_fixtureB->m_friction);
+}
+
+inline void b2Contact::SetRestitution(float32 restitution)
+{
+	m_restitution = restitution;
+}
+
+inline float32 b2Contact::GetRestitution() const
+{
+	return m_restitution;
+}
+
+inline void b2Contact::ResetRestitution()
+{
+	m_restitution = b2MixRestitution(m_fixtureA->m_restitution, m_fixtureB->m_restitution);
+}
+
+#endif

+ 832 - 0
src/libraries/Box2D/Dynamics/Contacts/b2ContactSolver.cpp

@@ -0,0 +1,832 @@
+/*
+* Copyright (c) 2006-2011 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Dynamics/Contacts/b2ContactSolver.h>
+
+#include <Box2D/Dynamics/Contacts/b2Contact.h>
+#include <Box2D/Dynamics/b2Body.h>
+#include <Box2D/Dynamics/b2Fixture.h>
+#include <Box2D/Dynamics/b2World.h>
+#include <Box2D/Common/b2StackAllocator.h>
+
+#define B2_DEBUG_SOLVER 0
+
+struct b2ContactPositionConstraint
+{
+	b2Vec2 localPoints[b2_maxManifoldPoints];
+	b2Vec2 localNormal;
+	b2Vec2 localPoint;
+	int32 indexA;
+	int32 indexB;
+	float32 invMassA, invMassB;
+	b2Vec2 localCenterA, localCenterB;
+	float32 invIA, invIB;
+	b2Manifold::Type type;
+	float32 radiusA, radiusB;
+	int32 pointCount;
+};
+
+b2ContactSolver::b2ContactSolver(b2ContactSolverDef* def)
+{
+	m_step = def->step;
+	m_allocator = def->allocator;
+	m_count = def->count;
+	m_positionConstraints = (b2ContactPositionConstraint*)m_allocator->Allocate(m_count * sizeof(b2ContactPositionConstraint));
+	m_velocityConstraints = (b2ContactVelocityConstraint*)m_allocator->Allocate(m_count * sizeof(b2ContactVelocityConstraint));
+	m_positions = def->positions;
+	m_velocities = def->velocities;
+	m_contacts = def->contacts;
+
+	// Initialize position independent portions of the constraints.
+	for (int32 i = 0; i < m_count; ++i)
+	{
+		b2Contact* contact = m_contacts[i];
+
+		b2Fixture* fixtureA = contact->m_fixtureA;
+		b2Fixture* fixtureB = contact->m_fixtureB;
+		b2Shape* shapeA = fixtureA->GetShape();
+		b2Shape* shapeB = fixtureB->GetShape();
+		float32 radiusA = shapeA->m_radius;
+		float32 radiusB = shapeB->m_radius;
+		b2Body* bodyA = fixtureA->GetBody();
+		b2Body* bodyB = fixtureB->GetBody();
+		b2Manifold* manifold = contact->GetManifold();
+
+		int32 pointCount = manifold->pointCount;
+		b2Assert(pointCount > 0);
+
+		b2ContactVelocityConstraint* vc = m_velocityConstraints + i;
+		vc->friction = contact->m_friction;
+		vc->restitution = contact->m_restitution;
+		vc->indexA = bodyA->m_islandIndex;
+		vc->indexB = bodyB->m_islandIndex;
+		vc->invMassA = bodyA->m_invMass;
+		vc->invMassB = bodyB->m_invMass;
+		vc->invIA = bodyA->m_invI;
+		vc->invIB = bodyB->m_invI;
+		vc->contactIndex = i;
+		vc->pointCount = pointCount;
+		vc->K.SetZero();
+		vc->normalMass.SetZero();
+
+		b2ContactPositionConstraint* pc = m_positionConstraints + i;
+		pc->indexA = bodyA->m_islandIndex;
+		pc->indexB = bodyB->m_islandIndex;
+		pc->invMassA = bodyA->m_invMass;
+		pc->invMassB = bodyB->m_invMass;
+		pc->localCenterA = bodyA->m_sweep.localCenter;
+		pc->localCenterB = bodyB->m_sweep.localCenter;
+		pc->invIA = bodyA->m_invI;
+		pc->invIB = bodyB->m_invI;
+		pc->localNormal = manifold->localNormal;
+		pc->localPoint = manifold->localPoint;
+		pc->pointCount = pointCount;
+		pc->radiusA = radiusA;
+		pc->radiusB = radiusB;
+		pc->type = manifold->type;
+
+		for (int32 j = 0; j < pointCount; ++j)
+		{
+			b2ManifoldPoint* cp = manifold->points + j;
+			b2VelocityConstraintPoint* vcp = vc->points + j;
+	
+			if (m_step.warmStarting)
+			{
+				vcp->normalImpulse = m_step.dtRatio * cp->normalImpulse;
+				vcp->tangentImpulse = m_step.dtRatio * cp->tangentImpulse;
+			}
+			else
+			{
+				vcp->normalImpulse = 0.0f;
+				vcp->tangentImpulse = 0.0f;
+			}
+
+			vcp->rA.SetZero();
+			vcp->rB.SetZero();
+			vcp->normalMass = 0.0f;
+			vcp->tangentMass = 0.0f;
+			vcp->velocityBias = 0.0f;
+
+			pc->localPoints[j] = cp->localPoint;
+		}
+	}
+}
+
+b2ContactSolver::~b2ContactSolver()
+{
+	m_allocator->Free(m_velocityConstraints);
+	m_allocator->Free(m_positionConstraints);
+}
+
+// Initialize position dependent portions of the velocity constraints.
+void b2ContactSolver::InitializeVelocityConstraints()
+{
+	for (int32 i = 0; i < m_count; ++i)
+	{
+		b2ContactVelocityConstraint* vc = m_velocityConstraints + i;
+		b2ContactPositionConstraint* pc = m_positionConstraints + i;
+
+		float32 radiusA = pc->radiusA;
+		float32 radiusB = pc->radiusB;
+		b2Manifold* manifold = m_contacts[vc->contactIndex]->GetManifold();
+
+		int32 indexA = vc->indexA;
+		int32 indexB = vc->indexB;
+
+		float32 mA = vc->invMassA;
+		float32 mB = vc->invMassB;
+		float32 iA = vc->invIA;
+		float32 iB = vc->invIB;
+		b2Vec2 localCenterA = pc->localCenterA;
+		b2Vec2 localCenterB = pc->localCenterB;
+
+		b2Vec2 cA = m_positions[indexA].c;
+		float32 aA = m_positions[indexA].a;
+		b2Vec2 vA = m_velocities[indexA].v;
+		float32 wA = m_velocities[indexA].w;
+
+		b2Vec2 cB = m_positions[indexB].c;
+		float32 aB = m_positions[indexB].a;
+		b2Vec2 vB = m_velocities[indexB].v;
+		float32 wB = m_velocities[indexB].w;
+
+		b2Assert(manifold->pointCount > 0);
+
+		b2Transform xfA, xfB;
+		xfA.q.Set(aA);
+		xfB.q.Set(aB);
+		xfA.p = cA - b2Mul(xfA.q, localCenterA);
+		xfB.p = cB - b2Mul(xfB.q, localCenterB);
+
+		b2WorldManifold worldManifold;
+		worldManifold.Initialize(manifold, xfA, radiusA, xfB, radiusB);
+
+		vc->normal = worldManifold.normal;
+
+		int32 pointCount = vc->pointCount;
+		for (int32 j = 0; j < pointCount; ++j)
+		{
+			b2VelocityConstraintPoint* vcp = vc->points + j;
+
+			vcp->rA = worldManifold.points[j] - cA;
+			vcp->rB = worldManifold.points[j] - cB;
+
+			float32 rnA = b2Cross(vcp->rA, vc->normal);
+			float32 rnB = b2Cross(vcp->rB, vc->normal);
+
+			float32 kNormal = mA + mB + iA * rnA * rnA + iB * rnB * rnB;
+
+			vcp->normalMass = kNormal > 0.0f ? 1.0f / kNormal : 0.0f;
+
+			b2Vec2 tangent = b2Cross(vc->normal, 1.0f);
+
+			float32 rtA = b2Cross(vcp->rA, tangent);
+			float32 rtB = b2Cross(vcp->rB, tangent);
+
+			float32 kTangent = mA + mB + iA * rtA * rtA + iB * rtB * rtB;
+
+			vcp->tangentMass = kTangent > 0.0f ? 1.0f /  kTangent : 0.0f;
+
+			// Setup a velocity bias for restitution.
+			vcp->velocityBias = 0.0f;
+			float32 vRel = b2Dot(vc->normal, vB + b2Cross(wB, vcp->rB) - vA - b2Cross(wA, vcp->rA));
+			if (vRel < -b2_velocityThreshold)
+			{
+				vcp->velocityBias = -vc->restitution * vRel;
+			}
+		}
+
+		// If we have two points, then prepare the block solver.
+		if (vc->pointCount == 2)
+		{
+			b2VelocityConstraintPoint* vcp1 = vc->points + 0;
+			b2VelocityConstraintPoint* vcp2 = vc->points + 1;
+
+			float32 rn1A = b2Cross(vcp1->rA, vc->normal);
+			float32 rn1B = b2Cross(vcp1->rB, vc->normal);
+			float32 rn2A = b2Cross(vcp2->rA, vc->normal);
+			float32 rn2B = b2Cross(vcp2->rB, vc->normal);
+
+			float32 k11 = mA + mB + iA * rn1A * rn1A + iB * rn1B * rn1B;
+			float32 k22 = mA + mB + iA * rn2A * rn2A + iB * rn2B * rn2B;
+			float32 k12 = mA + mB + iA * rn1A * rn2A + iB * rn1B * rn2B;
+
+			// Ensure a reasonable condition number.
+			const float32 k_maxConditionNumber = 1000.0f;
+			if (k11 * k11 < k_maxConditionNumber * (k11 * k22 - k12 * k12))
+			{
+				// K is safe to invert.
+				vc->K.ex.Set(k11, k12);
+				vc->K.ey.Set(k12, k22);
+				vc->normalMass = vc->K.GetInverse();
+			}
+			else
+			{
+				// The constraints are redundant, just use one.
+				// TODO_ERIN use deepest?
+				vc->pointCount = 1;
+			}
+		}
+	}
+}
+
+void b2ContactSolver::WarmStart()
+{
+	// Warm start.
+	for (int32 i = 0; i < m_count; ++i)
+	{
+		b2ContactVelocityConstraint* vc = m_velocityConstraints + i;
+
+		int32 indexA = vc->indexA;
+		int32 indexB = vc->indexB;
+		float32 mA = vc->invMassA;
+		float32 iA = vc->invIA;
+		float32 mB = vc->invMassB;
+		float32 iB = vc->invIB;
+		int32 pointCount = vc->pointCount;
+
+		b2Vec2 vA = m_velocities[indexA].v;
+		float32 wA = m_velocities[indexA].w;
+		b2Vec2 vB = m_velocities[indexB].v;
+		float32 wB = m_velocities[indexB].w;
+
+		b2Vec2 normal = vc->normal;
+		b2Vec2 tangent = b2Cross(normal, 1.0f);
+
+		for (int32 j = 0; j < pointCount; ++j)
+		{
+			b2VelocityConstraintPoint* vcp = vc->points + j;
+			b2Vec2 P = vcp->normalImpulse * normal + vcp->tangentImpulse * tangent;
+			wA -= iA * b2Cross(vcp->rA, P);
+			vA -= mA * P;
+			wB += iB * b2Cross(vcp->rB, P);
+			vB += mB * P;
+		}
+
+		m_velocities[indexA].v = vA;
+		m_velocities[indexA].w = wA;
+		m_velocities[indexB].v = vB;
+		m_velocities[indexB].w = wB;
+	}
+}
+
+void b2ContactSolver::SolveVelocityConstraints()
+{
+	for (int32 i = 0; i < m_count; ++i)
+	{
+		b2ContactVelocityConstraint* vc = m_velocityConstraints + i;
+
+		int32 indexA = vc->indexA;
+		int32 indexB = vc->indexB;
+		float32 mA = vc->invMassA;
+		float32 iA = vc->invIA;
+		float32 mB = vc->invMassB;
+		float32 iB = vc->invIB;
+		int32 pointCount = vc->pointCount;
+
+		b2Vec2 vA = m_velocities[indexA].v;
+		float32 wA = m_velocities[indexA].w;
+		b2Vec2 vB = m_velocities[indexB].v;
+		float32 wB = m_velocities[indexB].w;
+
+		b2Vec2 normal = vc->normal;
+		b2Vec2 tangent = b2Cross(normal, 1.0f);
+		float32 friction = vc->friction;
+
+		b2Assert(pointCount == 1 || pointCount == 2);
+
+		// Solve tangent constraints first because non-penetration is more important
+		// than friction.
+		for (int32 j = 0; j < pointCount; ++j)
+		{
+			b2VelocityConstraintPoint* vcp = vc->points + j;
+
+			// Relative velocity at contact
+			b2Vec2 dv = vB + b2Cross(wB, vcp->rB) - vA - b2Cross(wA, vcp->rA);
+
+			// Compute tangent force
+			float32 vt = b2Dot(dv, tangent);
+			float32 lambda = vcp->tangentMass * (-vt);
+
+			// b2Clamp the accumulated force
+			float32 maxFriction = friction * vcp->normalImpulse;
+			float32 newImpulse = b2Clamp(vcp->tangentImpulse + lambda, -maxFriction, maxFriction);
+			lambda = newImpulse - vcp->tangentImpulse;
+			vcp->tangentImpulse = newImpulse;
+
+			// Apply contact impulse
+			b2Vec2 P = lambda * tangent;
+
+			vA -= mA * P;
+			wA -= iA * b2Cross(vcp->rA, P);
+
+			vB += mB * P;
+			wB += iB * b2Cross(vcp->rB, P);
+		}
+
+		// Solve normal constraints
+		if (vc->pointCount == 1)
+		{
+			b2VelocityConstraintPoint* vcp = vc->points + 0;
+
+			// Relative velocity at contact
+			b2Vec2 dv = vB + b2Cross(wB, vcp->rB) - vA - b2Cross(wA, vcp->rA);
+
+			// Compute normal impulse
+			float32 vn = b2Dot(dv, normal);
+			float32 lambda = -vcp->normalMass * (vn - vcp->velocityBias);
+
+			// b2Clamp the accumulated impulse
+			float32 newImpulse = b2Max(vcp->normalImpulse + lambda, 0.0f);
+			lambda = newImpulse - vcp->normalImpulse;
+			vcp->normalImpulse = newImpulse;
+
+			// Apply contact impulse
+			b2Vec2 P = lambda * normal;
+			vA -= mA * P;
+			wA -= iA * b2Cross(vcp->rA, P);
+
+			vB += mB * P;
+			wB += iB * b2Cross(vcp->rB, P);
+		}
+		else
+		{
+			// Block solver developed in collaboration with Dirk Gregorius (back in 01/07 on Box2D_Lite).
+			// Build the mini LCP for this contact patch
+			//
+			// vn = A * x + b, vn >= 0, , vn >= 0, x >= 0 and vn_i * x_i = 0 with i = 1..2
+			//
+			// A = J * W * JT and J = ( -n, -r1 x n, n, r2 x n )
+			// b = vn0 - velocityBias
+			//
+			// The system is solved using the "Total enumeration method" (s. Murty). The complementary constraint vn_i * x_i
+			// implies that we must have in any solution either vn_i = 0 or x_i = 0. So for the 2D contact problem the cases
+			// vn1 = 0 and vn2 = 0, x1 = 0 and x2 = 0, x1 = 0 and vn2 = 0, x2 = 0 and vn1 = 0 need to be tested. The first valid
+			// solution that satisfies the problem is chosen.
+			// 
+			// In order to account of the accumulated impulse 'a' (because of the iterative nature of the solver which only requires
+			// that the accumulated impulse is clamped and not the incremental impulse) we change the impulse variable (x_i).
+			//
+			// Substitute:
+			// 
+			// x = a + d
+			// 
+			// a := old total impulse
+			// x := new total impulse
+			// d := incremental impulse 
+			//
+			// For the current iteration we extend the formula for the incremental impulse
+			// to compute the new total impulse:
+			//
+			// vn = A * d + b
+			//    = A * (x - a) + b
+			//    = A * x + b - A * a
+			//    = A * x + b'
+			// b' = b - A * a;
+
+			b2VelocityConstraintPoint* cp1 = vc->points + 0;
+			b2VelocityConstraintPoint* cp2 = vc->points + 1;
+
+			b2Vec2 a(cp1->normalImpulse, cp2->normalImpulse);
+			b2Assert(a.x >= 0.0f && a.y >= 0.0f);
+
+			// Relative velocity at contact
+			b2Vec2 dv1 = vB + b2Cross(wB, cp1->rB) - vA - b2Cross(wA, cp1->rA);
+			b2Vec2 dv2 = vB + b2Cross(wB, cp2->rB) - vA - b2Cross(wA, cp2->rA);
+
+			// Compute normal velocity
+			float32 vn1 = b2Dot(dv1, normal);
+			float32 vn2 = b2Dot(dv2, normal);
+
+			b2Vec2 b;
+			b.x = vn1 - cp1->velocityBias;
+			b.y = vn2 - cp2->velocityBias;
+
+			// Compute b'
+			b -= b2Mul(vc->K, a);
+
+			const float32 k_errorTol = 1e-3f;
+			B2_NOT_USED(k_errorTol);
+
+			for (;;)
+			{
+				//
+				// Case 1: vn = 0
+				//
+				// 0 = A * x + b'
+				//
+				// Solve for x:
+				//
+				// x = - inv(A) * b'
+				//
+				b2Vec2 x = - b2Mul(vc->normalMass, b);
+
+				if (x.x >= 0.0f && x.y >= 0.0f)
+				{
+					// Get the incremental impulse
+					b2Vec2 d = x - a;
+
+					// Apply incremental impulse
+					b2Vec2 P1 = d.x * normal;
+					b2Vec2 P2 = d.y * normal;
+					vA -= mA * (P1 + P2);
+					wA -= iA * (b2Cross(cp1->rA, P1) + b2Cross(cp2->rA, P2));
+
+					vB += mB * (P1 + P2);
+					wB += iB * (b2Cross(cp1->rB, P1) + b2Cross(cp2->rB, P2));
+
+					// Accumulate
+					cp1->normalImpulse = x.x;
+					cp2->normalImpulse = x.y;
+
+#if B2_DEBUG_SOLVER == 1
+					// Postconditions
+					dv1 = vB + b2Cross(wB, cp1->rB) - vA - b2Cross(wA, cp1->rA);
+					dv2 = vB + b2Cross(wB, cp2->rB) - vA - b2Cross(wA, cp2->rA);
+
+					// Compute normal velocity
+					vn1 = b2Dot(dv1, normal);
+					vn2 = b2Dot(dv2, normal);
+
+					b2Assert(b2Abs(vn1 - cp1->velocityBias) < k_errorTol);
+					b2Assert(b2Abs(vn2 - cp2->velocityBias) < k_errorTol);
+#endif
+					break;
+				}
+
+				//
+				// Case 2: vn1 = 0 and x2 = 0
+				//
+				//   0 = a11 * x1 + a12 * 0 + b1' 
+				// vn2 = a21 * x1 + a22 * 0 + b2'
+				//
+				x.x = - cp1->normalMass * b.x;
+				x.y = 0.0f;
+				vn1 = 0.0f;
+				vn2 = vc->K.ex.y * x.x + b.y;
+
+				if (x.x >= 0.0f && vn2 >= 0.0f)
+				{
+					// Get the incremental impulse
+					b2Vec2 d = x - a;
+
+					// Apply incremental impulse
+					b2Vec2 P1 = d.x * normal;
+					b2Vec2 P2 = d.y * normal;
+					vA -= mA * (P1 + P2);
+					wA -= iA * (b2Cross(cp1->rA, P1) + b2Cross(cp2->rA, P2));
+
+					vB += mB * (P1 + P2);
+					wB += iB * (b2Cross(cp1->rB, P1) + b2Cross(cp2->rB, P2));
+
+					// Accumulate
+					cp1->normalImpulse = x.x;
+					cp2->normalImpulse = x.y;
+
+#if B2_DEBUG_SOLVER == 1
+					// Postconditions
+					dv1 = vB + b2Cross(wB, cp1->rB) - vA - b2Cross(wA, cp1->rA);
+
+					// Compute normal velocity
+					vn1 = b2Dot(dv1, normal);
+
+					b2Assert(b2Abs(vn1 - cp1->velocityBias) < k_errorTol);
+#endif
+					break;
+				}
+
+
+				//
+				// Case 3: vn2 = 0 and x1 = 0
+				//
+				// vn1 = a11 * 0 + a12 * x2 + b1' 
+				//   0 = a21 * 0 + a22 * x2 + b2'
+				//
+				x.x = 0.0f;
+				x.y = - cp2->normalMass * b.y;
+				vn1 = vc->K.ey.x * x.y + b.x;
+				vn2 = 0.0f;
+
+				if (x.y >= 0.0f && vn1 >= 0.0f)
+				{
+					// Resubstitute for the incremental impulse
+					b2Vec2 d = x - a;
+
+					// Apply incremental impulse
+					b2Vec2 P1 = d.x * normal;
+					b2Vec2 P2 = d.y * normal;
+					vA -= mA * (P1 + P2);
+					wA -= iA * (b2Cross(cp1->rA, P1) + b2Cross(cp2->rA, P2));
+
+					vB += mB * (P1 + P2);
+					wB += iB * (b2Cross(cp1->rB, P1) + b2Cross(cp2->rB, P2));
+
+					// Accumulate
+					cp1->normalImpulse = x.x;
+					cp2->normalImpulse = x.y;
+
+#if B2_DEBUG_SOLVER == 1
+					// Postconditions
+					dv2 = vB + b2Cross(wB, cp2->rB) - vA - b2Cross(wA, cp2->rA);
+
+					// Compute normal velocity
+					vn2 = b2Dot(dv2, normal);
+
+					b2Assert(b2Abs(vn2 - cp2->velocityBias) < k_errorTol);
+#endif
+					break;
+				}
+
+				//
+				// Case 4: x1 = 0 and x2 = 0
+				// 
+				// vn1 = b1
+				// vn2 = b2;
+				x.x = 0.0f;
+				x.y = 0.0f;
+				vn1 = b.x;
+				vn2 = b.y;
+
+				if (vn1 >= 0.0f && vn2 >= 0.0f )
+				{
+					// Resubstitute for the incremental impulse
+					b2Vec2 d = x - a;
+
+					// Apply incremental impulse
+					b2Vec2 P1 = d.x * normal;
+					b2Vec2 P2 = d.y * normal;
+					vA -= mA * (P1 + P2);
+					wA -= iA * (b2Cross(cp1->rA, P1) + b2Cross(cp2->rA, P2));
+
+					vB += mB * (P1 + P2);
+					wB += iB * (b2Cross(cp1->rB, P1) + b2Cross(cp2->rB, P2));
+
+					// Accumulate
+					cp1->normalImpulse = x.x;
+					cp2->normalImpulse = x.y;
+
+					break;
+				}
+
+				// No solution, give up. This is hit sometimes, but it doesn't seem to matter.
+				break;
+			}
+		}
+
+		m_velocities[indexA].v = vA;
+		m_velocities[indexA].w = wA;
+		m_velocities[indexB].v = vB;
+		m_velocities[indexB].w = wB;
+	}
+}
+
+void b2ContactSolver::StoreImpulses()
+{
+	for (int32 i = 0; i < m_count; ++i)
+	{
+		b2ContactVelocityConstraint* vc = m_velocityConstraints + i;
+		b2Manifold* manifold = m_contacts[vc->contactIndex]->GetManifold();
+
+		for (int32 j = 0; j < vc->pointCount; ++j)
+		{
+			manifold->points[j].normalImpulse = vc->points[j].normalImpulse;
+			manifold->points[j].tangentImpulse = vc->points[j].tangentImpulse;
+		}
+	}
+}
+
+struct b2PositionSolverManifold
+{
+	void Initialize(b2ContactPositionConstraint* pc, const b2Transform& xfA, const b2Transform& xfB, int32 index)
+	{
+		b2Assert(pc->pointCount > 0);
+
+		switch (pc->type)
+		{
+		case b2Manifold::e_circles:
+			{
+				b2Vec2 pointA = b2Mul(xfA, pc->localPoint);
+				b2Vec2 pointB = b2Mul(xfB, pc->localPoints[0]);
+				normal = pointB - pointA;
+				normal.Normalize();
+				point = 0.5f * (pointA + pointB);
+				separation = b2Dot(pointB - pointA, normal) - pc->radiusA - pc->radiusB;
+			}
+			break;
+
+		case b2Manifold::e_faceA:
+			{
+				normal = b2Mul(xfA.q, pc->localNormal);
+				b2Vec2 planePoint = b2Mul(xfA, pc->localPoint);
+
+				b2Vec2 clipPoint = b2Mul(xfB, pc->localPoints[index]);
+				separation = b2Dot(clipPoint - planePoint, normal) - pc->radiusA - pc->radiusB;
+				point = clipPoint;
+			}
+			break;
+
+		case b2Manifold::e_faceB:
+			{
+				normal = b2Mul(xfB.q, pc->localNormal);
+				b2Vec2 planePoint = b2Mul(xfB, pc->localPoint);
+
+				b2Vec2 clipPoint = b2Mul(xfA, pc->localPoints[index]);
+				separation = b2Dot(clipPoint - planePoint, normal) - pc->radiusA - pc->radiusB;
+				point = clipPoint;
+
+				// Ensure normal points from A to B
+				normal = -normal;
+			}
+			break;
+		}
+	}
+
+	b2Vec2 normal;
+	b2Vec2 point;
+	float32 separation;
+};
+
+// Sequential solver.
+bool b2ContactSolver::SolvePositionConstraints()
+{
+	float32 minSeparation = 0.0f;
+
+	for (int32 i = 0; i < m_count; ++i)
+	{
+		b2ContactPositionConstraint* pc = m_positionConstraints + i;
+
+		int32 indexA = pc->indexA;
+		int32 indexB = pc->indexB;
+		b2Vec2 localCenterA = pc->localCenterA;
+		float32 mA = pc->invMassA;
+		float32 iA = pc->invIA;
+		b2Vec2 localCenterB = pc->localCenterB;
+		float32 mB = pc->invMassB;
+		float32 iB = pc->invIB;
+		int32 pointCount = pc->pointCount;
+
+		b2Vec2 cA = m_positions[indexA].c;
+		float32 aA = m_positions[indexA].a;
+
+		b2Vec2 cB = m_positions[indexB].c;
+		float32 aB = m_positions[indexB].a;
+
+		// Solve normal constraints
+		for (int32 j = 0; j < pointCount; ++j)
+		{
+			b2Transform xfA, xfB;
+			xfA.q.Set(aA);
+			xfB.q.Set(aB);
+			xfA.p = cA - b2Mul(xfA.q, localCenterA);
+			xfB.p = cB - b2Mul(xfB.q, localCenterB);
+
+			b2PositionSolverManifold psm;
+			psm.Initialize(pc, xfA, xfB, j);
+			b2Vec2 normal = psm.normal;
+
+			b2Vec2 point = psm.point;
+			float32 separation = psm.separation;
+
+			b2Vec2 rA = point - cA;
+			b2Vec2 rB = point - cB;
+
+			// Track max constraint error.
+			minSeparation = b2Min(minSeparation, separation);
+
+			// Prevent large corrections and allow slop.
+			float32 C = b2Clamp(b2_baumgarte * (separation + b2_linearSlop), -b2_maxLinearCorrection, 0.0f);
+
+			// Compute the effective mass.
+			float32 rnA = b2Cross(rA, normal);
+			float32 rnB = b2Cross(rB, normal);
+			float32 K = mA + mB + iA * rnA * rnA + iB * rnB * rnB;
+
+			// Compute normal impulse
+			float32 impulse = K > 0.0f ? - C / K : 0.0f;
+
+			b2Vec2 P = impulse * normal;
+
+			cA -= mA * P;
+			aA -= iA * b2Cross(rA, P);
+
+			cB += mB * P;
+			aB += iB * b2Cross(rB, P);
+		}
+
+		m_positions[indexA].c = cA;
+		m_positions[indexA].a = aA;
+
+		m_positions[indexB].c = cB;
+		m_positions[indexB].a = aB;
+	}
+
+	// We can't expect minSpeparation >= -b2_linearSlop because we don't
+	// push the separation above -b2_linearSlop.
+	return minSeparation >= -3.0f * b2_linearSlop;
+}
+
+// Sequential position solver for position constraints.
+bool b2ContactSolver::SolveTOIPositionConstraints(int32 toiIndexA, int32 toiIndexB)
+{
+	float32 minSeparation = 0.0f;
+
+	for (int32 i = 0; i < m_count; ++i)
+	{
+		b2ContactPositionConstraint* pc = m_positionConstraints + i;
+
+		int32 indexA = pc->indexA;
+		int32 indexB = pc->indexB;
+		b2Vec2 localCenterA = pc->localCenterA;
+		b2Vec2 localCenterB = pc->localCenterB;
+		int32 pointCount = pc->pointCount;
+
+		float32 mA = 0.0f;
+		float32 iA = 0.0f;
+		if (indexA == toiIndexA || indexA == toiIndexB)
+		{
+			mA = pc->invMassA;
+			iA = pc->invIA;
+		}
+
+		float32 mB = pc->invMassB;
+		float32 iB = pc->invIB;
+		if (indexB == toiIndexA || indexB == toiIndexB)
+		{
+			mB = pc->invMassB;
+			iB = pc->invIB;
+		}
+
+		b2Vec2 cA = m_positions[indexA].c;
+		float32 aA = m_positions[indexA].a;
+
+		b2Vec2 cB = m_positions[indexB].c;
+		float32 aB = m_positions[indexB].a;
+
+		// Solve normal constraints
+		for (int32 j = 0; j < pointCount; ++j)
+		{
+			b2Transform xfA, xfB;
+			xfA.q.Set(aA);
+			xfB.q.Set(aB);
+			xfA.p = cA - b2Mul(xfA.q, localCenterA);
+			xfB.p = cB - b2Mul(xfB.q, localCenterB);
+
+			b2PositionSolverManifold psm;
+			psm.Initialize(pc, xfA, xfB, j);
+			b2Vec2 normal = psm.normal;
+
+			b2Vec2 point = psm.point;
+			float32 separation = psm.separation;
+
+			b2Vec2 rA = point - cA;
+			b2Vec2 rB = point - cB;
+
+			// Track max constraint error.
+			minSeparation = b2Min(minSeparation, separation);
+
+			// Prevent large corrections and allow slop.
+			float32 C = b2Clamp(b2_toiBaugarte * (separation + b2_linearSlop), -b2_maxLinearCorrection, 0.0f);
+
+			// Compute the effective mass.
+			float32 rnA = b2Cross(rA, normal);
+			float32 rnB = b2Cross(rB, normal);
+			float32 K = mA + mB + iA * rnA * rnA + iB * rnB * rnB;
+
+			// Compute normal impulse
+			float32 impulse = K > 0.0f ? - C / K : 0.0f;
+
+			b2Vec2 P = impulse * normal;
+
+			cA -= mA * P;
+			aA -= iA * b2Cross(rA, P);
+
+			cB += mB * P;
+			aB += iB * b2Cross(rB, P);
+		}
+
+		m_positions[indexA].c = cA;
+		m_positions[indexA].a = aA;
+
+		m_positions[indexB].c = cB;
+		m_positions[indexB].a = aB;
+	}
+
+	// We can't expect minSpeparation >= -b2_linearSlop because we don't
+	// push the separation above -b2_linearSlop.
+	return minSeparation >= -1.5f * b2_linearSlop;
+}

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