From 9d293af17658587c5a39bdc937d57058af00d37d Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Sun, 4 May 2014 04:10:46 -0300 Subject: [PATCH 01/15] Fixed love.filesystem.setIdentity breaking if a file has been written to an old identity dir before the new setIdentity call --- src/modules/filesystem/physfs/Filesystem.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/modules/filesystem/physfs/Filesystem.cpp b/src/modules/filesystem/physfs/Filesystem.cpp index 748dbceea..914b28178 100644 --- a/src/modules/filesystem/physfs/Filesystem.cpp +++ b/src/modules/filesystem/physfs/Filesystem.cpp @@ -130,6 +130,11 @@ bool Filesystem::setIdentity(const char *ident, bool appendToPath) // (No error on fail, it means that the path doesn't exist). PHYSFS_addToSearchPath(save_path_full.c_str(), appendToPath); + // HACK: This forces setupWriteDirectory to be called the next time a file + // is opened for writing - otherwise it won't be called at all if it was + // already called at least once before. + PHYSFS_setWriteDir(nullptr); + return true; } From e25cdfc71c4809b9f616a11fe69ba15154288779 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Mon, 5 May 2014 00:27:42 -0300 Subject: [PATCH 02/15] Fixed creating and setting the write directory on some sandboxed operating systems --- src/modules/filesystem/physfs/Filesystem.cpp | 44 ++++++++++++++----- src/modules/filesystem/physfs/Filesystem.h | 4 +- .../filesystem/physfs/wrap_Filesystem.cpp | 4 +- 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/src/modules/filesystem/physfs/Filesystem.cpp b/src/modules/filesystem/physfs/Filesystem.cpp index 914b28178..66cbd2b35 100644 --- a/src/modules/filesystem/physfs/Filesystem.cpp +++ b/src/modules/filesystem/physfs/Filesystem.cpp @@ -176,16 +176,36 @@ bool Filesystem::setupWriteDirectory() if (save_identity.empty() || save_path_full.empty() || save_path_relative.empty()) return false; - // Set the appdata folder as writable directory. + // We need to make sure the write directory is created. To do that, we also + // need to make sure all its parent directories are also created. + std::string temp_writedir = getDriveRoot(save_path_full); + std::string temp_createdir = skipDriveRoot(save_path_full); + + // On some sandboxed platforms, physfs will break when its write directory + // is the root of the drive and it tries to create a folder (even if the + // folder's path is in a writable location.) If the user's home folder is + // in the save path, we'll try starting from there instead. + if (save_path_full.find(getUserDirectory()) == 0) + { + temp_writedir = getUserDirectory(); + temp_createdir = save_path_full.substr(getUserDirectory().length()); + + // Strip leading '/' characters from the path we want to create. + size_t startpos = temp_createdir.find_first_not_of('/'); + if (startpos != std::string::npos) + temp_createdir = temp_createdir.substr(startpos); + } + + // Set either '/' or the user's home as a writable directory. // (We must create the save folder before mounting it). - if (!PHYSFS_setWriteDir(getDriveRoot(save_path_full).c_str())) + if (!PHYSFS_setWriteDir(temp_writedir.c_str())) return false; - // Create the save folder. (We're now "at" %APPDATA%). - if (!createDirectory(skipDriveRoot(save_path_full).c_str())) + // Create the save folder. (We're now "at" either '/' or the user's home). + if (!createDirectory(temp_createdir.c_str())) { // Clear the write directory in case of error. - PHYSFS_setWriteDir(0); + PHYSFS_setWriteDir(nullptr); return false; } @@ -196,7 +216,7 @@ bool Filesystem::setupWriteDirectory() // Add the directory. (Will not be readded if already present). if (!PHYSFS_addToSearchPath(save_path_full.c_str(), 0)) { - PHYSFS_setWriteDir(0); // Clear the write directory in case of error. + PHYSFS_setWriteDir(nullptr); // Clear the write directory in case of error. return false; } @@ -332,12 +352,12 @@ const char *Filesystem::getWorkingDirectory() return cwd.c_str(); } -const char *Filesystem::getUserDirectory() +std::string Filesystem::getUserDirectory() { - return PHYSFS_getUserDir(); + return std::string(PHYSFS_getUserDir()); } -const char *Filesystem::getAppdataDirectory() +std::string Filesystem::getAppdataDirectory() { #ifdef LOVE_WINDOWS if (appdata.empty()) @@ -346,7 +366,7 @@ const char *Filesystem::getAppdataDirectory() appdata = to_utf8(w_appdata); replace_char(appdata, '\\', '/'); } - return appdata.c_str(); + return appdata; #elif defined(LOVE_MACOSX) if (appdata.empty()) { @@ -354,7 +374,7 @@ const char *Filesystem::getAppdataDirectory() udir.append("/Library/Application Support"); appdata = udir; } - return appdata.c_str(); + return appdata; #elif defined(LOVE_LINUX) if (appdata.empty()) { @@ -364,7 +384,7 @@ const char *Filesystem::getAppdataDirectory() else appdata = xdgdatahome; } - return appdata.c_str(); + return appdata; #else return getUserDirectory(); #endif diff --git a/src/modules/filesystem/physfs/Filesystem.h b/src/modules/filesystem/physfs/Filesystem.h index f9ccfecb3..025da9ac9 100644 --- a/src/modules/filesystem/physfs/Filesystem.h +++ b/src/modules/filesystem/physfs/Filesystem.h @@ -145,14 +145,14 @@ public: /** * Gets the user home directory. **/ - const char *getUserDirectory(); + std::string getUserDirectory(); /** * Gets the APPDATA directory. On Windows, this is the folder * in the %APPDATA% enviroment variable. On Linux, this is the * user home folder. **/ - const char *getAppdataDirectory(); + std::string getAppdataDirectory(); /** * Gets the full path of the save folder. diff --git a/src/modules/filesystem/physfs/wrap_Filesystem.cpp b/src/modules/filesystem/physfs/wrap_Filesystem.cpp index 0a89387e6..77845ef12 100644 --- a/src/modules/filesystem/physfs/wrap_Filesystem.cpp +++ b/src/modules/filesystem/physfs/wrap_Filesystem.cpp @@ -211,13 +211,13 @@ int w_getWorkingDirectory(lua_State *L) int w_getUserDirectory(lua_State *L) { - lua_pushstring(L, instance->getUserDirectory()); + luax_pushstring(L, instance->getUserDirectory()); return 1; } int w_getAppdataDirectory(lua_State *L) { - lua_pushstring(L, instance->getAppdataDirectory()); + luax_pushstring(L, instance->getAppdataDirectory()); return 1; } From 05d8543518b73aed1282f78c9a3dd9e0f1fd00db Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Mon, 5 May 2014 16:30:56 -0300 Subject: [PATCH 03/15] Improved performance of love.graphics.present slightly on some platforms --- src/modules/window/sdl/Window.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/modules/window/sdl/Window.cpp b/src/modules/window/sdl/Window.cpp index 7ea6044e8..049e639ac 100644 --- a/src/modules/window/sdl/Window.cpp +++ b/src/modules/window/sdl/Window.cpp @@ -304,6 +304,7 @@ void Window::setWindowGLAttributes(int fsaa, bool /* sRGB */) const SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1); + SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 0); // FSAA. SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, (fsaa > 0) ? 1 : 0); From d705b54198ed8a9939e5e22af19849d8ba7c32d9 Mon Sep 17 00:00:00 2001 From: Bart van Strien Date: Tue, 6 May 2014 19:35:02 +0200 Subject: [PATCH 04/15] Clean up unused variable after clang static analyzer run --- src/modules/sound/lullaby/Mpg123Decoder.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/sound/lullaby/Mpg123Decoder.cpp b/src/modules/sound/lullaby/Mpg123Decoder.cpp index a89b3ef68..01dc6c83f 100644 --- a/src/modules/sound/lullaby/Mpg123Decoder.cpp +++ b/src/modules/sound/lullaby/Mpg123Decoder.cpp @@ -117,7 +117,7 @@ int Mpg123Decoder::decode() size += numbytes; long rate = 0; int encoding = 0; - int ret = mpg123_getformat(handle, &rate, &channels, &encoding); + mpg123_getformat(handle, &rate, &channels, &encoding); if (rate == 0) rate = sampleRate; else @@ -126,7 +126,7 @@ int Mpg123Decoder::decode() channels = MPG123_STEREO; if (encoding == 0) encoding = MPG123_ENC_SIGNED_16; - ret = mpg123_format(handle, rate, channels, encoding); + int ret = mpg123_format(handle, rate, channels, encoding); if (ret != MPG123_OK) throw love::Exception("Could not set output format."); } From ce385ec27a0e578f1f1741f7b746ca461e38a52d Mon Sep 17 00:00:00 2001 From: Bart van Strien Date: Tue, 6 May 2014 19:48:50 +0200 Subject: [PATCH 05/15] Switch from vfork/exec to posix_spawn after clang static analyzer run --- src/modules/system/System.cpp | 50 +++++++++++++++-------------------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/src/modules/system/System.cpp b/src/modules/system/System.cpp index 397cfbb41..dd74c120f 100755 --- a/src/modules/system/System.cpp +++ b/src/modules/system/System.cpp @@ -25,8 +25,9 @@ #if defined(LOVE_MACOSX) #include #elif defined(LOVE_LINUX) -#include -#include +#include +//#include +//#include #include #elif defined(LOVE_WINDOWS) #include "common/utf8.h" @@ -53,12 +54,17 @@ std::string System::getOS() const #endif } +extern "C" +{ + extern char **environ; // The environment, always available +} + bool System::openURL(const std::string &url) const { - bool success = false; #if defined(LOVE_MACOSX) + bool success = false; // We could be lazy and use system("open " + url), but this is safer. CFURLRef cfurl = CFURLCreateWithBytes(nullptr, (const UInt8 *) url.c_str(), @@ -68,34 +74,24 @@ bool System::openURL(const std::string &url) const success = LSOpenCFURLRef(cfurl, nullptr) == noErr; CFRelease(cfurl); + return success; #elif defined(LOVE_LINUX) - // Spawn a child process, which we'll replace with xdg-open. - pid_t pid = vfork(); + pid_t pid; + const char *argv[] = {"xdg-open", url.c_str(), nullptr}; - if (pid == 0) // Child process. - { - // Replace the child process with xdg-open and pass in the URL. - execlp("xdg-open", "xdg-open", url.c_str(), nullptr); + // Note: at the moment this process inherits our file descriptors. + // Note: the below const_cast is really ugly as well. + if (posix_spawnp(&pid, "xdg-open", nullptr, nullptr, const_cast(argv), environ) != 0) + return false; - // exec will only return if it errored, so we should exit with non-zero. - _exit(1); - } - else if (pid > 0) // Parent process. - { - // Wait for xdg-open to complete (or fail.) - int status = 0; - if (waitpid(pid, &status, 0) == pid) - success = (status == 0); - else - success = false; - } + // Wait for xdg-open to complete (or fail.) + int status = 0; + if (waitpid(pid, &status, 0) == pid) + return (status == 0); else - { - // vfork() failed. - success = false; - } + return false; #elif defined(LOVE_WINDOWS) @@ -109,11 +105,9 @@ bool System::openURL(const std::string &url) const nullptr, SW_SHOW); - success = (int) result > 32; + return (int) result > 32; #endif - - return success; } bool System::getConstant(const char *in, System::PowerState &out) From 6a491ed0f004fa6a94fc27fa56fc5784b0084272 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Tue, 6 May 2014 21:24:26 -0300 Subject: [PATCH 06/15] Don't do unnecessary vertex buffer orphaning when calling SpriteBatch:unbind() on a SpriteBatch with the static usage hint --- src/modules/graphics/opengl/VertexBuffer.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/modules/graphics/opengl/VertexBuffer.cpp b/src/modules/graphics/opengl/VertexBuffer.cpp index 181c0aea8..d0e8c0f2f 100644 --- a/src/modules/graphics/opengl/VertexBuffer.cpp +++ b/src/modules/graphics/opengl/VertexBuffer.cpp @@ -182,10 +182,18 @@ void VBO::unmap() is_bound = true; } - // "orphan" current buffer to avoid implicit synchronisation on the GPU: - // http://www.seas.upenn.edu/~pcozzi/OpenGLInsights/OpenGLInsights-AsynchronousBufferTransfers.pdf - glBufferDataARB(getTarget(), (GLsizeiptr) getSize(), NULL, getUsage()); - glBufferDataARB(getTarget(), (GLsizeiptr) getSize(), memory_map, getUsage()); + if (getUsage() == GL_STATIC_DRAW) + { + // Upload the mapped data to the buffer. + glBufferSubDataARB(getTarget(), 0, (GLsizeiptr) getSize(), memory_map); + } + else + { + // "orphan" current buffer to avoid implicit synchronisation on the GPU: + // http://www.seas.upenn.edu/~pcozzi/OpenGLInsights/OpenGLInsights-AsynchronousBufferTransfers.pdf + glBufferDataARB(getTarget(), (GLsizeiptr) getSize(), NULL, getUsage()); + glBufferDataARB(getTarget(), (GLsizeiptr) getSize(), memory_map, getUsage()); + } is_mapped = false; } From 036f6eb8cbdce5f921eb5369fd27440cafd6ecf1 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Sat, 10 May 2014 16:52:40 -0300 Subject: [PATCH 07/15] Added an optional duration argument to Joystick:setVibration. --- src/modules/joystick/Joystick.h | 4 +- src/modules/joystick/sdl/Joystick.cpp | 120 ++++++++++++------ src/modules/joystick/sdl/Joystick.h | 10 +- src/modules/joystick/sdl/JoystickModule.cpp | 14 +- src/modules/joystick/sdl/wrap_Joystick.cpp | 3 +- .../joystick/sdl/wrap_JoystickModule.cpp | 4 +- 6 files changed, 98 insertions(+), 57 deletions(-) diff --git a/src/modules/joystick/Joystick.h b/src/modules/joystick/Joystick.h index dde6bebdc..7f76c3a9c 100644 --- a/src/modules/joystick/Joystick.h +++ b/src/modules/joystick/Joystick.h @@ -157,9 +157,9 @@ public: virtual int getID() const = 0; virtual bool isVibrationSupported() = 0; - virtual bool setVibration(float left, float right) = 0; + virtual bool setVibration(float left, float right, float duration = -1.0f) = 0; virtual bool setVibration() = 0; - virtual void getVibration(float &left, float &right) const = 0; + virtual void getVibration(float &left, float &right) = 0; static bool getConstant(const char *in, Hat &out); static bool getConstant(Hat in, const char *&out); diff --git a/src/modules/joystick/sdl/Joystick.cpp b/src/modules/joystick/sdl/Joystick.cpp index ed370a270..a7eccae0c 100644 --- a/src/modules/joystick/sdl/Joystick.cpp +++ b/src/modules/joystick/sdl/Joystick.cpp @@ -25,6 +25,11 @@ // C++ #include +#include + +#ifndef SDL_TICKS_PASSED +#define SDL_TICKS_PASSED(A, B) ((Sint32)((B) - (A)) <= 0) +#endif namespace love { @@ -34,9 +39,9 @@ namespace sdl { Joystick::Joystick(int id) - : joyhandle(0) - , controller(0) - , haptic(0) + : joyhandle(nullptr) + , controller(nullptr) + , haptic(nullptr) , instanceid(-1) , id(id) , vibration() @@ -44,9 +49,9 @@ Joystick::Joystick(int id) } Joystick::Joystick(int id, int joyindex) - : joyhandle(0) - , controller(0) - , haptic(0) + : joyhandle(nullptr) + , controller(nullptr) + , haptic(nullptr) , instanceid(-1) , id(id) , vibration() @@ -95,10 +100,7 @@ bool Joystick::open(int deviceindex) void Joystick::close() { if (haptic) - { - SDL_HapticRumbleStop(haptic); SDL_HapticClose(haptic); - } if (controller) SDL_GameControllerClose(controller); @@ -106,16 +108,16 @@ void Joystick::close() if (joyhandle) SDL_JoystickClose(joyhandle); - joyhandle = 0; - controller = 0; - haptic = 0; + joyhandle = nullptr; + controller = nullptr; + haptic = nullptr; instanceid = -1; vibration = Vibration(); } bool Joystick::isConnected() const { - return joyhandle != 0 && SDL_JoystickGetAttached(joyhandle); + return joyhandle != nullptr && SDL_JoystickGetAttached(joyhandle); } const char *Joystick::getName() const @@ -209,7 +211,7 @@ bool Joystick::openGamepad(int deviceindex) if (isGamepad()) { SDL_GameControllerClose(controller); - controller = 0; + controller = nullptr; } controller = SDL_GameControllerOpen(deviceindex); @@ -218,7 +220,7 @@ bool Joystick::openGamepad(int deviceindex) bool Joystick::isGamepad() const { - return controller != 0; + return controller != nullptr; } float Joystick::getGamepadAxis(love::joystick::Joystick::GamepadAxis axis) const @@ -289,13 +291,13 @@ bool Joystick::checkCreateHaptic() if (haptic) { SDL_HapticClose(haptic); - haptic = 0; + haptic = nullptr; } haptic = SDL_HapticOpenFromJoystick(joyhandle); vibration = Vibration(); - return haptic != 0; + return haptic != nullptr; } bool Joystick::isVibrationSupported() @@ -312,8 +314,8 @@ bool Joystick::isVibrationSupported() if (isGamepad() && (features & SDL_HAPTIC_CUSTOM) != 0) return true; - // Check SDL's simple rumble as a last resort. - if (SDL_HapticRumbleSupported(haptic) == 1) + // Test for simple sine wave support as a last resort. + if ((features & SDL_HAPTIC_SINE) != 0) return true; return false; @@ -325,7 +327,7 @@ bool Joystick::runVibrationEffect() { if (SDL_HapticUpdateEffect(haptic, vibration.id, &vibration.effect) == 0) { - if (SDL_HapticRunEffect(haptic, vibration.id, 1) != -1) + if (SDL_HapticRunEffect(haptic, vibration.id, 1) == 0) return true; } @@ -336,17 +338,14 @@ bool Joystick::runVibrationEffect() vibration.id = SDL_HapticNewEffect(haptic, &vibration.effect); - if (vibration.id != -1 && SDL_HapticRunEffect(haptic, vibration.id, 1) != -1) + if (vibration.id != -1 && SDL_HapticRunEffect(haptic, vibration.id, 1) == 0) return true; return false; } -bool Joystick::setVibration(float left, float right) +bool Joystick::setVibration(float left, float right, float duration) { - // TODO: support non-infinite durations? The working Tattiebogle Xbox - // controller driver in OS X seems to ignore durations under 1 second. - left = std::min(std::max(left, 0.0f), 1.0f); right = std::min(std::max(right, 0.0f), 1.0f); @@ -356,24 +355,32 @@ bool Joystick::setVibration(float left, float right) if (!checkCreateHaptic()) return false; + Uint32 length = SDL_HAPTIC_INFINITY; + if (duration >= 0.0f) + { + float maxduration = std::numeric_limits::max() / 1000.0f; + length = Uint32(std::min(duration, maxduration) * 1000); + } + bool success = false; unsigned int features = SDL_HapticQuery(haptic); + int axes = SDL_HapticNumAxes(haptic); if ((features & SDL_HAPTIC_LEFTRIGHT) != 0) { memset(&vibration.effect, 0, sizeof(SDL_HapticEffect)); vibration.effect.type = SDL_HAPTIC_LEFTRIGHT; - vibration.effect.leftright.length = SDL_HAPTIC_INFINITY; + vibration.effect.leftright.length = length; vibration.effect.leftright.large_magnitude = Uint16(left * LOVE_UINT16_MAX); vibration.effect.leftright.small_magnitude = Uint16(right * LOVE_UINT16_MAX); success = runVibrationEffect(); } - // Some gamepad drivers only give support for controlling the motors via - // a custom FF effect. - if (!success && isGamepad() && (features & SDL_HAPTIC_CUSTOM) != 0) + // Some gamepad drivers only give support for controlling individual motors + // through a custom FF effect. + if (!success && isGamepad() && (features & SDL_HAPTIC_CUSTOM) && axes == 2) { // NOTE: this may cause issues with drivers which support custom effects // but aren't similar to https://github.com/d235j/360Controller . @@ -385,7 +392,7 @@ bool Joystick::setVibration(float left, float right) memset(&vibration.effect, 0, sizeof(SDL_HapticEffect)); vibration.effect.type = SDL_HAPTIC_CUSTOM; - vibration.effect.custom.length = SDL_HAPTIC_INFINITY; + vibration.effect.custom.length = length; vibration.effect.custom.channels = 2; vibration.effect.custom.period = 10; vibration.effect.custom.samples = 2; @@ -394,19 +401,36 @@ bool Joystick::setVibration(float left, float right) success = runVibrationEffect(); } - // Fall back to a simple rumble if all else fails. SDL's simple rumble API - // only supports a single strength value. - if (!success && SDL_HapticRumbleInit(haptic) == 0) + // Fall back to a simple sine wave if all else fails. This only supports a + // single strength value. + if (!success && (features & SDL_HAPTIC_SINE) != 0) { + memset(&vibration.effect, 0, sizeof(SDL_HapticEffect)); + vibration.effect.type = SDL_HAPTIC_SINE; + + vibration.effect.periodic.length = length; + vibration.effect.periodic.period = 10; + float strength = std::max(left, right); - int played = SDL_HapticRumblePlay(haptic, strength, SDL_HAPTIC_INFINITY); - success = (played == 0); + vibration.effect.periodic.magnitude = Sint16(strength * 0x7FFF); + + success = runVibrationEffect(); } if (success) { vibration.left = left; vibration.right = right; + + if (length == SDL_HAPTIC_INFINITY) + vibration.endtime = SDL_HAPTIC_INFINITY; + else + vibration.endtime = SDL_GetTicks() + length; + } + else + { + vibration.left = vibration.right = 0.0f; + vibration.endtime = SDL_HAPTIC_INFINITY; } return success; @@ -417,12 +441,7 @@ bool Joystick::setVibration() bool success = true; if (SDL_WasInit(SDL_INIT_HAPTIC) && haptic && SDL_HapticIndex(haptic) != -1) - { - // Stop all playing effects on the haptic device. - // FIXME: We should only stop the vibration effect, in case we use the - // Haptic API for other things in the future. - success = (SDL_HapticStopAll(haptic) == 0); - } + success = (SDL_HapticStopEffect(haptic, vibration.id) == 0); if (success) vibration.left = vibration.right = 0.0f; @@ -430,8 +449,25 @@ bool Joystick::setVibration() return success; } -void Joystick::getVibration(float &left, float &right) const +void Joystick::getVibration(float &left, float &right) { + if (vibration.endtime != SDL_HAPTIC_INFINITY) + { + // With some drivers, the effect physically stops at the right time, but + // SDL_HapticGetEffectStatus still thinks it's playing. So we explicitly + // stop it once it's done, just to be sure. + if (SDL_TICKS_PASSED(SDL_GetTicks(), vibration.endtime)) + { + setVibration(); + vibration.endtime = SDL_HAPTIC_INFINITY; + } + } + + // Check if the haptic effect has stopped playing. + int id = vibration.id; + if (!haptic || id == -1 || SDL_HapticGetEffectStatus(haptic, id) != 1) + vibration.left = vibration.right = 0.0f; + left = vibration.left; right = vibration.right; } diff --git a/src/modules/joystick/sdl/Joystick.h b/src/modules/joystick/sdl/Joystick.h index 929cb5454..6d9cdaba8 100644 --- a/src/modules/joystick/sdl/Joystick.h +++ b/src/modules/joystick/sdl/Joystick.h @@ -74,9 +74,9 @@ public: int getID() const; bool isVibrationSupported(); - bool setVibration(float left, float right); + bool setVibration(float left, float right, float duration = -1.0f); bool setVibration(); - void getVibration(float &left, float &right) const; + void getVibration(float &left, float &right); static bool getConstant(Hat in, Uint8 &out); static bool getConstant(Uint8 in, Hat &out); @@ -111,8 +111,12 @@ private: Uint16 data[4]; int id; + Uint32 endtime; + Vibration() - : left(0.0f), right(0.0f), effect(), data(), id(-1) + : left(0.0f), right(0.0f) + , effect(), data(), id(-1) + , endtime(SDL_HAPTIC_INFINITY) {} } vibration; diff --git a/src/modules/joystick/sdl/JoystickModule.cpp b/src/modules/joystick/sdl/JoystickModule.cpp index f037927b1..ab0a28b16 100644 --- a/src/modules/joystick/sdl/JoystickModule.cpp +++ b/src/modules/joystick/sdl/JoystickModule.cpp @@ -77,7 +77,7 @@ const char *JoystickModule::getName() const love::joystick::Joystick *JoystickModule::getJoystick(int joyindex) { if (joyindex < 0 || (size_t) joyindex >= activeSticks.size()) - return 0; + return nullptr; return activeSticks[joyindex]; } @@ -107,13 +107,13 @@ love::joystick::Joystick *JoystickModule::getJoystickFromID(int instanceid) return activeSticks[i]; } - return 0; + return nullptr; } love::joystick::Joystick *JoystickModule::addJoystick(int deviceindex) { if (deviceindex < 0 || deviceindex >= SDL_NumJoysticks()) - return 0; + return nullptr; std::string guidstr = getDeviceGUID(deviceindex); joystick::Joystick *joystick = 0; @@ -140,7 +140,7 @@ love::joystick::Joystick *JoystickModule::addJoystick(int deviceindex) removeJoystick(joystick); if (!joystick->open(deviceindex)) - return 0; + return nullptr; // Make sure multiple instances of the same physical joystick aren't added // to the active list. @@ -262,7 +262,7 @@ bool JoystickModule::setGamepadMapping(const std::string &guid, Joystick::Gamepa if (status == 1) checkGamepads(guid); - return status >= 0; + return status >= 0; } Joystick::JoystickInput JoystickModule::getGamepadMapping(const std::string &guid, Joystick::GamepadInput gpinput) @@ -318,7 +318,7 @@ std::string JoystickModule::stringFromGamepadInput(Joystick::GamepadInput gpinpu SDL_GameControllerAxis sdlaxis; SDL_GameControllerButton sdlbutton; - const char *gpinputname = 0; + const char *gpinputname = nullptr; switch (gpinput.type) { @@ -435,7 +435,7 @@ void JoystickModule::checkGamepads(const std::string &guid) const // Big hack time: open the index as a game controller and compare // the underlying joystick handle to the active stick's. SDL_GameController *ctrl = SDL_GameControllerOpen(d_index); - if (ctrl == NULL) + if (ctrl == nullptr) continue; SDL_Joystick *stick = SDL_GameControllerGetJoystick(ctrl); diff --git a/src/modules/joystick/sdl/wrap_Joystick.cpp b/src/modules/joystick/sdl/wrap_Joystick.cpp index a0eb45694..90a3f4d3f 100644 --- a/src/modules/joystick/sdl/wrap_Joystick.cpp +++ b/src/modules/joystick/sdl/wrap_Joystick.cpp @@ -207,7 +207,8 @@ int w_Joystick_setVibration(lua_State *L) { float left = (float) luaL_checknumber(L, 2); float right = (float) luaL_optnumber(L, 3, left); - success = j->setVibration(left, right); + float duration = (float) luaL_optnumber(L, 4, -1.0); // -1 is infinite. + success = j->setVibration(left, right, duration); } luax_pushboolean(L, success); diff --git a/src/modules/joystick/sdl/wrap_JoystickModule.cpp b/src/modules/joystick/sdl/wrap_JoystickModule.cpp index a069e0156..7a438ff16 100644 --- a/src/modules/joystick/sdl/wrap_JoystickModule.cpp +++ b/src/modules/joystick/sdl/wrap_JoystickModule.cpp @@ -28,7 +28,7 @@ namespace joystick namespace sdl { -static JoystickModule *instance = 0; +static JoystickModule *instance = nullptr; int w_getJoysticks(lua_State *L) { @@ -194,7 +194,7 @@ static const lua_CFunction types[] = extern "C" int luaopen_love_joystick(lua_State *L) { - if (instance == 0) + if (instance == nullptr) { EXCEPT_GUARD(instance = new JoystickModule();) } From 408a5931138dbbbcb0572c18836dd4962df92494 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Tue, 13 May 2014 20:54:58 -0300 Subject: [PATCH 08/15] Added support for several specific Canvas formats. Also added love.graphics.hasCanvasFormat. The list includes RGBA with 4-bit components, RGBA with 10-bit R, G, and B components and a 2-bit alpha component, RGB with 9-bit RGB components and a 5-bit exponent component (for HDR rendering), and several more. --HG-- branch : Canvas-formats --- src/modules/graphics/Texture.cpp | 20 -- src/modules/graphics/Texture.h | 14 -- src/modules/graphics/opengl/Canvas.cpp | 176 ++++++++++++++---- src/modules/graphics/opengl/Canvas.h | 35 +++- src/modules/graphics/opengl/Graphics.cpp | 21 ++- src/modules/graphics/opengl/Graphics.h | 6 +- src/modules/graphics/opengl/Image.cpp | 24 ++- src/modules/graphics/opengl/Image.h | 24 ++- src/modules/graphics/opengl/wrap_Canvas.cpp | 6 +- src/modules/graphics/opengl/wrap_Graphics.cpp | 32 ++-- src/modules/graphics/opengl/wrap_Graphics.h | 1 + 11 files changed, 249 insertions(+), 110 deletions(-) diff --git a/src/modules/graphics/Texture.cpp b/src/modules/graphics/Texture.cpp index 0a8d85541..477eb33cb 100644 --- a/src/modules/graphics/Texture.cpp +++ b/src/modules/graphics/Texture.cpp @@ -109,16 +109,6 @@ bool Texture::getConstant(WrapMode in, const char *&out) return wrapModes.find(in, out); } -bool Texture::getConstant(const char *in, Format &out) -{ - return formats.find(in, out); -} - -bool Texture::getConstant(Format in, const char *&out) -{ - return formats.find(in, out); -} - StringMap::Entry Texture::filterModeEntries[] = { { "linear", Texture::FILTER_LINEAR }, @@ -135,15 +125,5 @@ StringMap::Entry Texture::wrapModeEnt StringMap Texture::wrapModes(Texture::wrapModeEntries, sizeof(Texture::wrapModeEntries)); -StringMap::Entry Texture::formatEntries[] = -{ - {"normal", Texture::FORMAT_NORMAL}, - {"hdr", Texture::FORMAT_HDR}, - {"srgb", Texture::FORMAT_SRGB}, -}; - -StringMap Texture::formats(Texture::formatEntries, sizeof(Texture::formatEntries)); - - } // graphics } // love diff --git a/src/modules/graphics/Texture.h b/src/modules/graphics/Texture.h index d9c83171e..7b5a525a4 100644 --- a/src/modules/graphics/Texture.h +++ b/src/modules/graphics/Texture.h @@ -55,14 +55,6 @@ public: FILTER_MAX_ENUM }; - enum Format - { - FORMAT_NORMAL, - FORMAT_HDR, - FORMAT_SRGB, - FORMAT_MAX_ENUM - }; - struct Filter { Filter(); @@ -119,9 +111,6 @@ public: static bool getConstant(const char *in, WrapMode &out); static bool getConstant(WrapMode in, const char *&out); - static bool getConstant(const char *in, Format &out); - static bool getConstant(Format in, const char *&out); - protected: int width; @@ -143,9 +132,6 @@ private: static StringMap::Entry wrapModeEntries[]; static StringMap wrapModes; - static StringMap::Entry formatEntries[]; - static StringMap formats; - }; // Texture } // graphics diff --git a/src/modules/graphics/opengl/Canvas.cpp b/src/modules/graphics/opengl/Canvas.cpp index 58ee616c4..6cb2f7e14 100644 --- a/src/modules/graphics/opengl/Canvas.cpp +++ b/src/modules/graphics/opengl/Canvas.cpp @@ -423,7 +423,7 @@ static void getStrategy() } } -Canvas::Canvas(int width, int height, Texture::Format format, int fsaa) +Canvas::Canvas(int width, int height, Format format, int fsaa) : fbo(0) , resolve_fbo(0) , texture(0) @@ -525,39 +525,33 @@ bool Canvas::loadVolatile() return false; } + if (!isFormatSupported(format)) + { + status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; + return false; + } + glGenTextures(1, &texture); gl.bindTexture(texture); setFilter(filter); setWrap(wrap); - GLint internalformat; - GLenum textype; - switch (format) - { - case Texture::FORMAT_HDR: - internalformat = GL_RGBA16F; - textype = GL_FLOAT; - break; - case Texture::FORMAT_SRGB: - internalformat = GL_SRGB8_ALPHA8; - textype = GL_UNSIGNED_BYTE; - break; - case Texture::FORMAT_NORMAL: - default: - internalformat = GL_RGBA8; - textype = GL_UNSIGNED_BYTE; - } + GLenum internalformat = GL_RGBA; + GLenum externalformat = GL_RGBA; + GLenum textype = GL_UNSIGNED_BYTE; + + convertFormat(format, internalformat, externalformat, textype); while (glGetError() != GL_NO_ERROR) /* Clear the error buffer. */; glTexImage2D(GL_TEXTURE_2D, 0, - internalformat, + (GLint) internalformat, width, height, 0, - GL_RGBA, + externalformat, textype, nullptr); @@ -981,41 +975,149 @@ bool Canvas::resolveMSAA() return true; } +Canvas::Format Canvas::getSizedFormat(Canvas::Format format) +{ + switch (format) + { + case FORMAT_NORMAL: + return FORMAT_RGBA8; + case FORMAT_HDR: + return FORMAT_RGBA16F; + default: + return format; + } +} + +void Canvas::convertFormat(Canvas::Format format, GLenum &internalformat, GLenum &externalformat, GLenum &type) +{ + format = getSizedFormat(format); + externalformat = GL_RGBA; + + switch (format) + { + case FORMAT_RGBA8: + default: + internalformat = GL_RGBA8; + type = GL_UNSIGNED_BYTE; + break; + case FORMAT_RGBA4: + internalformat = GL_RGBA4; + type = GL_UNSIGNED_SHORT_4_4_4_4; + break; + case FORMAT_RGB5A1: + internalformat = GL_RGB5_A1; + type = GL_UNSIGNED_SHORT_5_5_5_1; + break; + case FORMAT_RGB565: + internalformat = GL_RGB565; + externalformat = GL_RGB; + type = GL_UNSIGNED_SHORT_5_6_5; + break; + case FORMAT_RGB10A2: + internalformat = GL_RGB10_A2; + type = GL_UNSIGNED_INT_10_10_10_2; + break; + case FORMAT_RGB9E5: + internalformat = GL_RGB9_E5; + externalformat = GL_RGB; + type = GL_RGB9_E5; + case FORMAT_RG11B10F: + internalformat = GL_R11F_G11F_B10F; + externalformat = GL_RGB; + type = GL_UNSIGNED_INT_10F_11F_11F_REV; + case FORMAT_RGBA16F: + internalformat = GL_RGBA16F; + type = GL_FLOAT; + break; + case FORMAT_RGBA32F: + internalformat = GL_RGBA32F; + type = GL_FLOAT; + break; + case FORMAT_SRGB: + internalformat = GL_SRGB8_ALPHA8; + type = GL_UNSIGNED_BYTE; + break; + } +} + bool Canvas::isSupported() { getStrategy(); return (strategy != &strategyNone); } -bool Canvas::isHDRSupported() -{ - return GLEE_VERSION_3_0 || (isSupported() && GLEE_ARB_texture_float); -} - -bool Canvas::isSRGBSupported() -{ - if (GLEE_VERSION_3_0) - return true; - - if (!isSupported()) - return false; - - return (GLEE_ARB_framebuffer_sRGB || GLEE_EXT_framebuffer_sRGB) - && GLEE_EXT_texture_sRGB; -} - bool Canvas::isMultiCanvasSupported() { // system must support at least 4 simultanious active canvases. return gl.getMaxRenderTargets() >= 4; } +bool Canvas::isFormatSupported(Canvas::Format format) +{ + if (!isSupported()) + return false; + + format = getSizedFormat(format); + + switch (format) + { + case FORMAT_RGBA8: + case FORMAT_RGBA4: + case FORMAT_RGB5A1: + case FORMAT_RGB10A2: + return true; + case FORMAT_RGB565: + return GLEE_VERSION_4_2 || GLEE_ARB_ES2_compatibility; + case FORMAT_RGB9E5: + return GLEE_VERSION_3_0 || GLEE_EXT_texture_shared_exponent; + case FORMAT_RG11B10F: + return GLEE_VERSION_3_0 || (GLEE_ARB_texture_float && GLEE_ARB_color_buffer_float + && GLEE_EXT_packed_float); + case FORMAT_RGBA16F: + case FORMAT_RGBA32F: + return GLEE_VERSION_3_0 || (GLEE_ARB_texture_float && GLEE_ARB_color_buffer_float); + case FORMAT_SRGB: + return GLEE_VERSION_3_0 || ((GLEE_ARB_framebuffer_sRGB || GLEE_EXT_framebuffer_sRGB) + && (GLEE_VERSION_2_1 || GLEE_EXT_texture_sRGB)); + default: + return false; + } +} + void Canvas::bindDefaultCanvas() { if (current != nullptr) current->stopGrab(); } +bool Canvas::getConstant(const char *in, Format &out) +{ + return formats.find(in, out); +} + +bool Canvas::getConstant(Format in, const char *&out) +{ + return formats.find(in, out); +} + +StringMap::Entry Canvas::formatEntries[] = +{ + {"normal", Canvas::FORMAT_NORMAL}, + {"hdr", Canvas::FORMAT_HDR}, + {"rgba8", Canvas::FORMAT_RGBA8}, + {"rgba4", Canvas::FORMAT_RGBA4}, + {"rgb5a1", Canvas::FORMAT_RGB5A1}, + {"rgb565", Canvas::FORMAT_RGB565}, + {"rgb10a2", Canvas::FORMAT_RGB10A2}, + {"rgb9e5", Canvas::FORMAT_RGB9E5}, + {"rg11b10f", Canvas::FORMAT_RG11B10F}, + {"rgba16f", Canvas::FORMAT_RGBA16F}, + {"rgba32f", Canvas::FORMAT_RGBA32F}, + {"srgb", Canvas::FORMAT_SRGB}, +}; + +StringMap Canvas::formats(Canvas::formatEntries, sizeof(Canvas::formatEntries)); + } // opengl } // graphics } // love diff --git a/src/modules/graphics/opengl/Canvas.h b/src/modules/graphics/opengl/Canvas.h index 2d87b0bbc..41fb3b1fa 100644 --- a/src/modules/graphics/opengl/Canvas.h +++ b/src/modules/graphics/opengl/Canvas.h @@ -25,6 +25,7 @@ #include "image/Image.h" #include "image/ImageData.h" #include "common/Matrix.h" +#include "common/StringMap.h" #include "Texture.h" #include "OpenGL.h" @@ -39,7 +40,25 @@ class Canvas : public Texture { public: - Canvas(int width, int height, Texture::Format format = Texture::FORMAT_NORMAL, int fsaa = 0); + // Different Canvas render target formats. + enum Format + { + FORMAT_NORMAL, + FORMAT_HDR, + FORMAT_RGBA8, + FORMAT_RGBA4, + FORMAT_RGB5A1, + FORMAT_RGB565, + FORMAT_RGB10A2, + FORMAT_RGB9E5, + FORMAT_RG11B10F, + FORMAT_RGBA16F, + FORMAT_RGBA32F, + FORMAT_SRGB, + FORMAT_MAX_ENUM + }; + + Canvas(int width, int height, Format format = FORMAT_NORMAL, int fsaa = 0); virtual ~Canvas(); // Implements Volatile. @@ -85,7 +104,7 @@ public: return status; } - inline Texture::Format getTextureFormat() const + inline Format getTextureFormat() const { return format; } @@ -98,9 +117,8 @@ public: bool resolveMSAA(); static bool isSupported(); - static bool isHDRSupported(); - static bool isSRGBSupported(); static bool isMultiCanvasSupported(); + static bool isFormatSupported(Format format); static Canvas *current; static void bindDefaultCanvas(); @@ -111,10 +129,16 @@ public: // Whether the main screen should have linear -> sRGB conversions enabled. static bool screenHasSRGB; + static bool getConstant(const char *in, Format &out); + static bool getConstant(Format in, const char *&out); + private: bool createFSAAFBO(GLenum internalformat); + static Format getSizedFormat(Format format); + static void convertFormat(Format format, GLenum &internalformat, GLenum &externalformat, GLenum &type); + GLuint fbo; GLuint resolve_fbo; @@ -134,6 +158,9 @@ private: void setupGrab(); void drawv(const Matrix &t, const Vertex *v); + static StringMap::Entry formatEntries[]; + static StringMap formats; + }; // Canvas } // opengl diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index 68b71f379..a78908736 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -409,7 +409,7 @@ void Graphics::discardStencil() activeStencil = false; } -Image *Graphics::newImage(love::image::ImageData *data, Texture::Format format) +Image *Graphics::newImage(love::image::ImageData *data, Image::Format format) { // Create the image. Image *image = new Image(data, format); @@ -436,7 +436,7 @@ Image *Graphics::newImage(love::image::ImageData *data, Texture::Format format) return image; } -Image *Graphics::newImage(love::image::CompressedData *cdata, Texture::Format format) +Image *Graphics::newImage(love::image::CompressedData *cdata, Image::Format format) { // Create the image. Image *image = new Image(cdata, format); @@ -483,13 +483,14 @@ ParticleSystem *Graphics::newParticleSystem(Texture *texture, int size) return new ParticleSystem(texture, size); } -Canvas *Graphics::newCanvas(int width, int height, Texture::Format format, int fsaa) +Canvas *Graphics::newCanvas(int width, int height, Canvas::Format format, int fsaa) { - if (format == Texture::FORMAT_HDR && !Canvas::isHDRSupported()) - throw Exception("HDR Canvases are not supported by your OpenGL implementation"); - - if (format == Texture::FORMAT_SRGB && !Canvas::isSRGBSupported()) - throw Exception("sRGB Canvases are not supported by your OpenGL implementation"); + if (!Canvas::isFormatSupported(format)) + { + const char *fstr = "rgba8"; + Canvas::getConstant(format, fstr); + throw love::Exception("The %s canvas format is not supported by your OpenGL implementation.", fstr); + } if (width > gl.getMaxTextureSize()) throw Exception("Cannot create canvas: width of %d pixels is too large for this system.", width); @@ -540,8 +541,8 @@ Canvas *Graphics::newCanvas(int width, int height, Texture::Format format, int f } canvas->release(); - throw Exception(error_string.str().c_str()); - return NULL; // never reached + throw Exception("%s", error_string.str().c_str()); + return nullptr; // never reached } Shader *Graphics::newShader(const Shader::ShaderSources &sources) diff --git a/src/modules/graphics/opengl/Graphics.h b/src/modules/graphics/opengl/Graphics.h index 7ab7560cd..4e295eedf 100644 --- a/src/modules/graphics/opengl/Graphics.h +++ b/src/modules/graphics/opengl/Graphics.h @@ -194,8 +194,8 @@ public: /** * Creates an Image object with padding and/or optimization. **/ - Image *newImage(love::image::ImageData *data, Texture::Format format = Texture::FORMAT_NORMAL); - Image *newImage(love::image::CompressedData *cdata, Texture::Format format = Texture::FORMAT_NORMAL); + Image *newImage(love::image::ImageData *data, Image::Format format = Image::FORMAT_NORMAL); + Image *newImage(love::image::CompressedData *cdata, Image::Format format = Image::FORMAT_NORMAL); Quad *newQuad(Quad::Viewport v, float sw, float sh); @@ -208,7 +208,7 @@ public: ParticleSystem *newParticleSystem(Texture *texture, int size); - Canvas *newCanvas(int width, int height, Texture::Format format = Texture::FORMAT_NORMAL, int fsaa = 0); + Canvas *newCanvas(int width, int height, Canvas::Format format = Canvas::FORMAT_NORMAL, int fsaa = 0); Shader *newShader(const Shader::ShaderSources &sources); diff --git a/src/modules/graphics/opengl/Image.cpp b/src/modules/graphics/opengl/Image.cpp index 2166fd4a5..b7a37977d 100644 --- a/src/modules/graphics/opengl/Image.cpp +++ b/src/modules/graphics/opengl/Image.cpp @@ -36,7 +36,7 @@ float Image::maxMipmapSharpness = 0.0f; Texture::FilterMode Image::defaultMipmapFilter = Texture::FILTER_NONE; float Image::defaultMipmapSharpness = 0.0f; -Image::Image(love::image::ImageData *data, Texture::Format format) +Image::Image(love::image::ImageData *data, Format format) : data(data) , cdata(nullptr) , paddedWidth(width) @@ -55,7 +55,7 @@ Image::Image(love::image::ImageData *data, Texture::Format format) preload(); } -Image::Image(love::image::CompressedData *cdata, Texture::Format format) +Image::Image(love::image::CompressedData *cdata, Format format) : data(nullptr) , cdata(cdata) , paddedWidth(width) @@ -504,7 +504,7 @@ bool Image::refresh() return true; } -Texture::Format Image::getFormat() const +Image::Format Image::getFormat() const { return format; } @@ -663,6 +663,24 @@ bool Image::hasSRGBSupport() return GLEE_VERSION_2_1 || GLEE_EXT_texture_sRGB; } +bool Image::getConstant(const char *in, Format &out) +{ + return formats.find(in, out); +} + +bool Image::getConstant(Format in, const char *&out) +{ + return formats.find(in, out); +} + +StringMap::Entry Image::formatEntries[] = +{ + {"normal", Image::FORMAT_NORMAL}, + {"srgb", Image::FORMAT_SRGB}, +}; + +StringMap Image::formats(Image::formatEntries, sizeof(Image::formatEntries)); + } // opengl } // graphics } // love diff --git a/src/modules/graphics/opengl/Image.h b/src/modules/graphics/opengl/Image.h index d23f385ec..6e24b17c6 100644 --- a/src/modules/graphics/opengl/Image.h +++ b/src/modules/graphics/opengl/Image.h @@ -25,6 +25,7 @@ #include "common/config.h" #include "common/Matrix.h" #include "common/Vector.h" +#include "common/StringMap.h" #include "common/math.h" #include "image/ImageData.h" #include "image/CompressedData.h" @@ -50,20 +51,27 @@ class Image : public Texture { public: + enum Format + { + FORMAT_NORMAL, + FORMAT_SRGB, + FORMAT_MAX_ENUM + }; + /** * Creates a new Image. Not that anything is ready to use * before load is called. * * @param data The data from which to load the image. **/ - Image(love::image::ImageData *data, Texture::Format format = Texture::FORMAT_NORMAL); + Image(love::image::ImageData *data, Format format = FORMAT_NORMAL); /** * Creates a new Image with compressed image data. * * @param cdata The compressed data from which to load the image. **/ - Image(love::image::CompressedData *cdata, Texture::Format format = Texture::FORMAT_NORMAL); + Image(love::image::CompressedData *cdata, Format format = FORMAT_NORMAL); /** * Destructor. Deletes the hardware texture and other resources. @@ -120,7 +128,7 @@ public: **/ bool refresh(); - Texture::Format getFormat() const; + Format getFormat() const; static void setDefaultMipmapSharpness(float sharpness); static float getDefaultMipmapSharpness(); @@ -137,6 +145,9 @@ public: static bool hasSRGBSupport(); + static bool getConstant(const char *in, Format &out); + static bool getConstant(Format in, const char *&out); + private: void uploadDefaultTexture(); @@ -166,8 +177,8 @@ private: // Whether this Image is using a compressed texture. bool compressed; - // The format to interpret the texture's data as. - Texture::Format format; + // The format to interpret the image's data as. + Format format; // True if the image wasn't able to be properly created and it had to fall // back to a default texture. @@ -189,6 +200,9 @@ private: GLenum getCompressedFormat(image::CompressedData::Format cformat) const; + static StringMap::Entry formatEntries[]; + static StringMap formats; + }; // Image } // opengl diff --git a/src/modules/graphics/opengl/wrap_Canvas.cpp b/src/modules/graphics/opengl/wrap_Canvas.cpp index a3c31b7f9..4efc610e1 100644 --- a/src/modules/graphics/opengl/wrap_Canvas.cpp +++ b/src/modules/graphics/opengl/wrap_Canvas.cpp @@ -113,10 +113,10 @@ int w_Canvas_clear(lua_State *L) int w_Canvas_getFormat(lua_State *L) { Canvas *canvas = luax_checkcanvas(L, 1); - Texture::Format format = canvas->getTextureFormat(); + Canvas::Format format = canvas->getTextureFormat(); const char *str; - if (!Texture::getConstant(format, str)) - return luaL_error(L, "Unknown texture format."); + if (!Canvas::getConstant(format, str)) + return luaL_error(L, "Unknown Canvas format."); lua_pushstring(L, str); return 1; diff --git a/src/modules/graphics/opengl/wrap_Graphics.cpp b/src/modules/graphics/opengl/wrap_Graphics.cpp index 243c9e908..1814cb2ef 100644 --- a/src/modules/graphics/opengl/wrap_Graphics.cpp +++ b/src/modules/graphics/opengl/wrap_Graphics.cpp @@ -155,14 +155,11 @@ int w_newImage(lua_State *L) love::image::ImageData *data = nullptr; love::image::CompressedData *cdata = nullptr; - Texture::Format format = Texture::FORMAT_NORMAL; + Image::Format format = Image::FORMAT_NORMAL; const char *fstr = lua_isnoneornil(L, 2) ? nullptr : luaL_checkstring(L, 2); - if (fstr != nullptr && !Texture::getConstant(fstr, format)) - return luaL_error(L, "Invalid texture format: %s", fstr); - - if (format == Texture::FORMAT_HDR) // For now... - return luaL_error(L, "HDR images are not supported."); + if (fstr != nullptr && !Image::getConstant(fstr, format)) + return luaL_error(L, "Invalid Image format: %s", fstr); // Convert to FileData, if necessary. if (lua_isstring(L, 1) || luax_istype(L, 1, FILESYSTEM_FILE_T)) @@ -334,9 +331,9 @@ int w_newCanvas(lua_State *L) const char *str = luaL_optstring(L, 3, "normal"); int fsaa = luaL_optint(L, 4, 0); - Texture::Format format; - if (!Texture::getConstant(str, format)) - return luaL_error(L, "Invalid texture format: %s", str); + Canvas::Format format; + if (!Canvas::getConstant(str, format)) + return luaL_error(L, "Invalid Canvas format: %s", str); Canvas *canvas = nullptr; EXCEPT_GUARD(canvas = instance->newCanvas(width, height, format, fsaa);) @@ -985,7 +982,7 @@ int w_isSupported(lua_State *L) supported = false; break; case Graphics::SUPPORT_HDR_CANVAS: - if (!Canvas::isHDRSupported()) + if (!Canvas::isFormatSupported(Canvas::FORMAT_HDR)) supported = false; break; case Graphics::SUPPORT_MULTI_CANVAS: @@ -1021,7 +1018,7 @@ int w_isSupported(lua_State *L) supported = false; break; case Graphics::SUPPORT_SRGB: - if (!Canvas::isSRGBSupported()) + if (!Canvas::isFormatSupported(Canvas::FORMAT_SRGB)) supported = false; break; default: @@ -1034,6 +1031,18 @@ int w_isSupported(lua_State *L) return 1; } +int w_hasCanvasFormat(lua_State *L) +{ + const char *str = luaL_checkstring(L, 1); + Canvas::Format format; + + if (!Canvas::getConstant(str, format)) + return luaL_error(L, "Invalid canvas format: %s", str); + + luax_pushboolean(L, Canvas::isFormatSupported(format)); + return 1; +} + int w_getRendererInfo(lua_State *L) { std::string name, version, vendor, device; @@ -1410,6 +1419,7 @@ static const luaL_Reg functions[] = { "getShader", w_getShader }, { "isSupported", w_isSupported }, + { "hasCanvasFormat", w_hasCanvasFormat }, { "getRendererInfo", w_getRendererInfo }, { "getSystemLimit", w_getSystemLimit }, diff --git a/src/modules/graphics/opengl/wrap_Graphics.h b/src/modules/graphics/opengl/wrap_Graphics.h index 85977cca6..9a18bb7f3 100644 --- a/src/modules/graphics/opengl/wrap_Graphics.h +++ b/src/modules/graphics/opengl/wrap_Graphics.h @@ -93,6 +93,7 @@ int w_getCanvas(lua_State *L); int w_setShader(lua_State *L); int w_getShader(lua_State *L); int w_isSupported(lua_State *L); +int w_hasCanvasFormat(lua_State *L); int w_getRendererInfo(lua_State *L); int w_getSystemLimit(lua_State *L); int w_draw(lua_State *L); From febbecddf7afdbbd1f0652d47103bd412281e97e Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Tue, 13 May 2014 21:22:29 -0300 Subject: [PATCH 09/15] Fixed the texture type of the rgb9e5 canvas format --HG-- branch : Canvas-formats --- src/modules/graphics/opengl/Canvas.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/graphics/opengl/Canvas.cpp b/src/modules/graphics/opengl/Canvas.cpp index 6cb2f7e14..c63f8678f 100644 --- a/src/modules/graphics/opengl/Canvas.cpp +++ b/src/modules/graphics/opengl/Canvas.cpp @@ -1020,7 +1020,7 @@ void Canvas::convertFormat(Canvas::Format format, GLenum &internalformat, GLenum case FORMAT_RGB9E5: internalformat = GL_RGB9_E5; externalformat = GL_RGB; - type = GL_RGB9_E5; + type = GL_UNSIGNED_INT_5_9_9_9_REV; case FORMAT_RG11B10F: internalformat = GL_R11F_G11F_B10F; externalformat = GL_RGB; From 4aeba24e94eed9836239b7406a881f316ac2d8e5 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Tue, 13 May 2014 21:59:24 -0300 Subject: [PATCH 10/15] Fixed the rg11b10f canvas format, removed rgb9e5 due to lack of real support, improved love.graphics.hasCanvasFormat to do extra checks --HG-- branch : Canvas-formats --- src/modules/graphics/opengl/Canvas.cpp | 76 +++++++++++++++++++------- src/modules/graphics/opengl/Canvas.h | 3 +- 2 files changed, 59 insertions(+), 20 deletions(-) diff --git a/src/modules/graphics/opengl/Canvas.cpp b/src/modules/graphics/opengl/Canvas.cpp index c63f8678f..3b060dc7f 100644 --- a/src/modules/graphics/opengl/Canvas.cpp +++ b/src/modules/graphics/opengl/Canvas.cpp @@ -525,12 +525,6 @@ bool Canvas::loadVolatile() return false; } - if (!isFormatSupported(format)) - { - status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; - return false; - } - glGenTextures(1, &texture); gl.bindTexture(texture); @@ -1017,14 +1011,11 @@ void Canvas::convertFormat(Canvas::Format format, GLenum &internalformat, GLenum internalformat = GL_RGB10_A2; type = GL_UNSIGNED_INT_10_10_10_2; break; - case FORMAT_RGB9E5: - internalformat = GL_RGB9_E5; - externalformat = GL_RGB; - type = GL_UNSIGNED_INT_5_9_9_9_REV; case FORMAT_RG11B10F: internalformat = GL_R11F_G11F_B10F; externalformat = GL_RGB; type = GL_UNSIGNED_INT_10F_11F_11F_REV; + break; case FORMAT_RGBA16F: internalformat = GL_RGBA16F; type = GL_FLOAT; @@ -1052,11 +1043,14 @@ bool Canvas::isMultiCanvasSupported() return gl.getMaxRenderTargets() >= 4; } +bool Canvas::supportedFormats[] = {false}; + bool Canvas::isFormatSupported(Canvas::Format format) { if (!isSupported()) return false; + bool supported = true; format = getSizedFormat(format); switch (format) @@ -1065,23 +1059,68 @@ bool Canvas::isFormatSupported(Canvas::Format format) case FORMAT_RGBA4: case FORMAT_RGB5A1: case FORMAT_RGB10A2: - return true; + supported = true; + break; case FORMAT_RGB565: - return GLEE_VERSION_4_2 || GLEE_ARB_ES2_compatibility; - case FORMAT_RGB9E5: - return GLEE_VERSION_3_0 || GLEE_EXT_texture_shared_exponent; + supported = GLEE_VERSION_4_2 || GLEE_ARB_ES2_compatibility; + break; case FORMAT_RG11B10F: - return GLEE_VERSION_3_0 || (GLEE_ARB_texture_float && GLEE_ARB_color_buffer_float + supported = GLEE_VERSION_3_0 || (GLEE_ARB_texture_float && GLEE_ARB_color_buffer_float && GLEE_EXT_packed_float); + break; case FORMAT_RGBA16F: case FORMAT_RGBA32F: - return GLEE_VERSION_3_0 || (GLEE_ARB_texture_float && GLEE_ARB_color_buffer_float); + supported = GLEE_VERSION_3_0 || (GLEE_ARB_texture_float && GLEE_ARB_color_buffer_float); + break; case FORMAT_SRGB: - return GLEE_VERSION_3_0 || ((GLEE_ARB_framebuffer_sRGB || GLEE_EXT_framebuffer_sRGB) + supported = GLEE_VERSION_3_0 || ((GLEE_ARB_framebuffer_sRGB || GLEE_EXT_framebuffer_sRGB) && (GLEE_VERSION_2_1 || GLEE_EXT_texture_sRGB)); + break; default: - return false; + supported = false; + break; } + + if (!supported) + return false; + + if (supportedFormats[format]) + return true; + + // Even though we might have the necessary OpenGL version or extension, + // drivers are still allowed to throw FRAMEBUFFER_UNSUPPORTED when attaching + // a texture to a FBO whose format the driver doesn't like. So we should + // test with an actual FBO. + + GLenum internalformat = GL_RGBA; + GLenum externalformat = GL_RGBA; + GLenum textype = GL_UNSIGNED_BYTE; + convertFormat(format, internalformat, externalformat, textype); + + GLuint texture = 0; + glGenTextures(1, &texture); + gl.bindTexture(texture); + + Texture::Filter f; + f.min = f.mag = Texture::FILTER_NEAREST; + gl.setTextureFilter(f); + + Texture::Wrap w; + gl.setTextureWrap(w); + + glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 2, 2, 0, externalformat, textype, nullptr); + + GLuint fbo = 0; + GLenum status = strategy->createFBO(fbo, texture); + strategy->deleteFBO(fbo, 0, 0); + + gl.deleteTexture(texture); + + // Cache the result so we don't do this for every isFormatSupported call. + if (status == GL_FRAMEBUFFER_COMPLETE) + supportedFormats[format] = true; + + return status == GL_FRAMEBUFFER_COMPLETE; } void Canvas::bindDefaultCanvas() @@ -1109,7 +1148,6 @@ StringMap::Entry Canvas::formatEntries[ {"rgb5a1", Canvas::FORMAT_RGB5A1}, {"rgb565", Canvas::FORMAT_RGB565}, {"rgb10a2", Canvas::FORMAT_RGB10A2}, - {"rgb9e5", Canvas::FORMAT_RGB9E5}, {"rg11b10f", Canvas::FORMAT_RG11B10F}, {"rgba16f", Canvas::FORMAT_RGBA16F}, {"rgba32f", Canvas::FORMAT_RGBA32F}, diff --git a/src/modules/graphics/opengl/Canvas.h b/src/modules/graphics/opengl/Canvas.h index 41fb3b1fa..41cf0ad40 100644 --- a/src/modules/graphics/opengl/Canvas.h +++ b/src/modules/graphics/opengl/Canvas.h @@ -50,7 +50,6 @@ public: FORMAT_RGB5A1, FORMAT_RGB565, FORMAT_RGB10A2, - FORMAT_RGB9E5, FORMAT_RG11B10F, FORMAT_RGBA16F, FORMAT_RGBA32F, @@ -158,6 +157,8 @@ private: void setupGrab(); void drawv(const Matrix &t, const Vertex *v); + static bool supportedFormats[FORMAT_MAX_ENUM]; + static StringMap::Entry formatEntries[]; static StringMap formats; From 5658a2440b3091005e7841e417f30745c329cc50 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Wed, 14 May 2014 01:38:33 -0300 Subject: [PATCH 11/15] Added some comments describing the formats in the Canvas::Format enum. --HG-- branch : Canvas-formats --- src/modules/graphics/opengl/Canvas.cpp | 18 +++++++++--------- src/modules/graphics/opengl/Canvas.h | 23 ++++++++++++----------- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/modules/graphics/opengl/Canvas.cpp b/src/modules/graphics/opengl/Canvas.cpp index 3b060dc7f..72b932e7b 100644 --- a/src/modules/graphics/opengl/Canvas.cpp +++ b/src/modules/graphics/opengl/Canvas.cpp @@ -1044,6 +1044,7 @@ bool Canvas::isMultiCanvasSupported() } bool Canvas::supportedFormats[] = {false}; +bool Canvas::checkedFormats[] = {false}; bool Canvas::isFormatSupported(Canvas::Format format) { @@ -1065,12 +1066,11 @@ bool Canvas::isFormatSupported(Canvas::Format format) supported = GLEE_VERSION_4_2 || GLEE_ARB_ES2_compatibility; break; case FORMAT_RG11B10F: - supported = GLEE_VERSION_3_0 || (GLEE_ARB_texture_float && GLEE_ARB_color_buffer_float - && GLEE_EXT_packed_float); + supported = GLEE_VERSION_3_0 || (GLEE_ARB_texture_float && GLEE_EXT_packed_float); break; case FORMAT_RGBA16F: case FORMAT_RGBA32F: - supported = GLEE_VERSION_3_0 || (GLEE_ARB_texture_float && GLEE_ARB_color_buffer_float); + supported = GLEE_VERSION_3_0 || GLEE_ARB_texture_float; break; case FORMAT_SRGB: supported = GLEE_VERSION_3_0 || ((GLEE_ARB_framebuffer_sRGB || GLEE_EXT_framebuffer_sRGB) @@ -1084,8 +1084,8 @@ bool Canvas::isFormatSupported(Canvas::Format format) if (!supported) return false; - if (supportedFormats[format]) - return true; + if (checkedFormats[format]) + return supportedFormats[format]; // Even though we might have the necessary OpenGL version or extension, // drivers are still allowed to throw FRAMEBUFFER_UNSUPPORTED when attaching @@ -1111,16 +1111,16 @@ bool Canvas::isFormatSupported(Canvas::Format format) glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 2, 2, 0, externalformat, textype, nullptr); GLuint fbo = 0; - GLenum status = strategy->createFBO(fbo, texture); + supported = (strategy->createFBO(fbo, texture) == GL_FRAMEBUFFER_COMPLETE); strategy->deleteFBO(fbo, 0, 0); gl.deleteTexture(texture); // Cache the result so we don't do this for every isFormatSupported call. - if (status == GL_FRAMEBUFFER_COMPLETE) - supportedFormats[format] = true; + checkedFormats[format] = true; + supportedFormats[format] = supported; - return status == GL_FRAMEBUFFER_COMPLETE; + return supported; } void Canvas::bindDefaultCanvas() diff --git a/src/modules/graphics/opengl/Canvas.h b/src/modules/graphics/opengl/Canvas.h index 41cf0ad40..3e2a623d2 100644 --- a/src/modules/graphics/opengl/Canvas.h +++ b/src/modules/graphics/opengl/Canvas.h @@ -43,17 +43,17 @@ public: // Different Canvas render target formats. enum Format { - FORMAT_NORMAL, - FORMAT_HDR, - FORMAT_RGBA8, - FORMAT_RGBA4, - FORMAT_RGB5A1, - FORMAT_RGB565, - FORMAT_RGB10A2, - FORMAT_RG11B10F, - FORMAT_RGBA16F, - FORMAT_RGBA32F, - FORMAT_SRGB, + FORMAT_NORMAL, // Usually RGBA8 or a similar fallback. Always supported. + FORMAT_HDR, // Usually RGBA16F. Not always supported. + FORMAT_RGBA8, // RGBA with 8 bits per component. + FORMAT_RGBA4, // RGBA with 4 bits per component. + FORMAT_RGB5A1, // RGB with 5 bits per component, and A with 1 bit. + FORMAT_RGB565, // RGB with 5, 6, and 5 bits each, respectively. + FORMAT_RGB10A2, // RGB with 10 bits each, and A with 2 bits. + FORMAT_RG11B10F, // Floating point [0, +inf]. RG with 11 FP bits each, and B with 10 FP bits. + FORMAT_RGBA16F, // Floating point [-inf, +inf]. RGBA with 16 FP bits per component. + FORMAT_RGBA32F, // Floating point [-inf, +inf]. RGBA with 32 FP bits per component. + FORMAT_SRGB, // sRGB with 8 bits per component, plus 8 bit linear A. FORMAT_MAX_ENUM }; @@ -158,6 +158,7 @@ private: void drawv(const Matrix &t, const Vertex *v); static bool supportedFormats[FORMAT_MAX_ENUM]; + static bool checkedFormats[FORMAT_MAX_ENUM]; static StringMap::Entry formatEntries[]; static StringMap formats; From 976c26aa21cb1c8193f7fd061a0ec705407c85a9 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Wed, 14 May 2014 16:45:16 -0300 Subject: [PATCH 12/15] Removed an unnecessary extension dependency for support of the rg11b10f canvas format --- src/modules/graphics/opengl/Canvas.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/graphics/opengl/Canvas.cpp b/src/modules/graphics/opengl/Canvas.cpp index 72b932e7b..d994f5762 100644 --- a/src/modules/graphics/opengl/Canvas.cpp +++ b/src/modules/graphics/opengl/Canvas.cpp @@ -1066,7 +1066,7 @@ bool Canvas::isFormatSupported(Canvas::Format format) supported = GLEE_VERSION_4_2 || GLEE_ARB_ES2_compatibility; break; case FORMAT_RG11B10F: - supported = GLEE_VERSION_3_0 || (GLEE_ARB_texture_float && GLEE_EXT_packed_float); + supported = GLEE_VERSION_3_0 || GLEE_EXT_packed_float; break; case FORMAT_RGBA16F: case FORMAT_RGBA32F: From cb01e3f4d11b7225b8bb4aebeffbe1d31f7c6fac Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Wed, 14 May 2014 20:00:59 -0300 Subject: [PATCH 13/15] Fixed segfault when garbage collecting Shader objects --- src/modules/graphics/opengl/Shader.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/modules/graphics/opengl/Shader.cpp b/src/modules/graphics/opengl/Shader.cpp index b95a0d10b..6cd08ad3a 100644 --- a/src/modules/graphics/opengl/Shader.cpp +++ b/src/modules/graphics/opengl/Shader.cpp @@ -98,10 +98,9 @@ Shader::~Shader() detach(); for (auto it = boundRetainables.begin(); it != boundRetainables.end(); ++it) - { it->second->release(); - boundRetainables.erase(it); - } + + boundRetainables.clear(); unloadVolatile(); } From 2b12c9cb1e67882107a303a01c8c2125fa6d2ff8 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Tue, 20 May 2014 22:48:54 -0300 Subject: [PATCH 14/15] Updated the readme --- readme.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 3405073d1..14c58188d 100644 --- a/readme.md +++ b/readme.md @@ -29,10 +29,12 @@ 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.) +not our development target (which would be the next revision - version numbers are formatted major.minor.revision.) We tag all our releases (since we started using mercurial), and have binary downloads available for them. +Experimental changes are developed in the separate [love-experiments][love-experiments] repository. + Builds ------ @@ -69,3 +71,4 @@ Dependencies [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 +[love-experiments]: https://bitbucket.org/bartbes/love-experiments From fd5b5aad653517d51971fade4e52b8d48995aeb2 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Wed, 21 May 2014 21:14:08 -0300 Subject: [PATCH 15/15] Minor code cleanup --- src/common/runtime.h | 2 +- src/modules/audio/Audio.h | 2 +- src/modules/audio/Source.h | 4 ++-- src/modules/graphics/Graphics.h | 16 ++++++++-------- src/modules/graphics/opengl/Font.h | 2 +- src/modules/graphics/opengl/SpriteBatch.h | 2 +- src/modules/image/ImageData.h | 2 +- src/scripts/boot.lua | 1 - src/scripts/boot.lua.h | 1 - 9 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/common/runtime.h b/src/common/runtime.h index de9c6fbde..dae24f97c 100644 --- a/src/common/runtime.h +++ b/src/common/runtime.h @@ -49,7 +49,7 @@ extern void *_gcmutex; **/ enum Registry { - REGISTRY_GC = 1, + REGISTRY_GC, REGISTRY_MODULES, REGISTRY_TYPES }; diff --git a/src/modules/audio/Audio.h b/src/modules/audio/Audio.h index 9a8ca863c..7ed9b4362 100644 --- a/src/modules/audio/Audio.h +++ b/src/modules/audio/Audio.h @@ -51,7 +51,7 @@ public: */ enum DistanceModel { - DISTANCE_NONE = 1, + DISTANCE_NONE, DISTANCE_INVERSE, DISTANCE_INVERSE_CLAMPED, DISTANCE_LINEAR, diff --git a/src/modules/audio/Source.h b/src/modules/audio/Source.h index 43c5fafca..bf2756b0a 100644 --- a/src/modules/audio/Source.h +++ b/src/modules/audio/Source.h @@ -36,14 +36,14 @@ public: enum Type { - TYPE_STATIC = 1, + TYPE_STATIC, TYPE_STREAM, TYPE_MAX_ENUM }; // Type enum Unit { - UNIT_SECONDS = 1, + UNIT_SECONDS, UNIT_SAMPLES, UNIT_MAX_ENUM }; diff --git a/src/modules/graphics/Graphics.h b/src/modules/graphics/Graphics.h index 95406e485..00746a8cd 100644 --- a/src/modules/graphics/Graphics.h +++ b/src/modules/graphics/Graphics.h @@ -36,14 +36,14 @@ public: enum DrawMode { - DRAW_LINE = 1, + DRAW_LINE, DRAW_FILL, DRAW_MAX_ENUM }; enum AlignMode { - ALIGN_LEFT = 1, + ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT, ALIGN_JUSTIFY, @@ -52,7 +52,7 @@ public: enum BlendMode { - BLEND_ALPHA = 1, + BLEND_ALPHA, BLEND_ADDITIVE, BLEND_SUBTRACTIVE, BLEND_MULTIPLICATIVE, @@ -64,14 +64,14 @@ public: enum LineStyle { - LINE_ROUGH = 1, + LINE_ROUGH, LINE_SMOOTH, LINE_MAX_ENUM }; enum LineJoin { - LINE_JOIN_NONE = 1, + LINE_JOIN_NONE, LINE_JOIN_MITER, LINE_JOIN_BEVEL, LINE_JOIN_MAX_ENUM @@ -79,14 +79,14 @@ public: enum PointStyle { - POINT_ROUGH = 1, + POINT_ROUGH, POINT_SMOOTH, POINT_MAX_ENUM }; enum Support { - SUPPORT_CANVAS = 1, + SUPPORT_CANVAS, SUPPORT_HDR_CANVAS, SUPPORT_MULTI_CANVAS, SUPPORT_SHADER, @@ -102,7 +102,7 @@ public: enum RendererInfo { - RENDERER_INFO_NAME = 1, + RENDERER_INFO_NAME, RENDERER_INFO_VERSION, RENDERER_INFO_VENDOR, RENDERER_INFO_DEVICE, diff --git a/src/modules/graphics/opengl/Font.h b/src/modules/graphics/opengl/Font.h index fee277452..403b0ef45 100644 --- a/src/modules/graphics/opengl/Font.h +++ b/src/modules/graphics/opengl/Font.h @@ -142,7 +142,7 @@ private: enum FontType { - FONT_TRUETYPE = 1, + FONT_TRUETYPE, FONT_IMAGE, FONT_UNKNOWN }; diff --git a/src/modules/graphics/opengl/SpriteBatch.h b/src/modules/graphics/opengl/SpriteBatch.h index 7339c7c77..6f87f8fa5 100644 --- a/src/modules/graphics/opengl/SpriteBatch.h +++ b/src/modules/graphics/opengl/SpriteBatch.h @@ -52,7 +52,7 @@ public: enum UsageHint { - USAGE_DYNAMIC = 1, + USAGE_DYNAMIC, USAGE_STATIC, USAGE_STREAM, USAGE_MAX_ENUM diff --git a/src/modules/image/ImageData.h b/src/modules/image/ImageData.h index f85494d8b..8a0230c20 100644 --- a/src/modules/image/ImageData.h +++ b/src/modules/image/ImageData.h @@ -49,7 +49,7 @@ public: enum Format { - FORMAT_TGA = 1, + FORMAT_TGA, FORMAT_BMP, FORMAT_JPG, FORMAT_PNG, diff --git a/src/scripts/boot.lua b/src/scripts/boot.lua index faa95a7eb..39ec3b052 100644 --- a/src/scripts/boot.lua +++ b/src/scripts/boot.lua @@ -235,7 +235,6 @@ local no_game_code = false function love.boot() -- This is absolutely needed. - require("love") require("love.filesystem") love.arg.parse_options() diff --git a/src/scripts/boot.lua.h b/src/scripts/boot.lua.h index 5040735bb..88b46ce85 100644 --- a/src/scripts/boot.lua.h +++ b/src/scripts/boot.lua.h @@ -422,7 +422,6 @@ const unsigned char boot_lua[] = 0x28, 0x29, 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x62, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x65, 0x6c, 0x79, 0x20, 0x6e, 0x65, 0x65, 0x64, 0x65, 0x64, 0x2e, 0x0a, - 0x09, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x28, 0x22, 0x6c, 0x6f, 0x76, 0x65, 0x22, 0x29, 0x0a, 0x09, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x28, 0x22, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x22, 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x72, 0x67, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x5f, 0x6f, 0x70,