Browse Source

Merge default into minor.

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

+ 42 - 43
src/love.cpp

@@ -172,45 +172,8 @@ static int l_print_sdl_log(lua_State *L)
 }
 }
 #endif
 #endif
 
 
-int main(int argc, char **argv)
+static int runlove(int argc, char **argv)
 {
 {
-	int retval = 0;
-
-#ifdef LOVE_IOS
-	int orig_argc = argc;
-	char **orig_argv = argv;
-
-	// on iOS we should never programmatically exit the app, so we'll just
-	// "restart" when that is attempted. Games which use threads might cause
-	// some issues if the threads aren't cleaned up properly...
-	while (true)
-	{
-		argc = orig_argc;
-		argv = orig_argv;
-#endif
-
-#ifdef LOVE_LEGENDARY_APP_ARGV_HACK
-	int hack_argc = 0;
-	char **hack_argv = 0;
-	get_app_arguments(argc, argv, hack_argc, hack_argv);
-	argc = hack_argc;
-	argv = hack_argv;
-#endif // LOVE_LEGENDARY_APP_ARGV_HACK
-
-	if (strcmp(LOVE_VERSION_STRING, love_version()) != 0)
-	{
-		printf("Version mismatch detected!\nLOVE binary is version %s\n"
-				"LOVE library is version %s\n", LOVE_VERSION_STRING, love_version());
-		return 1;
-	}
-
-	// Oh, you just want the version? Okay!
-	if (argc > 1 && strcmp(argv[1], "--version") == 0)
-	{
-		printf("LOVE %s (%s)\n", love_version(), love_codename());
-		return 0;
-	}
-
 	// Create the virtual machine.
 	// Create the virtual machine.
 	lua_State *L = luaL_newstate();
 	lua_State *L = luaL_newstate();
 	luaL_openlibs(L);
 	luaL_openlibs(L);
@@ -269,12 +232,52 @@ int main(int argc, char **argv)
 	// Call the returned boot function.
 	// Call the returned boot function.
 	lua_call(L, 0, 1);
 	lua_call(L, 0, 1);
 
 
+	int retval = 0;
 	if (lua_isnumber(L, -1))
 	if (lua_isnumber(L, -1))
 		retval = (int) lua_tonumber(L, -1);
 		retval = (int) lua_tonumber(L, -1);
 
 
 	lua_close(L);
 	lua_close(L);
 
 
-#if defined(LOVE_LEGENDARY_APP_ARGV_HACK)
+	return retval;
+}
+
+int main(int argc, char **argv)
+{
+	int retval = 0;
+
+#ifdef LOVE_LEGENDARY_APP_ARGV_HACK
+	int hack_argc = 0;
+	char **hack_argv = 0;
+	get_app_arguments(argc, argv, hack_argc, hack_argv);
+	argc = hack_argc;
+	argv = hack_argv;
+#endif // LOVE_LEGENDARY_APP_ARGV_HACK
+
+	if (strcmp(LOVE_VERSION_STRING, love_version()) != 0)
+	{
+		printf("Version mismatch detected!\nLOVE binary is version %s\n"
+			   "LOVE library is version %s\n", LOVE_VERSION_STRING, love_version());
+		return 1;
+	}
+
+	// Oh, you just want the version? Okay!
+	if (argc > 1 && strcmp(argv[1], "--version") == 0)
+	{
+		printf("LOVE %s (%s)\n", love_version(), love_codename());
+		return 0;
+	}
+
+#ifdef LOVE_IOS
+	// on iOS we should never programmatically exit the app, so we'll just
+	// "restart" when that is attempted. Games which use threads might cause
+	// some issues if the threads aren't cleaned up properly...
+	while (true)
+#endif
+	{
+		retval = runlove(argc, argv);
+	}
+
+#if defined(LOVE_LEGENDARY_APP_ARGV_HACK) && !defined(LOVE_IOS)
 	if (hack_argv)
 	if (hack_argv)
 	{
 	{
 		for (int i = 0; i<hack_argc; ++i)
 		for (int i = 0; i<hack_argc; ++i)
@@ -283,10 +286,6 @@ int main(int argc, char **argv)
 	}
 	}
 #endif // LOVE_LEGENDARY_APP_ARGV_HACK
 #endif // LOVE_LEGENDARY_APP_ARGV_HACK
 
 
-#ifdef LOVE_IOS
-	} // while (true)
-#endif
-
 #ifdef LOVE_ANDROID
 #ifdef LOVE_ANDROID
 	SDL_Quit();
 	SDL_Quit();
 #endif
 #endif

+ 2 - 1
src/modules/graphics/opengl/Canvas.cpp

@@ -521,7 +521,8 @@ void Canvas::stopGrab(bool switchingToOtherCanvas)
 	// Make sure the canvas texture is up to date if we're using MSAA.
 	// Make sure the canvas texture is up to date if we're using MSAA.
 	resolveMSAA(false);
 	resolveMSAA(false);
 
 
-	gl.matrices.projection.pop_back();
+	if (gl.matrices.projection.size() > 1)
+		gl.matrices.projection.pop_back();
 
 
 	if (!switchingToOtherCanvas)
 	if (!switchingToOtherCanvas)
 	{
 	{

+ 3 - 6
src/modules/graphics/opengl/Graphics.cpp

@@ -252,8 +252,6 @@ bool Graphics::setMode(int width, int height)
 
 
 	created = true;
 	created = true;
 
 
-	setViewportSize(width, height);
-
 	// Enable blending
 	// Enable blending
 	glEnable(GL_BLEND);
 	glEnable(GL_BLEND);
 
 
@@ -310,6 +308,8 @@ bool Graphics::setMode(int width, int height)
 	if (quadIndices == nullptr)
 	if (quadIndices == nullptr)
 		quadIndices = new QuadIndices(20);
 		quadIndices = new QuadIndices(20);
 
 
+	setViewportSize(width, height);
+
 	// Restore the graphics state.
 	// Restore the graphics state.
 	restoreState(states.back());
 	restoreState(states.back());
 
 
@@ -1658,13 +1658,10 @@ Graphics::Stats Graphics::getStats() const
 
 
 double Graphics::getSystemLimit(SystemLimit limittype) const
 double Graphics::getSystemLimit(SystemLimit limittype) const
 {
 {
-	GLfloat limits[2];
-
 	switch (limittype)
 	switch (limittype)
 	{
 	{
 	case Graphics::LIMIT_POINT_SIZE:
 	case Graphics::LIMIT_POINT_SIZE:
-		glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, limits);
-		return (double) limits[1];
+		return (double) gl.getMaxPointSize();
 	case Graphics::LIMIT_TEXTURE_SIZE:
 	case Graphics::LIMIT_TEXTURE_SIZE:
 		return (double) gl.getMaxTextureSize();
 		return (double) gl.getMaxTextureSize();
 	case Graphics::LIMIT_MULTI_CANVAS:
 	case Graphics::LIMIT_MULTI_CANVAS:

+ 9 - 0
src/modules/graphics/opengl/OpenGL.cpp

@@ -289,6 +289,10 @@ void OpenGL::initMaxValues()
 		maxRenderbufferSamples = 0;
 		maxRenderbufferSamples = 0;
 
 
 	glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
 	glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
+
+	GLfloat limits[2];
+	glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, limits);
+	maxPointSize = limits[1];
 }
 }
 
 
 void OpenGL::initMatrices()
 void OpenGL::initMatrices()
@@ -656,6 +660,11 @@ int OpenGL::getMaxTextureUnits() const
 	return maxTextureUnits;
 	return maxTextureUnits;
 }
 }
 
 
+float OpenGL::getMaxPointSize() const
+{
+	return maxPointSize;
+}
+
 void OpenGL::updateTextureMemorySize(size_t oldsize, size_t newsize)
 void OpenGL::updateTextureMemorySize(size_t oldsize, size_t newsize)
 {
 {
 	int64 memsize = (int64) stats.textureMemory + ((int64) newsize - (int64) oldsize);
 	int64 memsize = (int64) stats.textureMemory + ((int64) newsize - (int64) oldsize);

+ 7 - 0
src/modules/graphics/opengl/OpenGL.h

@@ -377,6 +377,12 @@ public:
 	 **/
 	 **/
 	int getMaxTextureUnits() const;
 	int getMaxTextureUnits() const;
 
 
+	/**
+	 * Returns the maximum point size.
+	 **/
+	float getMaxPointSize() const;
+
+
 	void updateTextureMemorySize(size_t oldsize, size_t newsize);
 	void updateTextureMemorySize(size_t oldsize, size_t newsize);
 
 
 	/**
 	/**
@@ -408,6 +414,7 @@ private:
 	int maxRenderTargets;
 	int maxRenderTargets;
 	int maxRenderbufferSamples;
 	int maxRenderbufferSamples;
 	int maxTextureUnits;
 	int maxTextureUnits;
+	float maxPointSize;
 
 
 	Vendor vendor;
 	Vendor vendor;
 
 

+ 27 - 10
src/modules/system/System.cpp

@@ -26,20 +26,35 @@
 #include <CoreServices/CoreServices.h>
 #include <CoreServices/CoreServices.h>
 #elif defined(LOVE_IOS)
 #elif defined(LOVE_IOS)
 #include "common/ios.h"
 #include "common/ios.h"
-#elif defined(LOVE_ANDROID)
-#include "common/android.h"
-#elif defined(LOVE_LINUX)
-#include <spawn.h>
-//#include <stdlib.h>
-//#include <unistd.h>
+#elif defined(LOVE_LINUX) || defined(LOVE_ANDROID)
 #include <signal.h>
 #include <signal.h>
 #include <sys/wait.h>
 #include <sys/wait.h>
+#include <errno.h>
 #elif defined(LOVE_WINDOWS)
 #elif defined(LOVE_WINDOWS)
 #include "common/utf8.h"
 #include "common/utf8.h"
 #include <shlobj.h>
 #include <shlobj.h>
 #include <shellapi.h>
 #include <shellapi.h>
 #pragma comment(lib, "shell32.lib")
 #pragma comment(lib, "shell32.lib")
 #endif
 #endif
+#if defined(LOVE_ANDROID)
+#include "common/android.h"
+#elif defined(LOVE_LINUX)
+#include <spawn.h>
+#endif
+
+#if defined(LOVE_LINUX)
+static void sigchld_handler(int sig)
+{
+	// Because waitpid can set errno, we need to save it.
+	auto old = errno;
+
+	// Reap whilst there are children waiting to be reaped.
+	while (waitpid(-1, nullptr, WNOHANG) > 0)
+		;
+
+	errno = old;
+}
+#endif
 
 
 namespace love
 namespace love
 {
 {
@@ -50,12 +65,14 @@ System::System()
 {
 {
 #if defined(LOVE_LINUX)
 #if defined(LOVE_LINUX)
 	// Enable automatic cleanup of zombie processes
 	// Enable automatic cleanup of zombie processes
+	// NOTE: We're using our own handler, instead of SA_NOCLDWAIT because the
+	// latter breaks wait, and thus os.execute.
+	// NOTE: This isn't perfect, due to multithreading our SIGCHLD can happen
+	// on a different thread than the one calling wait(), thus causing a race.
 	struct sigaction act = {0};
 	struct sigaction act = {0};
 	sigemptyset(&act.sa_mask);
 	sigemptyset(&act.sa_mask);
-	act.sa_handler = SIG_DFL;
-	act.sa_flags = SA_NOCLDWAIT;
-
-	// Requires linux 2.6 or higher, so anything remotely modern
+	act.sa_handler = sigchld_handler;
+	act.sa_flags = SA_RESTART;
 	sigaction(SIGCHLD, &act, nullptr);
 	sigaction(SIGCHLD, &act, nullptr);
 #endif
 #endif
 }
 }

+ 7 - 0
src/modules/timer/Timer.cpp

@@ -21,6 +21,7 @@
 // LOVE
 // LOVE
 #include "common/config.h"
 #include "common/config.h"
 #include "common/int.h"
 #include "common/int.h"
+#include "common/delay.h"
 #include "Timer.h"
 #include "Timer.h"
 
 
 #if defined(LOVE_WINDOWS)
 #if defined(LOVE_WINDOWS)
@@ -85,6 +86,12 @@ void Timer::step()
 	}
 	}
 }
 }
 
 
+void Timer::sleep(double seconds) const
+{
+	if (seconds > 0)
+		love::sleep((unsigned int)(seconds*1000));
+}
+
 double Timer::getDelta() const
 double Timer::getDelta() const
 {
 {
 	return dt;
 	return dt;

+ 1 - 1
src/modules/timer/Timer.h

@@ -50,7 +50,7 @@ public:
 	 * usually 1ms.
 	 * usually 1ms.
 	 * @param seconds The number of seconds to sleep for.
 	 * @param seconds The number of seconds to sleep for.
 	 **/
 	 **/
-	virtual void sleep(double seconds) const = 0;
+	virtual void sleep(double seconds) const;
 
 
 	/**
 	/**
 	 * Gets the time between the last two frames, assuming step is called
 	 * Gets the time between the last two frames, assuming step is called

+ 2 - 15
src/modules/timer/sdl/Timer.cpp

@@ -20,10 +20,6 @@
 
 
 // LOVE
 // LOVE
 #include "Timer.h"
 #include "Timer.h"
-#include "common/delay.h"
-
-// SDL
-#include <SDL.h>
 
 
 namespace love
 namespace love
 {
 {
@@ -34,15 +30,12 @@ namespace sdl
 
 
 Timer::Timer()
 Timer::Timer()
 {
 {
-	// Init the SDL timer system (needed for SDL_Delay.)
-	if (SDL_InitSubSystem(SDL_INIT_TIMER) < 0)
-		throw love::Exception("Could not initialize SDL timer subsystem (%s)", SDL_GetError());
+	// We don't need to initialize the SDL timer subsystem for SDL_Delay to
+	// function - and doing so causes SDL to create a worker thread.
 }
 }
 
 
 Timer::~Timer()
 Timer::~Timer()
 {
 {
-	// Quit SDL timer.
-	SDL_QuitSubSystem(SDL_INIT_TIMER);
 }
 }
 
 
 const char *Timer::getName() const
 const char *Timer::getName() const
@@ -50,12 +43,6 @@ const char *Timer::getName() const
 	return "love.timer.sdl";
 	return "love.timer.sdl";
 }
 }
 
 
-void Timer::sleep(double seconds) const
-{
-	if (seconds > 0)
-		love::sleep((unsigned int)(seconds*1000));
-}
-
 } // sdl
 } // sdl
 } // timer
 } // timer
 } // love
 } // love

+ 0 - 3
src/modules/timer/sdl/Timer.h

@@ -37,11 +37,8 @@ public:
 
 
 	Timer();
 	Timer();
 	virtual ~Timer();
 	virtual ~Timer();
-
 	const char *getName() const override;
 	const char *getName() const override;
 
 
-	void sleep(double seconds) const override;
-
 }; // Timer
 }; // Timer
 
 
 } // sdl
 } // sdl