diff --git a/CMakeLists.txt b/CMakeLists.txt
index 333c87aa0..66088a08f 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -23,13 +23,17 @@ if(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR})
message(FATAL_ERROR "Prevented in-tree build.")
endif()
-cmake_minimum_required(VERSION 2.8)
+cmake_minimum_required(VERSION 3.1)
project(love)
set(LOVE_EXE_NAME love)
set(LOVE_LIB_NAME liblove)
+set(CMAKE_MODULE_PATH "${love_SOURCE_DIR}/extra/cmake" ${CMAKE_MODULE_PATH})
+# Needed for shared libs on Linux. (-fPIC).
+set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
+
set (CMAKE_CXX_STANDARD 11)
if(MSVC)
@@ -157,19 +161,87 @@ if(MEGA)
# automatically.
endif()
else()
- message(FATAL_ERROR "
+ if(MSVC)
+ message(FATAL_ERROR "
It is currently only possible to build with megasource on Windows.
Please see http://bitbucket.org/rude/megasource
")
+ endif()
+
+ find_package(Freetype REQUIRED)
+ find_package(ModPlug REQUIRED)
+ find_package(OpenAL REQUIRED)
+ find_package(OpenGL REQUIRED)
+ find_package(PhysFS REQUIRED)
+ find_package(SDL2 REQUIRED)
+ find_package(Theora REQUIRED)
+ find_package(Vorbis REQUIRED)
+
+ # required for enet
+ add_definitions(-D HAS_SOCKLEN_T)
+
+ set(LOVE_INCLUDE_DIRS
+ ${SDL2_INCLUDE_DIR}
+ ${PHYSFS_INCLUDE_DIR}
+ ${FREETYPE_INCLUDE_DIRS}
+ ${VORBIS_INCLUDE_DIR}
+ )
+
+ set(LOVE_LINK_LIBRARIES
+ ${OPENGL_gl_LIBRARY}
+ ${SDL2_LIBRARY}
+ ${FREETYPE_LIBRARY}
+ ${OPENAL_LIBRARY}
+ ${MODPLUG_LIBRARY}
+ ${PHYSFS_LIBRARY}
+ ${THEORA_LIBRARY}
+ ${THEORADEC_LIBRARY}
+ ${VORBISFILE_LIBRARY}
+ ${LOVE_LUA_LIBRARY}
+ )
+
+ if(LOVE_MPG123)
+ find_package(MPG123 REQUIRED)
+ set(LOVE_LINK_LIBRARIES
+ ${LOVE_LINK_LIBRARIES}
+ ${MPG123_LIBRARY}
+ )
+ endif()
+
+ if(LOVE_JIT)
+ find_package(LuaJIT REQUIRED)
+ set(LOVE_LUA_LIBRARY ${LUAJIT_LIBRARY})
+ set(LOVE_LUA_INCLUDE_DIR ${LUAJIT_INCLUDE_DIR})
+ else()
+ find_package(Lua51 REQUIRED)
+ set(LOVE_LUA_LIBRARY ${LUA_LIBRARY})
+ set(LOVE_LUA_INCLUDE_DIR ${LUA_INCLUDE_DIR})
+ endif()
+
+ set(LOVE_INCLUDE_DIRS
+ ${LOVE_INCLUDE_DIRS}
+ ${LOVE_LUA_INCLUDE_DIR}
+ )
+ set(LOVE_LINK_LIBRARIES
+ ${LOVE_LINK_LIBRARIES}
+ ${LOVE_LUA_LIBRARY}
+ )
+
endif()
###
### No Megasource-specific stuff beyond this point!
###
-function(disable_warnings ARG_TARGET)
+if(MSVC)
+ set(DISABLE_WARNING_FLAG -W0)
+else()
+ set(DISABLE_WARNING_FLAG -w)
+endif()
+
+function(love_disable_warnings ARG_TARGET)
get_target_property(OLD_FLAGS ${ARG_TARGET} COMPILE_FLAGS)
- set(NEW_FLAGS -W0)
+ set(NEW_FLAGS ${DISABLE_WARNING_FLAG})
if(OLD_FLAGS)
set(NEW_FLAGS "${OLD_FLAGS} ${NEW_FLAGS}")
endif()
@@ -1342,7 +1414,7 @@ set(LOVE_3P
love_3p_wuff
)
-disable_warnings(love_3p_box2d love_3p_enet love_3p_luasocket)
+love_disable_warnings(love_3p_box2d love_3p_enet love_3p_luasocket)
#
# liblove
diff --git a/changes.txt b/changes.txt
index b86c62bc5..14e370adc 100644
--- a/changes.txt
+++ b/changes.txt
@@ -34,6 +34,8 @@ Released: N/A
* Added Quad:getTextureDimensions.
* Added PrismaticJoint:getAxis and WheelJoint:getAxis.
* Added 2-point version of love.physics.newRevoluteJoint.
+ * Added table variants of Fixture:setCategory and Fixture:setMask.
+ * Added getNextVertex and getPreviousVertex to ChainShape and EdgeShape.
* Fixed love on iOS 6.
* Fixed os.execute always returning -1 on Linux.
@@ -49,6 +51,7 @@ Released: N/A
* Fixed large burst of particles when dramatically increasing the emission rate of a ParticleSystem.
* Fixed MouseJoint:getBodies unconditionally erroring.
* Fixed memory leak in Text:set.
+ * Fixed incorrect kerning caused by using kerning information for the wrong character in some fonts.
* Improved performance of Channel methods by roughly 2x in many cases.
diff --git a/extra/cmake/FindLuaJIT.cmake b/extra/cmake/FindLuaJIT.cmake
new file mode 100644
index 000000000..a48410195
--- /dev/null
+++ b/extra/cmake/FindLuaJIT.cmake
@@ -0,0 +1,25 @@
+# Sets the following variables:
+#
+# LUAJIT_FOUND
+# LUAJIT_INCLUDE_DIR
+# LUAJIT_LIBRARY
+
+set(LUAJIT_SEARCH_PATHS
+ /usr/local
+ /usr
+ )
+
+find_path(LUAJIT_INCLUDE_DIR
+ NAMES luajit.h
+ PATH_SUFFIXES include include/luajit-2.0
+ PATHS ${LUAJIT_SEARCH_PATHS})
+
+find_library(LUAJIT_LIBRARY
+ NAMES luajit-5.1
+ PATH_SUFFIXES lib
+ PATHS ${LUAJIT_SEARCH_PATHS})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(LuaJIT DEFAULT_MSG LUAJIT_LIBRARY LUAJIT_INCLUDE_DIR)
+
+mark_as_advanced(LUAJIT_INCLUDE_DIR LUAJIT_LIBRARY)
diff --git a/extra/cmake/FindMPG123.cmake b/extra/cmake/FindMPG123.cmake
new file mode 100644
index 000000000..6cda993b2
--- /dev/null
+++ b/extra/cmake/FindMPG123.cmake
@@ -0,0 +1,25 @@
+# Sets the following variables:
+#
+# MPG123_FOUND
+# MPG123_INCLUDE_DIR
+# MPG123_LIBRARY
+
+set(MPG123_SEARCH_PATHS
+ /usr/local
+ /usr
+ )
+
+find_path(MPG123_INCLUDE_DIR
+ NAMES mpg123.h
+ PATH_SUFFIXES include
+ PATHS ${MPG123_SEARCH_PATHS})
+
+find_library(MPG123_LIBRARY
+ NAMES mpg123
+ PATH_SUFFIXES lib
+ PATHS ${MPG123_SEARCH_PATHS})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(MPG123 DEFAULT_MSG MPG123_LIBRARY MPG123_INCLUDE_DIR)
+
+mark_as_advanced(MPG123_INCLUDE_DIR MPG123_LIBRARY)
diff --git a/extra/cmake/FindModPlug.cmake b/extra/cmake/FindModPlug.cmake
new file mode 100644
index 000000000..16641d3be
--- /dev/null
+++ b/extra/cmake/FindModPlug.cmake
@@ -0,0 +1,25 @@
+# Sets the following variables:
+#
+# MODPLUG_FOUND
+# MODPLUG_INCLUDE_DIR
+# MODPLUG_LIBRARY
+
+set(MODPLUG_SEARCH_PATHS
+ /usr/local
+ /usr
+ )
+
+find_path(MODPLUG_INCLUDE_DIR
+ NAMES libmodplug/modplug.h
+ PATH_SUFFIXES include
+ PATHS ${MODPLUG_SEARCH_PATHS})
+
+find_library(MODPLUG_LIBRARY
+ NAMES modplug
+ PATH_SUFFIXES lib
+ PATHS ${MODPLUG_SEARCH_PATHS})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(ModPlug DEFAULT_MSG MODPLUG_LIBRARY MODPLUG_INCLUDE_DIR)
+
+mark_as_advanced(MODPLUG_INCLUDE_DIR MODPLUG_LIBRARY)
diff --git a/extra/cmake/FindSDL2.cmake b/extra/cmake/FindSDL2.cmake
new file mode 100644
index 000000000..81de07ffd
--- /dev/null
+++ b/extra/cmake/FindSDL2.cmake
@@ -0,0 +1,25 @@
+# Sets the following variables:
+#
+# SDL2_FOUND
+# SDL2_INCLUDE_DIR
+# SDL2_LIBRARY
+
+set(SDL2_SEARCH_PATHS
+ /usr/local
+ /usr
+ )
+
+find_path(SDL2_INCLUDE_DIR
+ NAMES SDL.h
+ PATH_SUFFIXES include include/SDL2
+ PATHS ${SDL2_SEARCH_PATHS})
+
+find_library(SDL2_LIBRARY
+ NAMES SDL2
+ PATH_SUFFIXES lib
+ PATHS ${SDL2_SEARCH_PATHS})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(SDL2 DEFAULT_MSG SDL2_LIBRARY SDL2_INCLUDE_DIR)
+
+mark_as_advanced(SDL2_INCLUDE_DIR SDL2_LIBRARY)
diff --git a/extra/cmake/FindTheora.cmake b/extra/cmake/FindTheora.cmake
new file mode 100644
index 000000000..4a3804a5b
--- /dev/null
+++ b/extra/cmake/FindTheora.cmake
@@ -0,0 +1,31 @@
+# Sets the following variables:
+#
+# THEORA_FOUND
+# THEORA_INCLUDE_DIR
+# THEORA_LIBRARY
+# THEORADEC_LIBRARY
+
+set(THEORA_SEARCH_PATHS
+ /usr/local
+ /usr
+ )
+
+find_path(THEORA_INCLUDE_DIR
+ NAMES theora/codec.h
+ PATH_SUFFIXES include
+ PATHS ${THEORA_SEARCH_PATHS})
+
+find_library(THEORA_LIBRARY
+ NAMES theora
+ PATH_SUFFIXES lib
+ PATHS ${THEORA_SEARCH_PATHS})
+
+find_library(THEORADEC_LIBRARY
+ NAMES theoradec
+ PATH_SUFFIXES lib
+ PATHS ${THEORA_SEARCH_PATHS})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Theora DEFAULT_MSG THEORA_LIBRARY THEORA_INCLUDE_DIR)
+
+mark_as_advanced(THEORA_INCLUDE_DIR THEORA_LIBRARY)
diff --git a/extra/cmake/FindVorbis.cmake b/extra/cmake/FindVorbis.cmake
new file mode 100644
index 000000000..6a263a4c8
--- /dev/null
+++ b/extra/cmake/FindVorbis.cmake
@@ -0,0 +1,30 @@
+# Sets the following variables:
+#
+# VORBIS_FOUND
+# VORBIS_INCLUDE_DIR
+# VORBIS_LIBRARY
+# VORBISFILE_LIBRARY
+
+set(VORBIS_SEARCH_PATHS
+ /usr/local
+ /usr
+ )
+
+find_path(VORBIS_INCLUDE_DIR vorbis/vorbisfile.h
+ PATH_SUFFIXES include
+ PATHS ${VORBIS_SEARCH_PATHS})
+
+find_library(VORBIS_LIBRARY
+ NAMES vorbis
+ PATH_SUFFIXES lib
+ PATHS ${VORBIS_SEARCH_PATHS})
+
+find_library(VORBISFILE_LIBRARY
+ NAMES vorbisfile
+ PATH_SUFFIXES lib
+ PATHS ${VORBIS_SEARCH_PATHS})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Vorbis DEFAULT_MSG VORBIS_LIBRARY VORBISFILE_LIBRARY VORBIS_INCLUDE_DIR)
+
+mark_as_advanced(VORBIS_INCLUDE_DIR VORBIS_LIBRARY VORBISFILE_LIBRARY)
diff --git a/platform/xcode/macosx/love-macosx.plist b/platform/xcode/macosx/love-macosx.plist
index a1fb47dba..acf845a37 100644
--- a/platform/xcode/macosx/love-macosx.plist
+++ b/platform/xcode/macosx/love-macosx.plist
@@ -7,6 +7,10 @@
CFBundleDocumentTypes
+ CFBundleTypeExtensions
+
+ love
+
CFBundleTypeIconFile
GameIcon
CFBundleTypeName
@@ -19,6 +23,8 @@
org.love2d.love-game
+ LSTypeIsPackage
+ 1
CFBundleTypeName
@@ -73,6 +79,7 @@
UTTypeConformsTo
com.pkware.zip-archive
+ com.apple.package
UTTypeDescription
LÖVE Project
diff --git a/src/modules/font/freetype/TrueTypeRasterizer.cpp b/src/modules/font/freetype/TrueTypeRasterizer.cpp
index 8fea1b645..1c67ef00f 100644
--- a/src/modules/font/freetype/TrueTypeRasterizer.cpp
+++ b/src/modules/font/freetype/TrueTypeRasterizer.cpp
@@ -168,7 +168,11 @@ bool TrueTypeRasterizer::hasGlyph(uint32 glyph) const
float TrueTypeRasterizer::getKerning(uint32 leftglyph, uint32 rightglyph) const
{
FT_Vector kerning = {};
- FT_Get_Kerning(face, leftglyph, rightglyph, FT_KERNING_DEFAULT, &kerning);
+ FT_Get_Kerning(face,
+ FT_Get_Char_Index(face, leftglyph),
+ FT_Get_Char_Index(face, rightglyph),
+ FT_KERNING_DEFAULT,
+ &kerning);
return float(kerning.x >> 6);
}
diff --git a/src/modules/graphics/opengl/GLBuffer.cpp b/src/modules/graphics/opengl/GLBuffer.cpp
index 6658e8fdd..4cee2f34a 100644
--- a/src/modules/graphics/opengl/GLBuffer.cpp
+++ b/src/modules/graphics/opengl/GLBuffer.cpp
@@ -58,12 +58,10 @@ GLBuffer::GLBuffer(size_t size, const void *data, GLenum target, GLenum usage, u
if (data != nullptr)
memcpy(memory_map, data, size);
- bool ok = load(data != nullptr);
-
- if (!ok)
+ if (!load(data != nullptr))
{
delete[] memory_map;
- throw love::Exception("Could not load VBO.");
+ throw love::Exception("Could not load vertex buffer (out of VRAM?)");
}
}
@@ -221,13 +219,16 @@ bool GLBuffer::load(bool restore)
GLBuffer::Bind bind(*this);
+ while (glGetError() != GL_NO_ERROR)
+ /* Clear the error buffer. */;
+
// Copy the old buffer only if 'restore' was requested.
const GLvoid *src = restore ? memory_map : nullptr;
// Note that if 'src' is '0', no data will be copied.
glBufferData(getTarget(), (GLsizeiptr) getSize(), src, getUsage());
- return true;
+ return (glGetError() == GL_NO_ERROR);
}
void GLBuffer::unload()
diff --git a/src/modules/graphics/opengl/SpriteBatch.cpp b/src/modules/graphics/opengl/SpriteBatch.cpp
index 5edcad539..27671dbd8 100644
--- a/src/modules/graphics/opengl/SpriteBatch.cpp
+++ b/src/modules/graphics/opengl/SpriteBatch.cpp
@@ -166,14 +166,18 @@ void SpriteBatch::setBufferSize(int newsize)
size_t vertex_size = sizeof(Vertex) * 4 * newsize;
GLBuffer *new_array_buf = nullptr;
+ int new_next = std::min(next, newsize);
+
try
{
new_array_buf = new GLBuffer(vertex_size, nullptr, array_buf->getTarget(), array_buf->getUsage(), array_buf->getMapFlags());
- // Copy as much of the old data into the new GLBuffer as can fit.
GLBuffer::Bind bind(*new_array_buf);
- void *new_data = new_array_buf->map();
- memcpy(new_data, old_data, sizeof(Vertex) * 4 * std::min(newsize, size));
+
+ // Copy as much of the old data into the new GLBuffer as can fit.
+ size_t copy_size = sizeof(Vertex) * 4 * new_next;
+ memcpy(new_array_buf->map(), old_data, copy_size);
+ new_array_buf->setMappedRangeModified(0, copy_size);
quad_indices = QuadIndices(newsize);
}
@@ -189,7 +193,7 @@ void SpriteBatch::setBufferSize(int newsize)
array_buf = new_array_buf;
size = newsize;
- next = std::min(next, newsize);
+ next = new_next;
}
int SpriteBatch::getBufferSize() const
diff --git a/src/modules/physics/box2d/ChainShape.cpp b/src/modules/physics/box2d/ChainShape.cpp
index d55e3920d..1b77d0cc8 100644
--- a/src/modules/physics/box2d/ChainShape.cpp
+++ b/src/modules/physics/box2d/ChainShape.cpp
@@ -55,6 +55,12 @@ void ChainShape::setNextVertex(float x, float y)
c->SetNextVertex(Physics::scaleDown(v));
}
+void ChainShape::setNextVertex()
+{
+ b2ChainShape *c = (b2ChainShape *)shape;
+ c->m_hasNextVertex = false;
+}
+
void ChainShape::setPreviousVertex(float x, float y)
{
if (loop)
@@ -64,7 +70,43 @@ void ChainShape::setPreviousVertex(float x, float y)
}
b2Vec2 v(x, y);
b2ChainShape *c = (b2ChainShape *)shape;
- c->SetNextVertex(Physics::scaleDown(v));
+ c->SetPrevVertex(Physics::scaleDown(v));
+}
+
+void ChainShape::setPreviousVertex()
+{
+ b2ChainShape *c = (b2ChainShape *)shape;
+ c->m_hasPrevVertex = false;
+}
+
+bool ChainShape::getNextVertex(float &x, float &y) const
+{
+ b2ChainShape *c = (b2ChainShape *)shape;
+
+ if (c->m_hasNextVertex)
+ {
+ b2Vec2 v = Physics::scaleUp(c->m_nextVertex);
+ x = v.x;
+ y = v.y;
+ return true;
+ }
+
+ return false;
+}
+
+bool ChainShape::getPreviousVertex(float &x, float &y) const
+{
+ b2ChainShape *c = (b2ChainShape *)shape;
+
+ if (c->m_hasPrevVertex)
+ {
+ b2Vec2 v = Physics::scaleUp(c->m_prevVertex);
+ x = v.x;
+ y = v.y;
+ return true;
+ }
+
+ return false;
}
EdgeShape *ChainShape::getChildEdge(int index) const
diff --git a/src/modules/physics/box2d/ChainShape.h b/src/modules/physics/box2d/ChainShape.h
index 9f53ca958..8b7a18f2f 100644
--- a/src/modules/physics/box2d/ChainShape.h
+++ b/src/modules/physics/box2d/ChainShape.h
@@ -54,6 +54,7 @@ public:
* @param y The y-coordinate of the vertex.
**/
void setNextVertex(float x, float y);
+ void setNextVertex();
/**
* Establish connectivity to a vertex that precedes
@@ -62,6 +63,17 @@ public:
* @param y The y-coordinate of the vertex.
**/
void setPreviousVertex(float x, float y);
+ void setPreviousVertex();
+
+ /**
+ * Gets the vertex that follows the last vertex.
+ **/
+ bool getNextVertex(float &x, float &y) const;
+
+ /**
+ * Gets the vertex that precedes the first vertex.
+ **/
+ bool getPreviousVertex(float &x, float &y) const;
/**
* Returns a child EdgeShape.
diff --git a/src/modules/physics/box2d/EdgeShape.cpp b/src/modules/physics/box2d/EdgeShape.cpp
index 47f427c9a..8189b1318 100644
--- a/src/modules/physics/box2d/EdgeShape.cpp
+++ b/src/modules/physics/box2d/EdgeShape.cpp
@@ -43,6 +43,64 @@ EdgeShape::~EdgeShape()
{
}
+void EdgeShape::setNextVertex(float x, float y)
+{
+ b2EdgeShape *e = (b2EdgeShape *)shape;
+ b2Vec2 v(x, y);
+ e->m_vertex3 = Physics::scaleDown(v);
+ e->m_hasVertex3 = true;
+}
+
+void EdgeShape::setNextVertex()
+{
+ b2EdgeShape *e = (b2EdgeShape *)shape;
+ e->m_hasVertex3 = false;
+}
+
+bool EdgeShape::getNextVertex(float &x, float &y) const
+{
+ b2EdgeShape *e = (b2EdgeShape *)shape;
+
+ if (e->m_hasVertex3)
+ {
+ b2Vec2 v = Physics::scaleUp(e->m_vertex3);
+ x = v.x;
+ y = v.y;
+ return true;
+ }
+
+ return false;
+}
+
+void EdgeShape::setPreviousVertex(float x, float y)
+{
+ b2EdgeShape *e = (b2EdgeShape *)shape;
+ b2Vec2 v(x, y);
+ e->m_vertex0 = Physics::scaleDown(v);
+ e->m_hasVertex0 = true;
+}
+
+void EdgeShape::setPreviousVertex()
+{
+ b2EdgeShape *e = (b2EdgeShape *)shape;
+ e->m_hasVertex0 = false;
+}
+
+bool EdgeShape::getPreviousVertex(float &x, float &y) const
+{
+ b2EdgeShape *e = (b2EdgeShape *)shape;
+
+ if (e->m_hasVertex0)
+ {
+ b2Vec2 v = Physics::scaleUp(e->m_vertex0);
+ x = v.x;
+ y = v.y;
+ return true;
+ }
+
+ return false;
+}
+
int EdgeShape::getPoints(lua_State *L)
{
b2EdgeShape *e = (b2EdgeShape *)shape;
diff --git a/src/modules/physics/box2d/EdgeShape.h b/src/modules/physics/box2d/EdgeShape.h
index 86fd4e831..3e5184a22 100644
--- a/src/modules/physics/box2d/EdgeShape.h
+++ b/src/modules/physics/box2d/EdgeShape.h
@@ -47,6 +47,14 @@ public:
virtual ~EdgeShape();
+ void setNextVertex(float x, float y);
+ void setNextVertex();
+ bool getNextVertex(float &x, float &y) const;
+
+ void setPreviousVertex(float x, float y);
+ void setPreviousVertex();
+ bool getPreviousVertex(float &x, float &y) const;
+
/**
* Returns the transformed points of the edge shape.
* This function is useful for debug drawing and such.
diff --git a/src/modules/physics/box2d/Fixture.cpp b/src/modules/physics/box2d/Fixture.cpp
index 49689a4be..7f0b31e28 100644
--- a/src/modules/physics/box2d/Fixture.cpp
+++ b/src/modules/physics/box2d/Fixture.cpp
@@ -193,16 +193,28 @@ int Fixture::getMask(lua_State *L)
uint16 Fixture::getBits(lua_State *L)
{
// Get number of args.
- int argc = lua_gettop(L);
+ bool istable = lua_istable(L, 1);
+ int argc = istable ? (int) luax_objlen(L, 1) : lua_gettop(L);
// The new bitset.
std::bitset<16> b;
- for (int i = 1; i<=argc; i++)
+ for (int i = 1; i <= argc; i++)
{
- size_t bpos = (size_t)(lua_tointeger(L, i)-1);
+ size_t bpos = 0;
+
+ if (istable)
+ {
+ lua_rawgeti(L, 1, i);
+ bpos = (size_t) (lua_tointeger(L, -1) - 1);
+ lua_pop(L, 1);
+ }
+ else
+ bpos = (size_t) (lua_tointeger(L, i) - 1);
+
if (bpos >= 16)
luaL_error(L, "Values must be in range 1-16.");
+
b.set(bpos, true);
}
@@ -272,7 +284,8 @@ int Fixture::rayCast(lua_State *L) const
int Fixture::getBoundingBox(lua_State *L) const
{
int childIndex = (int) luaL_optnumber(L, 1, 1) - 1; // Convert from 1-based index
- b2AABB box = fixture->GetAABB(childIndex);
+ b2AABB box;
+ luax_catchexcept(L, [&]() { box = fixture->GetAABB(childIndex); });
box = Physics::scaleUp(box);
lua_pushnumber(L, box.lowerBound.x);
lua_pushnumber(L, box.lowerBound.y);
diff --git a/src/modules/physics/box2d/MouseJoint.cpp b/src/modules/physics/box2d/MouseJoint.cpp
index 08e41d35e..96768e870 100644
--- a/src/modules/physics/box2d/MouseJoint.cpp
+++ b/src/modules/physics/box2d/MouseJoint.cpp
@@ -36,6 +36,9 @@ MouseJoint::MouseJoint(Body *body1, float x, float y)
: Joint(body1)
, joint(NULL)
{
+ if (body1->getType() == Body::BODY_KINEMATIC)
+ throw love::Exception("Cannot attach a MouseJoint to a kinematic body");
+
b2MouseJointDef def;
def.bodyA = body1->world->getGroundBody();
diff --git a/src/modules/physics/box2d/PrismaticJoint.cpp b/src/modules/physics/box2d/PrismaticJoint.cpp
index 69f182074..e390405e8 100644
--- a/src/modules/physics/box2d/PrismaticJoint.cpp
+++ b/src/modules/physics/box2d/PrismaticJoint.cpp
@@ -140,8 +140,10 @@ int PrismaticJoint::getLimits(lua_State *L)
int PrismaticJoint::getAxis(lua_State *L)
{
- lua_pushnumber(L, joint->GetLocalAxisA().x);
- lua_pushnumber(L, joint->GetLocalAxisA().y);
+ b2Vec2 axis = joint->GetLocalAxisA();
+ getBodyA()->getWorldVector(axis.x, axis.y, axis.x, axis.y);
+ lua_pushnumber(L, axis.x);
+ lua_pushnumber(L, axis.y);
return 2;
}
diff --git a/src/modules/physics/box2d/WheelJoint.cpp b/src/modules/physics/box2d/WheelJoint.cpp
index bd066c157..2670878cd 100644
--- a/src/modules/physics/box2d/WheelJoint.cpp
+++ b/src/modules/physics/box2d/WheelJoint.cpp
@@ -115,8 +115,10 @@ float WheelJoint::getSpringDampingRatio() const
int WheelJoint::getAxis(lua_State *L)
{
- lua_pushnumber(L, joint->GetLocalAxisA().x);
- lua_pushnumber(L, joint->GetLocalAxisA().y);
+ b2Vec2 axis = joint->GetLocalAxisA();
+ getBodyA()->getWorldVector(axis.x, axis.y, axis.x, axis.y);
+ lua_pushnumber(L, axis.x);
+ lua_pushnumber(L, axis.y);
return 2;
}
diff --git a/src/modules/physics/box2d/wrap_ChainShape.cpp b/src/modules/physics/box2d/wrap_ChainShape.cpp
index 8cf7d8f85..a68e66772 100644
--- a/src/modules/physics/box2d/wrap_ChainShape.cpp
+++ b/src/modules/physics/box2d/wrap_ChainShape.cpp
@@ -37,18 +37,28 @@ ChainShape *luax_checkchainshape(lua_State *L, int idx)
int w_ChainShape_setNextVertex(lua_State *L)
{
ChainShape *c = luax_checkchainshape(L, 1);
- float x = (float)luaL_checknumber(L, 2);
- float y = (float)luaL_checknumber(L, 3);
- luax_catchexcept(L, [&](){ c->setNextVertex(x, y); });
+ if (lua_isnoneornil(L, 2))
+ c->setNextVertex();
+ else
+ {
+ float x = (float)luaL_checknumber(L, 2);
+ float y = (float)luaL_checknumber(L, 3);
+ luax_catchexcept(L, [&](){ c->setNextVertex(x, y); });
+ }
return 0;
}
int w_ChainShape_setPreviousVertex(lua_State *L)
{
ChainShape *c = luax_checkchainshape(L, 1);
- float x = (float)luaL_checknumber(L, 2);
- float y = (float)luaL_checknumber(L, 3);
- luax_catchexcept(L, [&](){ c->setPreviousVertex(x, y); });
+ if (lua_isnoneornil(L, 2))
+ c->setPreviousVertex();
+ else
+ {
+ float x = (float)luaL_checknumber(L, 2);
+ float y = (float)luaL_checknumber(L, 3);
+ luax_catchexcept(L, [&](){ c->setPreviousVertex(x, y); });
+ }
return 0;
}
@@ -82,6 +92,32 @@ int w_ChainShape_getPoint(lua_State *L)
return 2;
}
+int w_ChainShape_getNextVertex(lua_State *L)
+{
+ ChainShape *c = luax_checkchainshape(L, 1);
+ float x, y;
+ if (c->getNextVertex(x, y))
+ {
+ lua_pushnumber(L, x);
+ lua_pushnumber(L, y);
+ return 2;
+ }
+ return 0;
+}
+
+int w_ChainShape_getPreviousVertex(lua_State *L)
+{
+ ChainShape *c = luax_checkchainshape(L, 1);
+ float x, y;
+ if (c->getPreviousVertex(x, y))
+ {
+ lua_pushnumber(L, x);
+ lua_pushnumber(L, y);
+ return 2;
+ }
+ return 0;
+}
+
int w_ChainShape_getPoints(lua_State *L)
{
ChainShape *c = luax_checkchainshape(L, 1);
@@ -102,6 +138,8 @@ static const luaL_Reg w_ChainShape_functions[] =
{
{ "setNextVertex", w_ChainShape_setNextVertex },
{ "setPreviousVertex", w_ChainShape_setPreviousVertex },
+ { "getNextVertex", w_ChainShape_getNextVertex },
+ { "getPreviousVertex", w_ChainShape_getPreviousVertex },
{ "getChildEdge", w_ChainShape_getChildEdge },
{ "getVertexCount", w_ChainShape_getVertexCount },
{ "getPoint", w_ChainShape_getPoint },
diff --git a/src/modules/physics/box2d/wrap_EdgeShape.cpp b/src/modules/physics/box2d/wrap_EdgeShape.cpp
index 4dfceb324..53c8805ce 100644
--- a/src/modules/physics/box2d/wrap_EdgeShape.cpp
+++ b/src/modules/physics/box2d/wrap_EdgeShape.cpp
@@ -32,6 +32,60 @@ EdgeShape *luax_checkedgeshape(lua_State *L, int idx)
return luax_checktype(L, idx, PHYSICS_EDGE_SHAPE_ID);
}
+int w_EdgeShape_setNextVertex(lua_State *L)
+{
+ EdgeShape *t = luax_checkedgeshape(L, 1);
+ if (lua_isnoneornil(L, 2))
+ t->setNextVertex();
+ else
+ {
+ float x = (float)luaL_checknumber(L, 2);
+ float y = (float)luaL_checknumber(L, 3);
+ t->setNextVertex(x, y);
+ }
+ return 0;
+}
+
+int w_EdgeShape_setPreviousVertex(lua_State *L)
+{
+ EdgeShape *t = luax_checkedgeshape(L, 1);
+ if (lua_isnoneornil(L, 2))
+ t->setPreviousVertex();
+ else
+ {
+ float x = (float)luaL_checknumber(L, 2);
+ float y = (float)luaL_checknumber(L, 3);
+ t->setPreviousVertex(x, y);
+ }
+ return 0;
+}
+
+int w_EdgeShape_getNextVertex(lua_State *L)
+{
+ EdgeShape *t = luax_checkedgeshape(L, 1);
+ float x, y;
+ if (t->getNextVertex(x, y))
+ {
+ lua_pushnumber(L, x);
+ lua_pushnumber(L, y);
+ return 2;
+ }
+ return 0;
+}
+
+int w_EdgeShape_getPreviousVertex(lua_State *L)
+{
+ EdgeShape *t = luax_checkedgeshape(L, 1);
+ float x, y;
+ if (t->getPreviousVertex(x, y))
+ {
+ lua_pushnumber(L, x);
+ lua_pushnumber(L, y);
+ return 2;
+ }
+ return 0;
+}
+
int w_EdgeShape_getPoints(lua_State *L)
{
EdgeShape *t = luax_checkedgeshape(L, 1);
@@ -41,6 +95,10 @@ int w_EdgeShape_getPoints(lua_State *L)
static const luaL_Reg w_EdgeShape_functions[] =
{
+ { "setNextVertex", w_EdgeShape_setNextVertex },
+ { "setPreviousVertex", w_EdgeShape_setPreviousVertex },
+ { "getNextVertex", w_EdgeShape_getNextVertex },
+ { "getPreviousVertex", w_EdgeShape_getPreviousVertex },
{ "getPoints", w_EdgeShape_getPoints },
{ 0, 0 }
};
diff --git a/src/scripts/auto.lua b/src/scripts/auto.lua
index 351ced94d..d4fb77bec 100644
--- a/src/scripts/auto.lua
+++ b/src/scripts/auto.lua
@@ -108,8 +108,14 @@ end
for i, v in ipairs(arg) do
--run the auto function for every argument
--but do it with pcall, to catch errors
- v = v:gsub("%.lua$", ""):gsub("^(.+)/", "") -- normalize input
- local ok, err = pcall(auto, v)
+ local ok, err = true
+ v = v:gsub("^scripts/", "")
+ if v:match("/") then
+ ok, err = false, "not in scripts directory"
+ else
+ v = v:gsub("%.lua$", "") -- normalize input
+ ok, err = pcall(auto, v)
+ end
if not ok then
--inform people we've failed
print(v .. ": " .. err)