Browse Source

Merge default into minor

--HG--
branch : minor
Alex Szpakowski 9 years ago
parent
commit
e9ac008f43

+ 77 - 5
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

+ 3 - 0
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.
   

+ 25 - 0
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)

+ 25 - 0
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)

+ 25 - 0
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)

+ 25 - 0
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)

+ 31 - 0
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)

+ 30 - 0
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)

+ 7 - 0
platform/xcode/macosx/love-macosx.plist

@@ -7,6 +7,10 @@
 	<key>CFBundleDocumentTypes</key>
 	<array>
 		<dict>
+			<key>CFBundleTypeExtensions</key>
+			<array>
+				<string>love</string>
+			</array>
 			<key>CFBundleTypeIconFile</key>
 			<string>GameIcon</string>
 			<key>CFBundleTypeName</key>
@@ -19,6 +23,8 @@
 			<array>
 				<string>org.love2d.love-game</string>
 			</array>
+			<key>LSTypeIsPackage</key>
+			<integer>1</integer>
 		</dict>
 		<dict>
 			<key>CFBundleTypeName</key>
@@ -73,6 +79,7 @@
 			<key>UTTypeConformsTo</key>
 			<array>
 				<string>com.pkware.zip-archive</string>
+				<string>com.apple.package</string>
 			</array>
 			<key>UTTypeDescription</key>
 			<string>LÖVE Project</string>

+ 5 - 1
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);
 }
 

+ 6 - 5
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()

+ 8 - 4
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

+ 43 - 1
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

+ 12 - 0
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.

+ 58 - 0
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;

+ 8 - 0
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.

+ 17 - 4
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);

+ 3 - 0
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();

+ 4 - 2
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;
 }
 

+ 4 - 2
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;
 }
 

+ 44 - 6
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 },

+ 58 - 0
src/modules/physics/box2d/wrap_EdgeShape.cpp

@@ -32,6 +32,60 @@ EdgeShape *luax_checkedgeshape(lua_State *L, int idx)
 	return luax_checktype<EdgeShape>(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 }
 };

+ 8 - 2
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)