diff --git a/src/love.cpp b/src/love.cpp index 1ee6f6c00..90543acc1 100644 --- a/src/love.cpp +++ b/src/love.cpp @@ -172,45 +172,8 @@ static int l_print_sdl_log(lua_State *L) } #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. lua_State *L = luaL_newstate(); luaL_openlibs(L); @@ -269,12 +232,52 @@ int main(int argc, char **argv) // Call the returned boot function. lua_call(L, 0, 1); + int retval = 0; if (lua_isnumber(L, -1)) retval = (int) lua_tonumber(L, -1); 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) { for (int i = 0; i 1) + gl.matrices.projection.pop_back(); if (!switchingToOtherCanvas) { diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index 464923120..0b5b928d9 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -252,8 +252,6 @@ bool Graphics::setMode(int width, int height) created = true; - setViewportSize(width, height); - // Enable blending glEnable(GL_BLEND); @@ -310,6 +308,8 @@ bool Graphics::setMode(int width, int height) if (quadIndices == nullptr) quadIndices = new QuadIndices(20); + setViewportSize(width, height); + // Restore the graphics state. restoreState(states.back()); @@ -1658,13 +1658,10 @@ Graphics::Stats Graphics::getStats() const double Graphics::getSystemLimit(SystemLimit limittype) const { - GLfloat limits[2]; - switch (limittype) { 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: return (double) gl.getMaxTextureSize(); case Graphics::LIMIT_MULTI_CANVAS: diff --git a/src/modules/graphics/opengl/OpenGL.cpp b/src/modules/graphics/opengl/OpenGL.cpp index 42319a291..276eaead3 100644 --- a/src/modules/graphics/opengl/OpenGL.cpp +++ b/src/modules/graphics/opengl/OpenGL.cpp @@ -289,6 +289,10 @@ void OpenGL::initMaxValues() maxRenderbufferSamples = 0; glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits); + + GLfloat limits[2]; + glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, limits); + maxPointSize = limits[1]; } void OpenGL::initMatrices() @@ -656,6 +660,11 @@ int OpenGL::getMaxTextureUnits() const return maxTextureUnits; } +float OpenGL::getMaxPointSize() const +{ + return maxPointSize; +} + void OpenGL::updateTextureMemorySize(size_t oldsize, size_t newsize) { int64 memsize = (int64) stats.textureMemory + ((int64) newsize - (int64) oldsize); diff --git a/src/modules/graphics/opengl/OpenGL.h b/src/modules/graphics/opengl/OpenGL.h index 7ec940936..e4496fde4 100644 --- a/src/modules/graphics/opengl/OpenGL.h +++ b/src/modules/graphics/opengl/OpenGL.h @@ -377,6 +377,12 @@ public: **/ int getMaxTextureUnits() const; + /** + * Returns the maximum point size. + **/ + float getMaxPointSize() const; + + void updateTextureMemorySize(size_t oldsize, size_t newsize); /** @@ -408,6 +414,7 @@ private: int maxRenderTargets; int maxRenderbufferSamples; int maxTextureUnits; + float maxPointSize; Vendor vendor; diff --git a/src/modules/system/System.cpp b/src/modules/system/System.cpp index 61e2ef742..aa15571ea 100755 --- a/src/modules/system/System.cpp +++ b/src/modules/system/System.cpp @@ -26,20 +26,35 @@ #include #elif defined(LOVE_IOS) #include "common/ios.h" -#elif defined(LOVE_ANDROID) -#include "common/android.h" -#elif defined(LOVE_LINUX) -#include -//#include -//#include +#elif defined(LOVE_LINUX) || defined(LOVE_ANDROID) #include #include +#include #elif defined(LOVE_WINDOWS) #include "common/utf8.h" #include #include #pragma comment(lib, "shell32.lib") #endif +#if defined(LOVE_ANDROID) +#include "common/android.h" +#elif defined(LOVE_LINUX) +#include +#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 { @@ -50,12 +65,14 @@ System::System() { #if defined(LOVE_LINUX) // 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}; 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); #endif } diff --git a/src/modules/timer/Timer.cpp b/src/modules/timer/Timer.cpp index c9737842d..ce5cc7307 100644 --- a/src/modules/timer/Timer.cpp +++ b/src/modules/timer/Timer.cpp @@ -21,6 +21,7 @@ // LOVE #include "common/config.h" #include "common/int.h" +#include "common/delay.h" #include "Timer.h" #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 { return dt; diff --git a/src/modules/timer/Timer.h b/src/modules/timer/Timer.h index 53d94e843..760b9d8c1 100644 --- a/src/modules/timer/Timer.h +++ b/src/modules/timer/Timer.h @@ -50,7 +50,7 @@ public: * usually 1ms. * @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 diff --git a/src/modules/timer/sdl/Timer.cpp b/src/modules/timer/sdl/Timer.cpp index 528ed190e..7a6f9ff37 100644 --- a/src/modules/timer/sdl/Timer.cpp +++ b/src/modules/timer/sdl/Timer.cpp @@ -20,10 +20,6 @@ // LOVE #include "Timer.h" -#include "common/delay.h" - -// SDL -#include namespace love { @@ -34,15 +30,12 @@ namespace sdl 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() { - // Quit SDL timer. - SDL_QuitSubSystem(SDL_INIT_TIMER); } const char *Timer::getName() const @@ -50,12 +43,6 @@ const char *Timer::getName() const return "love.timer.sdl"; } -void Timer::sleep(double seconds) const -{ - if (seconds > 0) - love::sleep((unsigned int)(seconds*1000)); -} - } // sdl } // timer } // love diff --git a/src/modules/timer/sdl/Timer.h b/src/modules/timer/sdl/Timer.h index 95571d7c1..cd5e2ea10 100644 --- a/src/modules/timer/sdl/Timer.h +++ b/src/modules/timer/sdl/Timer.h @@ -37,11 +37,8 @@ public: Timer(); virtual ~Timer(); - const char *getName() const override; - void sleep(double seconds) const override; - }; // Timer } // sdl