diff --git a/CMakeLists.txt b/CMakeLists.txt index 996d9bc6f..1897e3e34 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -172,7 +172,7 @@ Please see https://github.com/love2d/megasource find_package(ModPlug REQUIRED) find_package(OpenAL REQUIRED) find_package(OpenGL REQUIRED) - find_package(SDL2 REQUIRED) + find_package(SDL2 2.0.9 REQUIRED) find_package(Theora REQUIRED) find_package(Vorbis REQUIRED) find_package(ZLIB REQUIRED) @@ -540,8 +540,8 @@ set(LOVE_SRC_MODULE_GRAPHICS_ROOT src/modules/graphics/SpriteBatch.h src/modules/graphics/StreamBuffer.cpp src/modules/graphics/StreamBuffer.h - src/modules/graphics/Text.cpp - src/modules/graphics/Text.h + src/modules/graphics/TextBatch.cpp + src/modules/graphics/TextBatch.h src/modules/graphics/Texture.cpp src/modules/graphics/Texture.h src/modules/graphics/vertex.cpp @@ -570,8 +570,8 @@ set(LOVE_SRC_MODULE_GRAPHICS_ROOT src/modules/graphics/wrap_SpriteBatch.h src/modules/graphics/wrap_Texture.cpp src/modules/graphics/wrap_Texture.h - src/modules/graphics/wrap_Text.cpp - src/modules/graphics/wrap_Text.h + src/modules/graphics/wrap_TextBatch.cpp + src/modules/graphics/wrap_TextBatch.h src/modules/graphics/wrap_Video.cpp src/modules/graphics/wrap_Video.h ) @@ -907,6 +907,30 @@ set(LOVE_SRC_MODULE_PHYSICS source_group("modules\\physics" FILES ${LOVE_SRC_MODULE_PHYSICS_ROOT}) source_group("modules\\physics\\box2d" FILES ${LOVE_SRC_MODULE_PHYSICS_BOX2D}) +# +# love.sensor +# + +set(LOVE_SRC_MODULE_SENSOR_ROOT + src/modules/sensor/Sensor.cpp + src/modules/sensor/Sensor.h + src/modules/sensor/wrap_Sensor.cpp + src/modules/sensor/wrap_Sensor.h +) + +set(LOVE_SRC_MODULE_SENSOR_SDL + src/modules/sensor/sdl/Sensor.cpp + src/modules/sensor/sdl/Sensor.h +) + +set(LOVE_SRC_MODULE_SENSOR + ${LOVE_SRC_MODULE_SENSOR_ROOT} + ${LOVE_SRC_MODULE_SENSOR_SDL} +) + +source_group("modules\\sensor" FILES ${LOVE_SRC_MODULE_SENSOR_ROOT}) +source_group("modules\\sensor\\sdl" FILES ${LOVE_SRC_MODULE_SENSOR_SDL}) + # # love.sound # @@ -1881,6 +1905,7 @@ set(LOVE_LIB_SRC ${LOVE_SRC_MODULE_MATH} ${LOVE_SRC_MODULE_MOUSE} ${LOVE_SRC_MODULE_PHYSICS} + ${LOVE_SRC_MODULE_SENSOR} ${LOVE_SRC_MODULE_SOUND} ${LOVE_SRC_MODULE_SYSTEM} ${LOVE_SRC_MODULE_THREAD} diff --git a/changes.txt b/changes.txt index cc9b16b01..1ca00130b 100644 --- a/changes.txt +++ b/changes.txt @@ -25,6 +25,10 @@ Released: N/A * Added love.keyboard.isModifierActive. * Added Joystick:setPlayerIndex and Joystick:getPlayerIndex. * Added Joystick:getGamepadType. +* Added Joystick:hasSensor. +* Added Joystick:isSensorEnabled. +* Added Joystick:setSensorEnabled. +* Added Joystick:getSensorData. * Added new Gamepad API buttons: "misc1", "paddle1", "paddle2", "paddle3", "paddle4". and "touchpad". * Added World:getFixturesInArea(). * Added support for saving .exr image files via ImageData:encode. @@ -61,6 +65,9 @@ Released: N/A * Added a variant of love.graphics.setColorMask which accepts a single boolean. * Added new 'clampone' wrap mode. * Added a variant of Font:getWidth which takes a codepoint number argument. +* Added love.sensor module. +* Added love.sensorupdated callback. +* Added love.joysticksensorupdated callback. * Changed the default font from Vera size 12 to Noto Sans size 13. * Changed the Texture class and implementation to no longer have separate Canvas and Image subclasses. @@ -75,6 +82,7 @@ Released: N/A * Changed love.filesystem.exists to no longer be deprecated. * Changed RevoluteJoint:getMotorTorque to take 'dt' as a parameter instead of 'inverse_dt'. * Changed love.math.perlinNoise and simplexNoise to use higher precision numbers for its internal calculations. +* Changed t.accelerometerjoystick startup flag in love.conf to unset by default. * Renamed 'display' field to 'displayindex' in love.window.setMode/updateMode/getMode and love.conf. @@ -86,6 +94,7 @@ Released: N/A * Deprecated love.math.noise (replaced by perlinNoise and simplexNoise). * Deprecated love.graphics.getImageFormats and love.graphics.getCanvasFormats (replaced by getTextureFormats). * Deprecated t.window.highdpi in love.conf and the highdpi flag of love.window.setMode (replaced by t.highdpi in love.conf). +* Deprecated t.accelerometerjoystick in love.conf (replaced by love.sensor module). * Deprecated the variants of Mesh:attachAttribute and SpriteBatch:attachAttribute which accept a Mesh (replaced by variants which accept a Buffer). * Deprecated Texture:newImageData (replaced by love.graphics.readbackTexture). diff --git a/license.txt b/license.txt index ac60c4279..b00f4addb 100644 --- a/license.txt +++ b/license.txt @@ -13,6 +13,11 @@ This distribution contains code from the following projects (full license text b License: MIT/Expat Copyright (c) 2002-2016 Lee Salzman + - FreeType + Website: https://freetype.org/ + License: FreeType License + Copyright (c) 2006-2017 David Turner, Robert Wilhelm, and Werner Lemberg. + - GLAD Website: http://glad.dav1d.de/ License: MIT/Expat @@ -199,6 +204,172 @@ MIT/Expat OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +FreeType License + The FreeType Project LICENSE + ---------------------------- + + 2006-Jan-27 + + Copyright 1996-2002, 2006 by + David Turner, Robert Wilhelm, and Werner Lemberg + + Introduction + ============ + + The FreeType Project is distributed in several archive packages; + some of them may contain, in addition to the FreeType font engine, + various tools and contributions which rely on, or relate to, the + FreeType Project. + + This license applies to all files found in such packages, and + which do not fall under their own explicit license. The license + affects thus the FreeType font engine, the test programs, + documentation and makefiles, at the very least. + + This license was inspired by the BSD, Artistic, and IJG + (Independent JPEG Group) licenses, which all encourage inclusion + and use of free software in commercial and freeware products + alike. As a consequence, its main points are that: + + o We don't promise that this software works. However, we will be + interested in any kind of bug reports. (`as is' distribution) + + o You can use this software for whatever you want, in parts or + full form, without having to pay us. (`royalty-free' usage) + + o You may not pretend that you wrote this software. If you use + it, or only parts of it, in a program, you must acknowledge + somewhere in your documentation that you have used the + FreeType code. (`credits') + + We specifically permit and encourage the inclusion of this + software, with or without modifications, in commercial products. + We disclaim all warranties covering The FreeType Project and + assume no liability related to The FreeType Project. + + + Finally, many people asked us for a preferred form for a + credit/disclaimer to use in compliance with this license. We thus + encourage you to use the following text: + + """ + Portions of this software are copyright © The FreeType + Project (www.freetype.org). All rights reserved. + """ + + Please replace with the value from the FreeType version you + actually use. + + + Legal Terms + =========== + + 0. Definitions + -------------- + + Throughout this license, the terms `package', `FreeType Project', + and `FreeType archive' refer to the set of files originally + distributed by the authors (David Turner, Robert Wilhelm, and + Werner Lemberg) as the `FreeType Project', be they named as alpha, + beta or final release. + + `You' refers to the licensee, or person using the project, where + `using' is a generic term including compiling the project's source + code as well as linking it to form a `program' or `executable'. + This program is referred to as `a program using the FreeType + engine'. + + This license applies to all files distributed in the original + FreeType Project, including all source code, binaries and + documentation, unless otherwise stated in the file in its + original, unmodified form as distributed in the original archive. + If you are unsure whether or not a particular file is covered by + this license, you must contact us to verify this. + + The FreeType Project is copyright (C) 1996-2000 by David Turner, + Robert Wilhelm, and Werner Lemberg. All rights reserved except as + specified below. + + 1. No Warranty + -------------- + + THE FREETYPE PROJECT IS PROVIDED `AS IS' WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. IN NO EVENT WILL ANY OF THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY DAMAGES CAUSED BY THE USE OR THE INABILITY TO + USE, OF THE FREETYPE PROJECT. + + 2. Redistribution + ----------------- + + This license grants a worldwide, royalty-free, perpetual and + irrevocable right and license to use, execute, perform, compile, + display, copy, create derivative works of, distribute and + sublicense the FreeType Project (in both source and object code + forms) and derivative works thereof for any purpose; and to + authorize others to exercise some or all of the rights granted + herein, subject to the following conditions: + + o Redistribution of source code must retain this license file + (`FTL.TXT') unaltered; any additions, deletions or changes to + the original files must be clearly indicated in accompanying + documentation. The copyright notices of the unaltered, + original files must be preserved in all copies of source + files. + + o Redistribution in binary form must provide a disclaimer that + states that the software is based in part of the work of the + FreeType Team, in the distribution documentation. We also + encourage you to put an URL to the FreeType web page in your + documentation, though this isn't mandatory. + + These conditions apply to any software derived from or based on + the FreeType Project, not just the unmodified files. If you use + our work, you must acknowledge us. However, no fee need be paid + to us. + + 3. Advertising + -------------- + + Neither the FreeType authors and contributors nor you shall use + the name of the other for commercial, advertising, or promotional + purposes without specific prior written permission. + + We suggest, but do not require, that you use one or more of the + following phrases to refer to this software in your documentation + or advertising materials: `FreeType Project', `FreeType Engine', + `FreeType library', or `FreeType Distribution'. + + As you have not signed this license, you are not required to + accept it. However, as the FreeType Project is copyrighted + material, only this license, or another one contracted with the + authors, grants you the right to use, distribute, and modify it. + Therefore, by using, distributing, or modifying the FreeType + Project, you indicate that you understand and accept all the terms + of this license. + + 4. Contacts + ----------- + + There are two mailing lists related to FreeType: + + o freetype@nongnu.org + + Discusses general use and applications of FreeType, as well as + future and wanted additions to the library and distribution. + If you are looking for support, start in this list if you + haven't found anything to help you in the documentation. + + o freetype-devel@nongnu.org + + Discusses bugs, as well as engine internals, design issues, + specific licenses, porting, etc. + + Our home page can be found at + + http://www.freetype.org + 3-Clause BSD All rights reserved. diff --git a/platform/unix/deps.m4 b/platform/unix/deps.m4 index d84f01ac1..e087a88e8 100644 --- a/platform/unix/deps.m4 +++ b/platform/unix/deps.m4 @@ -21,7 +21,7 @@ AC_DEFUN([ACLOVE_DEP_LIBM], [ AC_DEFUN([ACLOVE_DEP_SDL2], [ aclove_sdl2_found=no - AM_PATH_SDL2([], [aclove_sdl2_found=yes], []) + AM_PATH_SDL2([2.0.9], [aclove_sdl2_found=yes], []) AS_VAR_IF([aclove_sdl2_found], [no], [LOVE_MSG_ERROR([SDL 2])], [])]) AC_DEFUN([ACLOVE_DEP_PTHREAD], [ diff --git a/platform/xcode/liblove.xcodeproj/project.pbxproj b/platform/xcode/liblove.xcodeproj/project.pbxproj index 69eb73b34..04bfbdc69 100644 --- a/platform/xcode/liblove.xcodeproj/project.pbxproj +++ b/platform/xcode/liblove.xcodeproj/project.pbxproj @@ -1114,6 +1114,15 @@ FACA02FB1F5E397E0084B28F /* HashFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FACA02E61F5E396B0084B28F /* HashFunction.cpp */; }; FACA02FC1F5E39810084B28F /* wrap_CompressedData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FACA02E81F5E396B0084B28F /* wrap_CompressedData.cpp */; }; FACA02FD1F5E39840084B28F /* wrap_DataModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FACA02EA1F5E396B0084B28F /* wrap_DataModule.cpp */; }; + FACA06AC293EE5CD001A2557 /* wrap_Sensor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FACA06A5293EE5CD001A2557 /* wrap_Sensor.cpp */; }; + FACA06AD293EE5CD001A2557 /* wrap_Sensor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FACA06A5293EE5CD001A2557 /* wrap_Sensor.cpp */; }; + FACA06AE293EE5CD001A2557 /* Sensor.h in Headers */ = {isa = PBXBuildFile; fileRef = FACA06A6293EE5CD001A2557 /* Sensor.h */; }; + FACA06AF293EE5CD001A2557 /* Sensor.h in Headers */ = {isa = PBXBuildFile; fileRef = FACA06A8293EE5CD001A2557 /* Sensor.h */; }; + FACA06B0293EE5CD001A2557 /* Sensor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FACA06A9293EE5CD001A2557 /* Sensor.cpp */; }; + FACA06B1293EE5CD001A2557 /* Sensor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FACA06A9293EE5CD001A2557 /* Sensor.cpp */; }; + FACA06B2293EE5CD001A2557 /* Sensor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FACA06AA293EE5CD001A2557 /* Sensor.cpp */; }; + FACA06B3293EE5CD001A2557 /* Sensor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FACA06AA293EE5CD001A2557 /* Sensor.cpp */; }; + FACA06B4293EE5CD001A2557 /* wrap_Sensor.h in Headers */ = {isa = PBXBuildFile; fileRef = FACA06AB293EE5CD001A2557 /* wrap_Sensor.h */; }; FACFB751276D7E3B0089F78D /* freetype.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = FACFB750276D7E2B0089F78D /* freetype.xcframework */; }; FACFB753276D7F860089F78D /* Lua.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = FACFB752276D7F6F0089F78D /* Lua.xcframework */; }; FAD19A171DFF8CA200D5398A /* ImageDataBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAD19A151DFF8CA200D5398A /* ImageDataBase.cpp */; }; @@ -1124,12 +1133,12 @@ FADF53F81E3C7ACD00012CC0 /* Buffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF53F61E3C7ACD00012CC0 /* Buffer.cpp */; }; FADF53F91E3C7ACD00012CC0 /* Buffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF53F61E3C7ACD00012CC0 /* Buffer.cpp */; }; FADF53FA1E3C7ACD00012CC0 /* Buffer.h in Headers */ = {isa = PBXBuildFile; fileRef = FADF53F71E3C7ACD00012CC0 /* Buffer.h */; }; - FADF53FD1E3D74F200012CC0 /* Text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF53FB1E3D74F200012CC0 /* Text.cpp */; }; - FADF53FE1E3D74F200012CC0 /* Text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF53FB1E3D74F200012CC0 /* Text.cpp */; }; - FADF53FF1E3D74F200012CC0 /* Text.h in Headers */ = {isa = PBXBuildFile; fileRef = FADF53FC1E3D74F200012CC0 /* Text.h */; }; - FADF54021E3D77B500012CC0 /* wrap_Text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF54001E3D77B500012CC0 /* wrap_Text.cpp */; }; - FADF54031E3D77B500012CC0 /* wrap_Text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF54001E3D77B500012CC0 /* wrap_Text.cpp */; }; - FADF54041E3D77B500012CC0 /* wrap_Text.h in Headers */ = {isa = PBXBuildFile; fileRef = FADF54011E3D77B500012CC0 /* wrap_Text.h */; }; + FADF53FD1E3D74F200012CC0 /* TextBatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF53FB1E3D74F200012CC0 /* TextBatch.cpp */; }; + FADF53FE1E3D74F200012CC0 /* TextBatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF53FB1E3D74F200012CC0 /* TextBatch.cpp */; }; + FADF53FF1E3D74F200012CC0 /* TextBatch.h in Headers */ = {isa = PBXBuildFile; fileRef = FADF53FC1E3D74F200012CC0 /* TextBatch.h */; }; + FADF54021E3D77B500012CC0 /* wrap_TextBatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF54001E3D77B500012CC0 /* wrap_TextBatch.cpp */; }; + FADF54031E3D77B500012CC0 /* wrap_TextBatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF54001E3D77B500012CC0 /* wrap_TextBatch.cpp */; }; + FADF54041E3D77B500012CC0 /* wrap_TextBatch.h in Headers */ = {isa = PBXBuildFile; fileRef = FADF54011E3D77B500012CC0 /* wrap_TextBatch.h */; }; FADF54071E3D78F700012CC0 /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF54051E3D78F700012CC0 /* Video.cpp */; }; FADF54081E3D78F700012CC0 /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF54051E3D78F700012CC0 /* Video.cpp */; }; FADF54091E3D78F700012CC0 /* Video.h in Headers */ = {isa = PBXBuildFile; fileRef = FADF54061E3D78F700012CC0 /* Video.h */; }; @@ -2138,6 +2147,12 @@ FACA02E91F5E396B0084B28F /* wrap_CompressedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_CompressedData.h; sourceTree = ""; }; FACA02EA1F5E396B0084B28F /* wrap_DataModule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_DataModule.cpp; sourceTree = ""; }; FACA02EB1F5E396B0084B28F /* wrap_DataModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_DataModule.h; sourceTree = ""; }; + FACA06A5293EE5CD001A2557 /* wrap_Sensor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Sensor.cpp; sourceTree = ""; }; + FACA06A6293EE5CD001A2557 /* Sensor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Sensor.h; sourceTree = ""; }; + FACA06A8293EE5CD001A2557 /* Sensor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Sensor.h; sourceTree = ""; }; + FACA06A9293EE5CD001A2557 /* Sensor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Sensor.cpp; sourceTree = ""; }; + FACA06AA293EE5CD001A2557 /* Sensor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Sensor.cpp; sourceTree = ""; }; + FACA06AB293EE5CD001A2557 /* wrap_Sensor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Sensor.h; sourceTree = ""; }; FACFB750276D7E2B0089F78D /* freetype.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = freetype.xcframework; path = ios/libraries/freetype.xcframework; sourceTree = ""; }; FACFB752276D7F6F0089F78D /* Lua.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = Lua.xcframework; path = ios/libraries/Lua.xcframework; sourceTree = ""; }; FAD19A151DFF8CA200D5398A /* ImageDataBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageDataBase.cpp; sourceTree = ""; }; @@ -2146,10 +2161,10 @@ FADF4CC52663D0EC004F95C1 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; FADF53F61E3C7ACD00012CC0 /* Buffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Buffer.cpp; sourceTree = ""; }; FADF53F71E3C7ACD00012CC0 /* Buffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Buffer.h; sourceTree = ""; }; - FADF53FB1E3D74F200012CC0 /* Text.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Text.cpp; sourceTree = ""; }; - FADF53FC1E3D74F200012CC0 /* Text.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Text.h; sourceTree = ""; }; - FADF54001E3D77B500012CC0 /* wrap_Text.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Text.cpp; sourceTree = ""; }; - FADF54011E3D77B500012CC0 /* wrap_Text.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Text.h; sourceTree = ""; }; + FADF53FB1E3D74F200012CC0 /* TextBatch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextBatch.cpp; sourceTree = ""; }; + FADF53FC1E3D74F200012CC0 /* TextBatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextBatch.h; sourceTree = ""; }; + FADF54001E3D77B500012CC0 /* wrap_TextBatch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_TextBatch.cpp; sourceTree = ""; }; + FADF54011E3D77B500012CC0 /* wrap_TextBatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_TextBatch.h; sourceTree = ""; }; FADF54051E3D78F700012CC0 /* Video.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Video.cpp; sourceTree = ""; }; FADF54061E3D78F700012CC0 /* Video.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Video.h; sourceTree = ""; }; FADF540A1E3D7CDD00012CC0 /* wrap_Video.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Video.cpp; sourceTree = ""; }; @@ -2660,6 +2675,7 @@ FA0B7C001A95902C000E1D17 /* math */, FA0B7C0D1A95902C000E1D17 /* mouse */, FA0B7C1B1A95902C000E1D17 /* physics */, + FACA06A4293EE5CD001A2557 /* sensor */, FA0B7C7B1A95902C000E1D17 /* sound */, FA0B7C9A1A95902C000E1D17 /* system */, FA0B7CA21A95902C000E1D17 /* thread */, @@ -2860,8 +2876,8 @@ FADF542E1E3DABF600012CC0 /* SpriteBatch.h */, FA29C0041E12355B00268CD8 /* StreamBuffer.cpp */, FA2AF6721DAD62710032B62C /* StreamBuffer.h */, - FADF53FB1E3D74F200012CC0 /* Text.cpp */, - FADF53FC1E3D74F200012CC0 /* Text.h */, + FADF53FB1E3D74F200012CC0 /* TextBatch.cpp */, + FADF53FC1E3D74F200012CC0 /* TextBatch.h */, FA0B7BBE1A95902C000E1D17 /* Texture.cpp */, FA0B7BBF1A95902C000E1D17 /* Texture.h */, FA2AF6731DAD64970032B62C /* vertex.cpp */, @@ -2889,8 +2905,8 @@ FA1BA0B61E17043400AA2803 /* wrap_Shader.h */, FADF54321E3DAE6E00012CC0 /* wrap_SpriteBatch.cpp */, FADF54331E3DAE6E00012CC0 /* wrap_SpriteBatch.h */, - FADF54001E3D77B500012CC0 /* wrap_Text.cpp */, - FADF54011E3D77B500012CC0 /* wrap_Text.h */, + FADF54001E3D77B500012CC0 /* wrap_TextBatch.cpp */, + FADF54011E3D77B500012CC0 /* wrap_TextBatch.h */, FA620A301AA2F8DB005DB4C2 /* wrap_Texture.cpp */, FA620A311AA2F8DB005DB4C2 /* wrap_Texture.h */, FADF540A1E3D7CDD00012CC0 /* wrap_Video.cpp */, @@ -3807,6 +3823,27 @@ path = data; sourceTree = ""; }; + FACA06A4293EE5CD001A2557 /* sensor */ = { + isa = PBXGroup; + children = ( + FACA06A7293EE5CD001A2557 /* sdl */, + FACA06AA293EE5CD001A2557 /* Sensor.cpp */, + FACA06A6293EE5CD001A2557 /* Sensor.h */, + FACA06A5293EE5CD001A2557 /* wrap_Sensor.cpp */, + FACA06AB293EE5CD001A2557 /* wrap_Sensor.h */, + ); + path = sensor; + sourceTree = ""; + }; + FACA06A7293EE5CD001A2557 /* sdl */ = { + isa = PBXGroup; + children = ( + FACA06A9293EE5CD001A2557 /* Sensor.cpp */, + FACA06A8293EE5CD001A2557 /* Sensor.h */, + ); + path = sdl; + sourceTree = ""; + }; FAF13FBF1E20934C00F898D2 /* glslang */ = { isa = PBXGroup; children = ( @@ -4010,6 +4047,7 @@ FA0B7D4A1A95902C000E1D17 /* Polyline.h in Headers */, FABDA9E72552448300B5C523 /* b2_chain_shape.h in Headers */, FAF1405C1E20934C00F898D2 /* InitializeGlobals.h in Headers */, + FACA06B4293EE5CD001A2557 /* wrap_Sensor.h in Headers */, FA0B7DB31A95902C000E1D17 /* wrap_Image.h in Headers */, FAF140591E20934C00F898D2 /* Common.h in Headers */, FA0B7EC31A95902C000E1D17 /* threads.h in Headers */, @@ -4210,7 +4248,7 @@ FABDA9EA2552448300B5C523 /* b2_world_callbacks.h in Headers */, FA0B7E7D1A95902C000E1D17 /* wrap_World.h in Headers */, FA0B7EBD1A95902C000E1D17 /* LuaThread.h in Headers */, - FADF53FF1E3D74F200012CC0 /* Text.h in Headers */, + FADF53FF1E3D74F200012CC0 /* TextBatch.h in Headers */, FA0B7DC01A95902C000E1D17 /* JoystickModule.h in Headers */, FA18CF3923DCF67900263725 /* spirv_msl.hpp in Headers */, FA0B7E871A95902C000E1D17 /* CoreAudioDecoder.h in Headers */, @@ -4299,6 +4337,7 @@ FA0B7DC31A95902C000E1D17 /* wrap_Joystick.h in Headers */, FA18CF3B23DCF67900263725 /* spirv_cross_util.hpp in Headers */, FAF140631E20934C00F898D2 /* Types.h in Headers */, + FACA06AF293EE5CD001A2557 /* Sensor.h in Headers */, FA4F2BE61DE6650600CA37D7 /* wrap_Transform.h in Headers */, FA0B7EE71A95902D000E1D17 /* Window.h in Headers */, FA0B7E651A95902C000E1D17 /* wrap_PolygonShape.h in Headers */, @@ -4359,6 +4398,7 @@ FA0B7E931A95902C000E1D17 /* ModPlugDecoder.h in Headers */, FA0B7D111A95902C000E1D17 /* BMFontRasterizer.h in Headers */, 217DFBE61D9F6D490055D849 /* http.lua.h in Headers */, + FACA06AE293EE5CD001A2557 /* Sensor.h in Headers */, FA18CF1D23DCF67900263725 /* sampler.hpp in Headers */, FA0B7E3E1A95902C000E1D17 /* wrap_Body.h in Headers */, FABDA9C92552448300B5C523 /* b2_distance.h in Headers */, @@ -4443,7 +4483,7 @@ FABDA9CF2552448300B5C523 /* b2_mouse_joint.h in Headers */, FABDA9E42552448300B5C523 /* b2_collision.h in Headers */, FA41A3CA1C0A1F950084430C /* ASTCHandler.h in Headers */, - FADF54041E3D77B500012CC0 /* wrap_Text.h in Headers */, + FADF54041E3D77B500012CC0 /* wrap_TextBatch.h in Headers */, FA0B7ED31A95902C000E1D17 /* wrap_ThreadModule.h in Headers */, FAB922C6257D99EF0035DAD6 /* Range.h in Headers */, FAC756F61E4F99B400B91289 /* Effect.h in Headers */, @@ -4613,6 +4653,7 @@ FAE64A952071365100BC7981 /* physfs_platform_qnx.c in Sources */, FABDA9FC2552448300B5C523 /* b2_collide_polygon.cpp in Sources */, FABDA9D12552448300B5C523 /* b2_draw.cpp in Sources */, + FACA06B3293EE5CD001A2557 /* Sensor.cpp in Sources */, FA0B7EA41A95902C000E1D17 /* SoundData.cpp in Sources */, FAF1406A1E20934C00F898D2 /* glslang_tab.cpp in Sources */, FA8951A31AA2EDF300EC385A /* wrap_Event.cpp in Sources */, @@ -4644,7 +4685,7 @@ FA1BA0A31E16D97500AA2803 /* wrap_Font.cpp in Sources */, FABDA9842552448200B5C523 /* b2_chain_polygon_contact.cpp in Sources */, FA0B7E0D1A95902C000E1D17 /* Fixture.cpp in Sources */, - FADF53FE1E3D74F200012CC0 /* Text.cpp in Sources */, + FADF53FE1E3D74F200012CC0 /* TextBatch.cpp in Sources */, FA0B7D191A95902C000E1D17 /* TrueTypeRasterizer.cpp in Sources */, FAC271E723B5B5B400C200D3 /* renderstate.cpp in Sources */, FA84DE6727791C36002674C6 /* GraphicsReadback.cpp in Sources */, @@ -4664,7 +4705,7 @@ FA0B7CE61A95902C000E1D17 /* wrap_Source.cpp in Sources */, FA9D8DDE1DEF842A002CD881 /* Drawable.cpp in Sources */, FA0B7CCE1A95902C000E1D17 /* Audio.cpp in Sources */, - FADF54031E3D77B500012CC0 /* wrap_Text.cpp in Sources */, + FADF54031E3D77B500012CC0 /* wrap_TextBatch.cpp in Sources */, FA0B7DCB1A95902C000E1D17 /* Keyboard.cpp in Sources */, FA0B7DFB1A95902C000E1D17 /* Body.cpp in Sources */, FA0B7ED21A95902C000E1D17 /* wrap_ThreadModule.cpp in Sources */, @@ -4688,6 +4729,7 @@ FA0B7AD51A958EA3000E1D17 /* unix.c in Sources */, FAB17BE71ABFAA9000F9BA27 /* lz4.c in Sources */, FAE64A902071364800BC7981 /* physfs_unicode.c in Sources */, + FACA06B1293EE5CD001A2557 /* Sensor.cpp in Sources */, FA4F2BE71DE6650D00CA37D7 /* Transform.cpp in Sources */, FAF140A11E20934C00F898D2 /* RemoveTree.cpp in Sources */, FABDA9972552448300B5C523 /* b2_distance_joint.cpp in Sources */, @@ -4833,6 +4875,7 @@ FA4F2BB41DE1E4BD00CA37D7 /* RecordingDevice.cpp in Sources */, FA0B7DF51A95902C000E1D17 /* wrap_Mouse.cpp in Sources */, FA0B7E861A95902C000E1D17 /* CoreAudioDecoder.cpp in Sources */, + FACA06AD293EE5CD001A2557 /* wrap_Sensor.cpp in Sources */, FA0B7E761A95902C000E1D17 /* wrap_WeldJoint.cpp in Sources */, FA0B7D561A95902C000E1D17 /* Buffer.cpp in Sources */, FA1557C51CE90BD900AFF582 /* EXRHandler.cpp in Sources */, @@ -5037,6 +5080,7 @@ FAF6C9E623C2DE2900D7B5BC /* SpvBuilder.cpp in Sources */, FABDA9C12552448300B5C523 /* b2_rope.cpp in Sources */, FA0B7D1E1A95902C000E1D17 /* ImageRasterizer.cpp in Sources */, + FACA06B2293EE5CD001A2557 /* Sensor.cpp in Sources */, FABDA9FB2552448300B5C523 /* b2_collide_polygon.cpp in Sources */, FABDA9D02552448300B5C523 /* b2_draw.cpp in Sources */, FAF140A31E20934C00F898D2 /* Scan.cpp in Sources */, @@ -5080,7 +5124,7 @@ FAC7CD781FE35E95006A60C7 /* physfs_platform_qnx.c in Sources */, FA0B7D3C1A95902C000E1D17 /* Texture.cpp in Sources */, FABDA9EB2552448300B5C523 /* b2_collide_circle.cpp in Sources */, - FADF53FD1E3D74F200012CC0 /* Text.cpp in Sources */, + FADF53FD1E3D74F200012CC0 /* TextBatch.cpp in Sources */, FA84DE612778D7F3002674C6 /* SpirvIntrinsics.cpp in Sources */, FAFEB29C28F210550025D7D0 /* unixstream.c in Sources */, FA6A2B741F60B6710074C308 /* ByteData.cpp in Sources */, @@ -5095,7 +5139,7 @@ FA9D8DDD1DEF842A002CD881 /* Drawable.cpp in Sources */, FA0B7DFA1A95902C000E1D17 /* Body.cpp in Sources */, FAF6C9EB23C2DE2900D7B5BC /* GlslangToSpv.cpp in Sources */, - FADF54021E3D77B500012CC0 /* wrap_Text.cpp in Sources */, + FADF54021E3D77B500012CC0 /* wrap_TextBatch.cpp in Sources */, FA0B7ED11A95902C000E1D17 /* wrap_ThreadModule.cpp in Sources */, FAC7CD7F1FE35E95006A60C7 /* physfs_archiver_wad.c in Sources */, FA0B7EDF1A95902D000E1D17 /* wrap_Touch.cpp in Sources */, @@ -5112,6 +5156,7 @@ FA0B7AB51A958EA3000E1D17 /* ddsparse.cpp in Sources */, FACA02F41F5E396B0084B28F /* wrap_CompressedData.cpp in Sources */, FAF140AC1E20934C00F898D2 /* Versions.cpp in Sources */, + FACA06B0293EE5CD001A2557 /* Sensor.cpp in Sources */, FA0B79461A958E3B000E1D17 /* Vector.cpp in Sources */, FAC7CD811FE35E95006A60C7 /* physfs_platform_os2.c in Sources */, FABDA9962552448300B5C523 /* b2_distance_joint.cpp in Sources */, @@ -5257,6 +5302,7 @@ FAC7CD891FE35E95006A60C7 /* physfs_archiver_dir.c in Sources */, FAF140751E20934C00F898D2 /* IntermTraverse.cpp in Sources */, FA0B7CE21A95902C000E1D17 /* wrap_Audio.cpp in Sources */, + FACA06AC293EE5CD001A2557 /* wrap_Sensor.cpp in Sources */, FA0B7DF71A95902C000E1D17 /* Body.cpp in Sources */, FABDA9ED2552448300B5C523 /* b2_circle_shape.cpp in Sources */, FA0B7DF41A95902C000E1D17 /* wrap_Mouse.cpp in Sources */, diff --git a/src/common/Module.h b/src/common/Module.h index c7cd4ca0a..013b3e6e2 100644 --- a/src/common/Module.h +++ b/src/common/Module.h @@ -51,6 +51,7 @@ public: M_MATH, M_MOUSE, M_PHYSICS, + M_SENSOR, M_SOUND, M_SYSTEM, M_THREAD, diff --git a/src/common/config.h b/src/common/config.h index bea645bc8..42d3bb27d 100644 --- a/src/common/config.h +++ b/src/common/config.h @@ -159,6 +159,7 @@ # define LOVE_ENABLE_MATH # define LOVE_ENABLE_MOUSE # define LOVE_ENABLE_PHYSICS +# define LOVE_ENABLE_SENSOR # define LOVE_ENABLE_SOUND # define LOVE_ENABLE_SYSTEM # define LOVE_ENABLE_THREAD diff --git a/src/modules/audio/openal/Source.cpp b/src/modules/audio/openal/Source.cpp index cc37cbff9..8a85e2eb7 100644 --- a/src/modules/audio/openal/Source.cpp +++ b/src/modules/audio/openal/Source.cpp @@ -1160,6 +1160,19 @@ int Source::streamAtomic(ALuint buffer, love::sound::Decoder *d) decoded = 0; } + // This shouldn't run after toLoop is calculated in this streamAtomic call, + // otherwise it'll decrease too quickly. + // TODO: this code is hard to understand, can it be made more clear? + // It's meant to reset offsetSamples once OpenAL starts processing the first + // queued buffer after a loop. + if (toLoop > 0) + { + if (--toLoop == 0) + { + offsetSamples = 0; + } + } + if (decoder->isFinished() && isLooping()) { int queued, processed; @@ -1172,14 +1185,6 @@ int Source::streamAtomic(ALuint buffer, love::sound::Decoder *d) d->rewind(); } - if (toLoop > 0) - { - if (--toLoop == 0) - { - offsetSamples = 0; - } - } - return decoded; } diff --git a/src/modules/event/sdl/Event.cpp b/src/modules/event/sdl/Event.cpp index 9039a5de7..ea18cad95 100644 --- a/src/modules/event/sdl/Event.cpp +++ b/src/modules/event/sdl/Event.cpp @@ -32,6 +32,7 @@ #include "audio/Audio.h" #include "common/config.h" #include "timer/Timer.h" +#include "sensor/sdl/Sensor.h" #include @@ -178,6 +179,7 @@ Message *Event::convert(const SDL_Event &e) vargs.reserve(4); love::filesystem::Filesystem *filesystem = nullptr; + love::sensor::Sensor *sensorInstance = nullptr; love::keyboard::Keyboard::Key key = love::keyboard::Keyboard::KEY_UNKNOWN; love::keyboard::Keyboard::Scancode scancode = love::keyboard::Keyboard::SCANCODE_UNKNOWN; @@ -191,10 +193,6 @@ Message *Event::convert(const SDL_Event &e) love::touch::Touch::TouchInfo touchinfo; #endif -#ifdef LOVE_LINUX - static bool touchNormalizationBug = false; -#endif - switch (e.type) { case SDL_KEYDOWN: @@ -313,22 +311,9 @@ Message *Event::convert(const SDL_Event &e) touchinfo.dy = e.tfinger.dy; touchinfo.pressure = e.tfinger.pressure; -#ifdef LOVE_LINUX - // FIXME: hacky workaround for SDL not normalizing touch coordinates in - // its X11 backend: https://bugzilla.libsdl.org/show_bug.cgi?id=2307 - if (touchNormalizationBug || fabs(touchinfo.x) >= 1.5 || fabs(touchinfo.y) >= 1.5 || fabs(touchinfo.dx) >= 1.5 || fabs(touchinfo.dy) >= 1.5) - { - touchNormalizationBug = true; - windowToDPICoords(&touchinfo.x, &touchinfo.y); - windowToDPICoords(&touchinfo.dx, &touchinfo.dy); - } - else -#endif - { - // SDL's coords are normalized to [0, 1], but we want screen coords. - normalizedToDPICoords(&touchinfo.x, &touchinfo.y); - normalizedToDPICoords(&touchinfo.dx, &touchinfo.dy); - } + // SDL's coords are normalized to [0, 1], but we want screen coords. + normalizedToDPICoords(&touchinfo.x, &touchinfo.y); + normalizedToDPICoords(&touchinfo.dx, &touchinfo.dy); // We need to update the love.touch.sdl internal state from here. touchmodule = (touch::sdl::Touch *) Module::getInstance("love.touch.sdl"); @@ -366,12 +351,14 @@ Message *Event::convert(const SDL_Event &e) case SDL_CONTROLLERBUTTONDOWN: case SDL_CONTROLLERBUTTONUP: case SDL_CONTROLLERAXISMOTION: +#if SDL_VERSION_ATLEAST(2, 0, 14) && defined(LOVE_ENABLE_SENSOR) + case SDL_CONTROLLERSENSORUPDATE: +#endif msg = convertJoystickEvent(e); break; case SDL_WINDOWEVENT: msg = convertWindowEvent(e); break; -#if SDL_VERSION_ATLEAST(2, 0, 9) case SDL_DISPLAYEVENT: if (e.display.event == SDL_DISPLAYEVENT_ORIENTATION) { @@ -405,7 +392,6 @@ Message *Event::convert(const SDL_Event &e) msg = new Message("displayrotated", vargs); } break; -#endif case SDL_DROPFILE: filesystem = Module::getInstance(Module::M_FILESYSTEM); if (filesystem != nullptr) @@ -446,6 +432,37 @@ Message *Event::convert(const SDL_Event &e) msg = new Message("localechanged"); break; #endif + case SDL_SENSORUPDATE: + sensorInstance = Module::getInstance(M_SENSOR); + if (sensorInstance) + { + std::vector sensors = sensorInstance->getHandles(); + + for (void *s: sensors) + { + SDL_Sensor *sensor = (SDL_Sensor *) s; + SDL_SensorID id = SDL_SensorGetInstanceID(sensor); + + if (e.sensor.which == id) + { + // Found sensor + const char *sensorType; + if (!sensor::Sensor::getConstant(sensor::sdl::Sensor::convert(SDL_SensorGetType(sensor)), sensorType)) + sensorType = "unknown"; + + vargs.emplace_back(sensorType, strlen(sensorType)); + // Both accelerometer and gyroscope only pass up to 3 values. + // https://github.com/libsdl-org/SDL/blob/SDL2/include/SDL_sensor.h#L81-L127 + vargs.emplace_back(e.sensor.data[0]); + vargs.emplace_back(e.sensor.data[1]); + vargs.emplace_back(e.sensor.data[2]); + msg = new Message("sensorupdated", vargs); + + break; + } + } + } + break; default: break; } @@ -564,6 +581,27 @@ Message *Event::convertJoystickEvent(const SDL_Event &e) const msg = new Message("joystickremoved", vargs); } break; +#if SDL_VERSION_ATLEAST(2, 0, 14) && defined(LOVE_ENABLE_SENSOR) + case SDL_CONTROLLERSENSORUPDATE: + stick = joymodule->getJoystickFromID(e.csensor.which); + if (stick) + { + using Sensor = love::sensor::Sensor; + + const char *sensorName; + Sensor::SensorType sensorType = love::sensor::sdl::Sensor::convert((SDL_SensorType) e.csensor.sensor); + if (!Sensor::getConstant(sensorType, sensorName)) + sensorName = "unknown"; + + vargs.emplace_back(joysticktype, stick); + vargs.emplace_back(sensorName, strlen(sensorName)); + vargs.emplace_back(e.csensor.data[0]); + vargs.emplace_back(e.csensor.data[1]); + vargs.emplace_back(e.csensor.data[2]); + msg = new Message("joysticksensorupdated", vargs); + } + break; +#endif // SDL_VERSION_ATLEAST(2, 0, 14) && defined(LOVE_ENABLE_SENSOR) default: break; } diff --git a/src/modules/graphics/Graphics.cpp b/src/modules/graphics/Graphics.cpp index 535f2cac4..9c9f71171 100644 --- a/src/modules/graphics/Graphics.cpp +++ b/src/modules/graphics/Graphics.cpp @@ -30,7 +30,7 @@ #include "ParticleSystem.h" #include "Font.h" #include "Video.h" -#include "Text.h" +#include "TextBatch.h" #include "common/deprecation.h" #include "common/config.h" @@ -439,9 +439,9 @@ Mesh *Graphics::newMesh(const std::vector &attributes, Pr return new Mesh(attributes, drawmode); } -love::graphics::Text *Graphics::newText(graphics::Font *font, const std::vector &text) +love::graphics::TextBatch *Graphics::newTextBatch(graphics::Font *font, const std::vector &text) { - return new Text(font, text); + return new TextBatch(font, text); } love::data::ByteData *Graphics::readbackBuffer(Buffer *buffer, size_t offset, size_t size, data::ByteData *dest, size_t destoffset) diff --git a/src/modules/graphics/Graphics.h b/src/modules/graphics/Graphics.h index a4e391213..e99aaed11 100644 --- a/src/modules/graphics/Graphics.h +++ b/src/modules/graphics/Graphics.h @@ -58,7 +58,7 @@ namespace graphics class SpriteBatch; class ParticleSystem; -class Text; +class TextBatch; class Video; class Buffer; @@ -460,7 +460,7 @@ public: Mesh *newMesh(const std::vector &vertexformat, const void *data, size_t datasize, PrimitiveType drawmode, BufferDataUsage usage); Mesh *newMesh(const std::vector &attributes, PrimitiveType drawmode); - Text *newText(Font *font, const std::vector &text = {}); + TextBatch *newTextBatch(Font *font, const std::vector &text = {}); data::ByteData *readbackBuffer(Buffer *buffer, size_t offset, size_t size, data::ByteData *dest, size_t destoffset); GraphicsReadback *readbackBufferAsync(Buffer *buffer, size_t offset, size_t size, data::ByteData *dest, size_t destoffset); diff --git a/src/modules/graphics/Mesh.cpp b/src/modules/graphics/Mesh.cpp index adbde8a4d..da44759bc 100644 --- a/src/modules/graphics/Mesh.cpp +++ b/src/modules/graphics/Mesh.cpp @@ -140,7 +140,7 @@ void Mesh::setupAttachedAttributes() if (getAttachedAttributeIndex(name) != -1) throw love::Exception("Duplicate vertex attribute name: %s", name.c_str()); - attachedAttributes.push_back({name, vertexBuffer, nullptr, (int) i, STEP_PER_VERTEX, true}); + attachedAttributes.push_back({name, vertexBuffer, nullptr, (int) i, 0, STEP_PER_VERTEX, true}); } } @@ -208,7 +208,7 @@ bool Mesh::isAttributeEnabled(const std::string &name) const return attachedAttributes[index].enabled; } -void Mesh::attachAttribute(const std::string &name, Buffer *buffer, Mesh *mesh, const std::string &attachname, AttributeStep step) +void Mesh::attachAttribute(const std::string &name, Buffer *buffer, Mesh *mesh, const std::string &attachname, int startindex, AttributeStep step) { if ((buffer->getUsageFlags() & BUFFERUSAGEFLAG_VERTEX) == 0) throw love::Exception("Buffer must be created with vertex buffer support to be used as a Mesh vertex attribute."); @@ -217,6 +217,9 @@ void Mesh::attachAttribute(const std::string &name, Buffer *buffer, Mesh *mesh, if (step == STEP_PER_INSTANCE && !gfx->getCapabilities().features[Graphics::FEATURE_INSTANCING]) throw love::Exception("Vertex attribute instancing is not supported on this system."); + if (startindex < 0 || startindex >= (int) buffer->getArrayLength()) + throw love::Exception("Invalid start array index %d.", startindex + 1); + BufferAttribute oldattrib = {}; BufferAttribute newattrib = {}; @@ -231,6 +234,7 @@ void Mesh::attachAttribute(const std::string &name, Buffer *buffer, Mesh *mesh, newattrib.mesh = mesh; newattrib.enabled = oldattrib.buffer.get() ? oldattrib.enabled : true; newattrib.indexInBuffer = buffer->getDataMemberIndex(attachname); + newattrib.startArrayIndex = startindex; newattrib.step = step; if (newattrib.indexInBuffer < 0) @@ -578,12 +582,13 @@ void Mesh::drawInstanced(Graphics *gfx, const Matrix4 &m, int instancecount) uint16 offset = (uint16) member.offset; uint16 stride = (uint16) buffer->getArrayStride(); + size_t bufferoffset = (size_t) stride * attrib.startArrayIndex; attributes.set(attributeindex, member.decl.format, offset, activebuffers); attributes.setBufferLayout(activebuffers, stride, attrib.step); // TODO: Ideally we want to reuse buffers with the same stride+step. - buffers.set(activebuffers, buffer, 0); + buffers.set(activebuffers, buffer, bufferoffset); activebuffers++; } } diff --git a/src/modules/graphics/Mesh.h b/src/modules/graphics/Mesh.h index a3a67fa2f..47adc7dc2 100644 --- a/src/modules/graphics/Mesh.h +++ b/src/modules/graphics/Mesh.h @@ -57,6 +57,7 @@ public: StrongRef buffer; StrongRef mesh; int indexInBuffer; + int startArrayIndex; AttributeStep step; bool enabled; }; @@ -109,7 +110,7 @@ public: * to make sure this Mesh knows to flush the passed in Mesh's data to its * buffer when drawing. **/ - void attachAttribute(const std::string &name, Buffer *buffer, Mesh *mesh, const std::string &attachname, AttributeStep step = STEP_PER_VERTEX); + void attachAttribute(const std::string &name, Buffer *buffer, Mesh *mesh, const std::string &attachname, int startindex = 0, AttributeStep step = STEP_PER_VERTEX); bool detachAttribute(const std::string &name); const std::vector &getAttachedAttributes() const; diff --git a/src/modules/graphics/Text.cpp b/src/modules/graphics/TextBatch.cpp similarity index 88% rename from src/modules/graphics/Text.cpp rename to src/modules/graphics/TextBatch.cpp index b05eac6bf..23a17b5ad 100644 --- a/src/modules/graphics/Text.cpp +++ b/src/modules/graphics/TextBatch.cpp @@ -18,7 +18,7 @@ * 3. This notice may not be removed or altered from any source distribution. **/ -#include "Text.h" +#include "TextBatch.h" #include "Graphics.h" #include @@ -28,9 +28,9 @@ namespace love namespace graphics { -love::Type Text::type("Text", &Drawable::type); +love::Type TextBatch::type("TextBatch", &Drawable::type); -Text::Text(Font *font, const std::vector &text) +TextBatch::TextBatch(Font *font, const std::vector &text) : font(font) , vertexAttributes(Font::vertexFormat, 0) , vertexData(nullptr) @@ -41,13 +41,13 @@ Text::Text(Font *font, const std::vector &text) set(text); } -Text::~Text() +TextBatch::~TextBatch() { if (vertexData != nullptr) free(vertexData); } -void Text::uploadVertices(const std::vector &vertices, size_t vertoffset) +void TextBatch::uploadVertices(const std::vector &vertices, size_t vertoffset) { size_t offset = vertoffset * sizeof(Font::GlyphVertex); size_t datasize = vertices.size() * sizeof(Font::GlyphVertex); @@ -90,7 +90,7 @@ void Text::uploadVertices(const std::vector &vertices, size_t } } -void Text::regenerateVertices() +void TextBatch::regenerateVertices() { // If the font's texture cache was invalidated then we need to recreate the // text's vertices, since glyph texcoords might have changed. @@ -107,7 +107,7 @@ void Text::regenerateVertices() } } -void Text::addTextData(const TextData &t) +void TextBatch::addTextData(const TextData &t) { std::vector vertices; std::vector newcommands; @@ -172,12 +172,12 @@ void Text::addTextData(const TextData &t) regenerateVertices(); } -void Text::set(const std::vector &text) +void TextBatch::set(const std::vector &text) { return set(text, -1.0f, Font::ALIGN_MAX_ENUM); } -void Text::set(const std::vector &text, float wrap, Font::AlignMode align) +void TextBatch::set(const std::vector &text, float wrap, Font::AlignMode align) { if (text.empty() || (text.size() == 1 && text[0].str.empty())) return clear(); @@ -188,12 +188,12 @@ void Text::set(const std::vector &text, float wrap, Font::A addTextData({codepoints, wrap, align, {}, false, false, Matrix4()}); } -int Text::add(const std::vector &text, const Matrix4 &m) +int TextBatch::add(const std::vector &text, const Matrix4 &m) { return addf(text, -1.0f, Font::ALIGN_MAX_ENUM, m); } -int Text::addf(const std::vector &text, float wrap, Font::AlignMode align, const Matrix4 &m) +int TextBatch::addf(const std::vector &text, float wrap, Font::AlignMode align, const Matrix4 &m) { Font::ColoredCodepoints codepoints; Font::getCodepointsFromString(text, codepoints); @@ -203,7 +203,7 @@ int Text::addf(const std::vector &text, float wrap, Font::A return (int) textData.size() - 1; } -void Text::clear() +void TextBatch::clear() { textData.clear(); drawCommands.clear(); @@ -211,7 +211,7 @@ void Text::clear() vertOffset = 0; } -void Text::setFont(Font *f) +void TextBatch::setFont(Font *f) { font.set(f); @@ -221,12 +221,12 @@ void Text::setFont(Font *f) regenerateVertices(); } -Font *Text::getFont() const +Font *TextBatch::getFont() const { return font.get(); } -int Text::getWidth(int index) const +int TextBatch::getWidth(int index) const { if (index < 0) index = std::max((int) textData.size() - 1, 0); @@ -237,7 +237,7 @@ int Text::getWidth(int index) const return textData[index].textInfo.width; } -int Text::getHeight(int index) const +int TextBatch::getHeight(int index) const { if (index < 0) index = std::max((int) textData.size() - 1, 0); @@ -248,7 +248,7 @@ int Text::getHeight(int index) const return textData[index].textInfo.height; } -void Text::draw(Graphics *gfx, const Matrix4 &m) +void TextBatch::draw(Graphics *gfx, const Matrix4 &m) { if (vertexBuffer == nullptr || vertexData == nullptr || drawCommands.empty()) return; diff --git a/src/modules/graphics/Text.h b/src/modules/graphics/TextBatch.h similarity index 95% rename from src/modules/graphics/Text.h rename to src/modules/graphics/TextBatch.h index d41af1857..ec466827c 100644 --- a/src/modules/graphics/Text.h +++ b/src/modules/graphics/TextBatch.h @@ -34,14 +34,14 @@ namespace graphics class Graphics; -class Text : public Drawable +class TextBatch : public Drawable { public: static love::Type type; - Text(Font *font, const std::vector &text = {}); - virtual ~Text(); + TextBatch(Font *font, const std::vector &text = {}); + virtual ~TextBatch(); void set(const std::vector &text); void set(const std::vector &text, float wrap, Font::AlignMode align); diff --git a/src/modules/graphics/vulkan/Graphics.cpp b/src/modules/graphics/vulkan/Graphics.cpp index ebfc21969..d1995fcf4 100644 --- a/src/modules/graphics/vulkan/Graphics.cpp +++ b/src/modules/graphics/vulkan/Graphics.cpp @@ -28,7 +28,7 @@ #include "Shader.h" #include "Vulkan.h" -#include "SDL_vulkan.h" +#include #include #include @@ -468,7 +468,8 @@ void Graphics::setViewportSize(int width, int height, int pixelwidth, int pixelh this->pixelWidth = pixelwidth; this->pixelHeight = pixelheight; - resetProjection(); + if (!isRenderTargetActive()) + resetProjection(); } bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) @@ -476,6 +477,9 @@ bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int requestedMsaa = msaa; windowHasStencil = windowhasstencil; + // Must be called before the swapchain is created. + setViewportSize(width, height, pixelwidth, pixelheight); + cleanUpFunctions.clear(); cleanUpFunctions.resize(MAX_FRAMES_IN_FLIGHT); @@ -529,8 +533,6 @@ bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int restoreState(states.back()); - setViewportSize(width, height, pixelwidth, pixelheight); - Vulkan::resetShaderSwitches(); frameCounter = 0; @@ -1783,16 +1785,20 @@ VkPresentModeKHR Graphics::chooseSwapPresentMode(const std::vector(M_WINDOW); - const void *handle = window->getHandle(); - - int width, height; - SDL_Vulkan_GetDrawableSize((SDL_Window*)handle, &width, &height); - VkExtent2D actualExtent = { - static_cast(width), - static_cast(height) + static_cast(pixelWidth), + static_cast(pixelHeight) }; actualExtent.width = clampuint32_t(actualExtent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width); diff --git a/src/modules/graphics/wrap_Graphics.cpp b/src/modules/graphics/wrap_Graphics.cpp index d3eb49432..76d6a3e64 100644 --- a/src/modules/graphics/wrap_Graphics.cpp +++ b/src/modules/graphics/wrap_Graphics.cpp @@ -2101,21 +2101,21 @@ int w_newMesh(lua_State *L) return 1; } -int w_newText(lua_State *L) +int w_newTextBatch(lua_State *L) { luax_checkgraphicscreated(L); graphics::Font *font = luax_checkfont(L, 1); - Text *t = nullptr; + TextBatch *t = nullptr; if (lua_isnoneornil(L, 2)) - luax_catchexcept(L, [&](){ t = instance()->newText(font); }); + luax_catchexcept(L, [&](){ t = instance()->newTextBatch(font); }); else { std::vector text; luax_checkcoloredstring(L, 2, text); - luax_catchexcept(L, [&](){ t = instance()->newText(font, text); }); + luax_catchexcept(L, [&](){ t = instance()->newTextBatch(font, text); }); } luax_pushtype(L, t); @@ -2123,6 +2123,12 @@ int w_newText(lua_State *L) return 1; } +int w_newText(lua_State *L) +{ + luax_markdeprecated(L, 1, "love.graphics.newText", API_FUNCTION, DEPRECATED_RENAMED, "love.graphics.newTextBatch"); + return w_newTextBatch(L); +} + int w_newVideo(lua_State *L) { luax_checkgraphicscreated(L); @@ -3769,7 +3775,7 @@ static const luaL_Reg functions[] = { "newVertexBuffer", w_newVertexBuffer }, { "newIndexBuffer", w_newIndexBuffer }, { "newMesh", w_newMesh }, - { "newText", w_newText }, + { "newTextBatch", w_newTextBatch }, { "_newVideo", w_newVideo }, { "readbackBuffer", w_readbackBuffer }, @@ -3895,6 +3901,7 @@ static const luaL_Reg functions[] = { "newArrayImage", w_newArrayImage }, { "newVolumeImage", w_newVolumeImage }, { "newCubeImage", w_newCubeImage }, + { "newText", w_newText }, { "getCanvasFormats", w_getCanvasFormats }, { "getImageFormats", w_getImageFormats }, @@ -3919,7 +3926,7 @@ static const lua_CFunction types[] = luaopen_particlesystem, luaopen_shader, luaopen_mesh, - luaopen_text, + luaopen_textbatch, luaopen_video, 0 }; diff --git a/src/modules/graphics/wrap_Graphics.h b/src/modules/graphics/wrap_Graphics.h index a2b9d0b89..fbd3e4026 100644 --- a/src/modules/graphics/wrap_Graphics.h +++ b/src/modules/graphics/wrap_Graphics.h @@ -29,7 +29,7 @@ #include "wrap_ParticleSystem.h" #include "wrap_Shader.h" #include "wrap_Mesh.h" -#include "wrap_Text.h" +#include "wrap_TextBatch.h" #include "wrap_Video.h" #include "wrap_Buffer.h" #include "wrap_GraphicsReadback.h" diff --git a/src/modules/graphics/wrap_Mesh.cpp b/src/modules/graphics/wrap_Mesh.cpp index 8096c0509..709739c76 100644 --- a/src/modules/graphics/wrap_Mesh.cpp +++ b/src/modules/graphics/wrap_Mesh.cpp @@ -314,8 +314,9 @@ int w_Mesh_attachAttribute(lua_State *L) return luax_enumerror(L, "vertex attribute step", getConstants(step), stepstr); const char *attachname = luaL_optstring(L, 5, name); + int startindex = (int) luaL_optinteger(L, 6, 1) - 1; - luax_catchexcept(L, [&](){ t->attachAttribute(name, buffer, mesh, attachname, step); }); + luax_catchexcept(L, [&](){ t->attachAttribute(name, buffer, mesh, attachname, startindex, step); }); return 0; } @@ -340,7 +341,7 @@ int w_Mesh_getAttachedAttributes(lua_State *L) { const auto &attrib = attributes[i]; - lua_createtable(L, 4, 0); + lua_createtable(L, 5, 0); luax_pushstring(L, attrib.name); lua_rawseti(L, -1, 1); @@ -358,6 +359,9 @@ int w_Mesh_getAttachedAttributes(lua_State *L) luax_pushstring(L, member.decl.name); lua_rawseti(L, -1, 4); + lua_pushinteger(L, attrib.startArrayIndex + 1); + lua_rawseti(L, -1, 5); + lua_rawseti(L, -1, i + 1); } diff --git a/src/modules/graphics/wrap_Text.cpp b/src/modules/graphics/wrap_TextBatch.cpp similarity index 74% rename from src/modules/graphics/wrap_Text.cpp rename to src/modules/graphics/wrap_TextBatch.cpp index 98ed593d6..d49f12602 100644 --- a/src/modules/graphics/wrap_Text.cpp +++ b/src/modules/graphics/wrap_TextBatch.cpp @@ -18,7 +18,7 @@ * 3. This notice may not be removed or altered from any source distribution. **/ -#include "wrap_Text.h" +#include "wrap_TextBatch.h" #include "wrap_Font.h" #include "math/wrap_Transform.h" @@ -27,14 +27,14 @@ namespace love namespace graphics { -Text *luax_checktext(lua_State *L, int idx) +TextBatch *luax_checktextbatch(lua_State *L, int idx) { - return luax_checktype(L, idx); + return luax_checktype(L, idx); } -int w_Text_set(lua_State *L) +int w_TextBatch_set(lua_State *L) { - Text *t = luax_checktext(L, 1); + TextBatch *t = luax_checktextbatch(L, 1); std::vector newtext; luax_checkcoloredstring(L, 2, newtext); @@ -43,9 +43,9 @@ int w_Text_set(lua_State *L) return 0; } -int w_Text_setf(lua_State *L) +int w_TextBatch_setf(lua_State *L) { - Text *t = luax_checktext(L, 1); + TextBatch *t = luax_checktextbatch(L, 1); float wraplimit = (float) luaL_checknumber(L, 3); @@ -62,9 +62,9 @@ int w_Text_setf(lua_State *L) return 0; } -int w_Text_add(lua_State *L) +int w_TextBatch_add(lua_State *L) { - Text *t = luax_checktext(L, 1); + TextBatch *t = luax_checktextbatch(L, 1); int index = 0; @@ -96,9 +96,9 @@ int w_Text_add(lua_State *L) return 1; } -int w_Text_addf(lua_State *L) +int w_TextBatch_addf(lua_State *L) { - Text *t = luax_checktext(L, 1); + TextBatch *t = luax_checktextbatch(L, 1); int index = 0; @@ -138,72 +138,72 @@ int w_Text_addf(lua_State *L) return 1; } -int w_Text_clear(lua_State *L) +int w_TextBatch_clear(lua_State *L) { - Text *t = luax_checktext(L, 1); + TextBatch *t = luax_checktextbatch(L, 1); luax_catchexcept(L, [&](){ t->clear(); }); return 0; } -int w_Text_setFont(lua_State *L) +int w_TextBatch_setFont(lua_State *L) { - Text *t = luax_checktext(L, 1); + TextBatch *t = luax_checktextbatch(L, 1); Font *f = luax_checktype(L, 2); luax_catchexcept(L, [&](){ t->setFont(f); }); return 0; } -int w_Text_getFont(lua_State *L) +int w_TextBatch_getFont(lua_State *L) { - Text *t = luax_checktext(L, 1); + TextBatch *t = luax_checktextbatch(L, 1); Font *f = t->getFont(); luax_pushtype(L, f); return 1; } -int w_Text_getWidth(lua_State *L) +int w_TextBatch_getWidth(lua_State *L) { - Text *t = luax_checktext(L, 1); + TextBatch *t = luax_checktextbatch(L, 1); int index = (int) luaL_optinteger(L, 2, 0) - 1; lua_pushnumber(L, t->getWidth(index)); return 1; } -int w_Text_getHeight(lua_State *L) +int w_TextBatch_getHeight(lua_State *L) { - Text *t = luax_checktext(L, 1); + TextBatch *t = luax_checktextbatch(L, 1); int index = (int) luaL_optinteger(L, 2, 0) - 1; lua_pushnumber(L, t->getHeight(index)); return 1; } -int w_Text_getDimensions(lua_State *L) +int w_TextBatch_getDimensions(lua_State *L) { - Text *t = luax_checktext(L, 1); + TextBatch *t = luax_checktextbatch(L, 1); int index = (int) luaL_optinteger(L, 2, 0) - 1; lua_pushnumber(L, t->getWidth(index)); lua_pushnumber(L, t->getHeight(index)); return 2; } -static const luaL_Reg w_Text_functions[] = +static const luaL_Reg w_TextBatch_functions[] = { - { "set", w_Text_set }, - { "setf", w_Text_setf }, - { "add", w_Text_add }, - { "addf", w_Text_addf }, - { "clear", w_Text_clear }, - { "setFont", w_Text_setFont }, - { "getFont", w_Text_getFont }, - { "getWidth", w_Text_getWidth }, - { "getHeight", w_Text_getHeight }, - { "getDimensions", w_Text_getDimensions }, + { "set", w_TextBatch_set }, + { "setf", w_TextBatch_setf }, + { "add", w_TextBatch_add }, + { "addf", w_TextBatch_addf }, + { "clear", w_TextBatch_clear }, + { "setFont", w_TextBatch_setFont }, + { "getFont", w_TextBatch_getFont }, + { "getWidth", w_TextBatch_getWidth }, + { "getHeight", w_TextBatch_getHeight }, + { "getDimensions", w_TextBatch_getDimensions }, { 0, 0 } }; -extern "C" int luaopen_text(lua_State *L) +extern "C" int luaopen_textbatch(lua_State *L) { - return luax_register_type(L, &Text::type, w_Text_functions, nullptr); + return luax_register_type(L, &TextBatch::type, w_TextBatch_functions, nullptr); } } // graphics diff --git a/src/modules/graphics/wrap_Text.h b/src/modules/graphics/wrap_TextBatch.h similarity index 89% rename from src/modules/graphics/wrap_Text.h rename to src/modules/graphics/wrap_TextBatch.h index 3295e3fdc..23f16516e 100644 --- a/src/modules/graphics/wrap_Text.h +++ b/src/modules/graphics/wrap_TextBatch.h @@ -20,7 +20,7 @@ #pragma once -#include "Text.h" +#include "TextBatch.h" #include "common/runtime.h" namespace love @@ -28,8 +28,8 @@ namespace love namespace graphics { -Text *luax_checktext(lua_State *L, int idx); -extern "C" int luaopen_text(lua_State *L); +TextBatch *luax_checktextbatch(lua_State *L, int idx); +extern "C" int luaopen_textbatch(lua_State *L); } // graphics } // love diff --git a/src/modules/graphics/wrap_Texture.cpp b/src/modules/graphics/wrap_Texture.cpp index 4a416a097..e657fffce 100644 --- a/src/modules/graphics/wrap_Texture.cpp +++ b/src/modules/graphics/wrap_Texture.cpp @@ -242,7 +242,7 @@ int w_Texture_setWrap(lua_State *L) return luax_enumerror(L, "wrap mode", SamplerState::getConstants(s.wrapW), rstr); luax_catchexcept(L, [&](){ t->setSamplerState(s); }); - return 1; + return 0; } int w_Texture_getWrap(lua_State *L) diff --git a/src/modules/joystick/Joystick.h b/src/modules/joystick/Joystick.h index 40002b460..4d201123c 100644 --- a/src/modules/joystick/Joystick.h +++ b/src/modules/joystick/Joystick.h @@ -24,6 +24,7 @@ // LOVE #include "common/Object.h" #include "common/StringMap.h" +#include "sensor/Sensor.h" // stdlib #include @@ -38,6 +39,8 @@ class Joystick : public Object { public: + using Sensor = love::sensor::Sensor; + static love::Type type; // Joystick hat values. @@ -198,6 +201,11 @@ public: virtual bool setVibration() = 0; virtual void getVibration(float &left, float &right) = 0; + virtual bool hasSensor(Sensor::SensorType type) const = 0; + virtual bool isSensorEnabled(Sensor::SensorType type) const = 0; + virtual void setSensorEnabled(Sensor::SensorType type, bool enabled) = 0; + virtual std::vector getSensorData(Sensor::SensorType type) const = 0; + STRINGMAP_CLASS_DECLARE(Hat); STRINGMAP_CLASS_DECLARE(GamepadType); STRINGMAP_CLASS_DECLARE(GamepadAxis); diff --git a/src/modules/joystick/sdl/Joystick.cpp b/src/modules/joystick/sdl/Joystick.cpp index 482a4b48a..2d5a2cc01 100644 --- a/src/modules/joystick/sdl/Joystick.cpp +++ b/src/modules/joystick/sdl/Joystick.cpp @@ -22,6 +22,10 @@ #include "common/config.h" #include "Joystick.h" #include "common/int.h" +#include "sensor/sdl/Sensor.h" + +// SDL +#include // C++ #include @@ -409,7 +413,6 @@ int Joystick::getID() const void Joystick::getDeviceInfo(int &vendorID, int &productID, int &productVersion) const { -#if SDL_VERSION_ATLEAST(2, 0, 6) if (joyhandle != nullptr) { vendorID = SDL_JoystickGetVendor(joyhandle); @@ -417,7 +420,6 @@ void Joystick::getDeviceInfo(int &vendorID, int &productID, int &productVersion) productVersion = SDL_JoystickGetProductVersion(joyhandle); } else -#endif { vendorID = 0; productID = 0; @@ -521,10 +523,8 @@ bool Joystick::setVibration(float left, float right, float duration) bool success = false; -#if SDL_VERSION_ATLEAST(2, 0, 9) if (SDL_JoystickRumble(joyhandle, (Uint16)(left * LOVE_UINT16_MAX), (Uint16)(right * LOVE_UINT16_MAX), length) == 0) success = true; -#endif if (!success && !checkCreateHaptic()) return false; @@ -606,10 +606,8 @@ bool Joystick::setVibration() { bool success = false; -#if SDL_VERSION_ATLEAST(2, 0, 9) if (!success) success = isConnected() && SDL_JoystickRumble(joyhandle, 0, 0, 0) == 0; -#endif if (!success && SDL_WasInit(SDL_INIT_HAPTIC) && haptic && SDL_HapticIndex(haptic) != -1) success = (SDL_HapticStopEffect(haptic, vibration.id) == 0); @@ -643,6 +641,86 @@ void Joystick::getVibration(float &left, float &right) right = vibration.right; } +bool Joystick::hasSensor(Sensor::SensorType type) const +{ +#if SDL_VERSION_ATLEAST(2, 0, 14) && defined(LOVE_ENABLE_SENSOR) + using SDLSensor = love::sensor::sdl::Sensor; + + if (!isGamepad()) + return false; + + return SDL_GameControllerHasSensor(controller, SDLSensor::convert(type)) == SDL_TRUE; +#else + return false; +#endif +} + +bool Joystick::isSensorEnabled(Sensor::SensorType type) const +{ +#if SDL_VERSION_ATLEAST(2, 0, 14) && defined(LOVE_ENABLE_SENSOR) + using SDLSensor = love::sensor::sdl::Sensor; + + if (!isGamepad()) + return false; + + return SDL_GameControllerIsSensorEnabled(controller, SDLSensor::convert(type)) == SDL_TRUE; +#else + return false; +#endif +} + +void Joystick::setSensorEnabled(Sensor::SensorType type, bool enabled) +{ +#if SDL_VERSION_ATLEAST(2, 0, 14) && defined(LOVE_ENABLE_SENSOR) + using SDLSensor = love::sensor::sdl::Sensor; + + if (!isGamepad()) + throw love::Exception("Sensor is only supported on gamepad"); + + if (SDL_GameControllerSetSensorEnabled(controller, SDLSensor::convert(type), enabled ? SDL_TRUE : SDL_FALSE) != 0) + { + const char *name = nullptr; + SDLSensor::getConstant(type, name); + + throw love::Exception("Could not open \"%s\" SDL gamepad sensor (%s)", name, SDL_GetError()); + } +#else + throw love::Exception("Compiled version of SDL or LOVE does not support gamepad sensor"); +#endif +} + +std::vector Joystick::getSensorData(Sensor::SensorType type) const +{ +#if SDL_VERSION_ATLEAST(2, 0, 14) && defined(LOVE_ENABLE_SENSOR) + using SDLSensor = love::sensor::sdl::Sensor; + + if (!isGamepad()) + throw love::Exception("Sensor is only supported on gamepad"); + + std::vector data(3); + + if (!isSensorEnabled(type)) + { + const char *name = nullptr; + SDLSensor::getConstant(type, name); + + throw love::Exception("\"%s\" gamepad sensor is not enabled", name); + } + + if (SDL_GameControllerGetSensorData(controller, SDLSensor::convert(type), data.data(), (int) data.size()) != 0) + { + const char *name = nullptr; + SDLSensor::getConstant(type, name); + + throw love::Exception("Could not get \"%s\" SDL gamepad sensor data (%s)", name, SDL_GetError()); + } + + return data; +#else + throw love::Exception("Compiled version of SDL or LOVE does not support gamepad sensor"); +#endif +} + bool Joystick::getConstant(Uint8 in, Joystick::Hat &out) { return hats.find(in, out); diff --git a/src/modules/joystick/sdl/Joystick.h b/src/modules/joystick/sdl/Joystick.h index 664ecd627..3cec2f061 100644 --- a/src/modules/joystick/sdl/Joystick.h +++ b/src/modules/joystick/sdl/Joystick.h @@ -88,6 +88,11 @@ public: bool setVibration() override; void getVibration(float &left, float &right) override; + bool hasSensor(Sensor::SensorType type) const override; + bool isSensorEnabled(Sensor::SensorType type) const override; + void setSensorEnabled(Sensor::SensorType type, bool enabled) override; + std::vector getSensorData(Sensor::SensorType type) const override; + static bool getConstant(Hat in, Uint8 &out); static bool getConstant(Uint8 in, Hat &out); diff --git a/src/modules/joystick/wrap_Joystick.cpp b/src/modules/joystick/wrap_Joystick.cpp index e1d66f884..214f7e303 100644 --- a/src/modules/joystick/wrap_Joystick.cpp +++ b/src/modules/joystick/wrap_Joystick.cpp @@ -21,6 +21,7 @@ // LOVE #include "wrap_Joystick.h" #include "wrap_JoystickModule.h" +#include "sensor/Sensor.h" #include @@ -367,6 +368,78 @@ int w_Joystick_getVibration(lua_State *L) return 2; } +#ifdef LOVE_ENABLE_SENSOR + +int w_Joystick_hasSensor(lua_State *L) +{ + using namespace love::sensor; + + Joystick *j = luax_checkjoystick(L, 1); + const char *sensorType = luaL_checkstring(L, 2); + + Sensor::SensorType type; + if (!Sensor::getConstant(sensorType, type)) + luax_enumerror(L, "sensor type", Sensor::getConstants(type), sensorType); + + luax_pushboolean(L, j->hasSensor(type)); + return 1; +} + +int w_Joystick_isSensorEnabled(lua_State *L) +{ + using namespace love::sensor; + + Joystick *j = luax_checkjoystick(L, 1); + const char *sensorType = luaL_checkstring(L, 2); + + Sensor::SensorType type; + if (!Sensor::getConstant(sensorType, type)) + luax_enumerror(L, "sensor type", Sensor::getConstants(type), sensorType); + + luax_pushboolean(L, j->isSensorEnabled(type)); + return 1; +} + +int w_Joystick_setSensorEnabled(lua_State *L) +{ + using namespace love::sensor; + + Joystick *j = luax_checkjoystick(L, 1); + const char *sensorType = luaL_checkstring(L, 2); + + Sensor::SensorType type; + if (!Sensor::getConstant(sensorType, type)) + luax_enumerror(L, "sensor type", Sensor::getConstants(type), sensorType); + + bool enabled = luax_checkboolean(L, 3); + + luax_catchexcept(L, [&]() { j->setSensorEnabled(type, enabled); }); + return 0; +} + +int w_Joystick_getSensorData(lua_State *L) +{ + using namespace love::sensor; + + Joystick *j = luax_checkjoystick(L, 1); + const char *sensorType = luaL_checkstring(L, 2); + + Sensor::SensorType type; + if (!Sensor::getConstant(sensorType, type)) + luax_enumerror(L, "sensor type", Sensor::getConstants(type), sensorType); + + std::vector data; + + luax_catchexcept(L, [&]() { data = j->getSensorData(type); }); + + for (float f: data) + lua_pushnumber(L, f); + + return (int) data.size(); +} + +#endif // LOVE_ENABLE_SENSOR + // List of functions to wrap. static const luaL_Reg w_Joystick_functions[] = { @@ -396,6 +469,13 @@ static const luaL_Reg w_Joystick_functions[] = { "setVibration", w_Joystick_setVibration }, { "getVibration", w_Joystick_getVibration }, +#ifdef LOVE_ENABLE_SENSOR + { "hasSensor", w_Joystick_hasSensor }, + { "isSensorEnabled", w_Joystick_isSensorEnabled }, + { "setSensorEnabled", w_Joystick_setSensorEnabled }, + { "getSensorData", w_Joystick_setSensorEnabled }, +#endif + // From wrap_JoystickModule. { "getConnectedIndex", w_getIndex }, diff --git a/src/modules/love/boot.lua b/src/modules/love/boot.lua index 8eb030604..19df5e34b 100644 --- a/src/modules/love/boot.lua +++ b/src/modules/love/boot.lua @@ -189,6 +189,7 @@ function love.init() audio = true, math = true, physics = true, + sensor = true, sound = true, system = true, font = true, @@ -204,7 +205,7 @@ function love.init() identity = false, appendidentity = false, externalstorage = false, -- Only relevant for Android. - accelerometerjoystick = true, -- Only relevant for Android / iOS. + accelerometerjoystick = nil, -- Only relevant for Android / iOS, deprecated. gammacorrect = false, highdpi = false, renderers = nil, @@ -311,6 +312,7 @@ function love.init() "touch", "sound", "system", + "sensor", "audio", "image", "video", diff --git a/src/modules/love/callbacks.lua b/src/modules/love/callbacks.lua index b0532a346..315998c1c 100644 --- a/src/modules/love/callbacks.lua +++ b/src/modules/love/callbacks.lua @@ -88,6 +88,9 @@ function love.createhandlers() joystickremoved = function (j) if love.joystickremoved then return love.joystickremoved(j) end end, + joysticksensorupdated = function (j, sensorType, x, y, z) + if love.joysticksensorupdated then return love.joysticksensorupdated(j, sensorType, x, y, z) end + end, focus = function (f) if love.focus then return love.focus(f) end end, @@ -134,6 +137,9 @@ function love.createhandlers() love.audio.setPlaybackDevice() end end, + sensorupdated = function (sensorType, x, y, z) + if love.sensorupdated then return love.sensorupdated(sensorType, x, y, z) end + end, }, { __index = function(self, name) error("Unknown event: " .. name) @@ -232,7 +238,8 @@ function love.errhand(msg) if love.audio then love.audio.stop() end love.graphics.reset() - local font = love.graphics.setNewFont(14) + local font = love.graphics.newFont(14) + love.graphics.setFont(font) love.graphics.setColor(1, 1, 1) diff --git a/src/modules/love/love.cpp b/src/modules/love/love.cpp index 4c1494aa4..99ee86be6 100644 --- a/src/modules/love/love.cpp +++ b/src/modules/love/love.cpp @@ -152,6 +152,9 @@ extern "C" #if defined(LOVE_ENABLE_PHYSICS) extern int luaopen_love_physics(lua_State*); #endif +#if defined(LOVE_ENABLE_SENSOR) + extern int luaopen_love_sensor(lua_State*); +#endif #if defined(LOVE_ENABLE_SOUND) extern int luaopen_love_sound(lua_State*); #endif @@ -221,6 +224,9 @@ static const luaL_Reg modules[] = { #if defined(LOVE_ENABLE_PHYSICS) { "love.physics", luaopen_love_physics }, #endif +#if defined(LOVE_ENABLE_SENSOR) + { "love.sensor", luaopen_love_sensor }, +#endif #if defined(LOVE_ENABLE_SOUND) { "love.sound", luaopen_love_sound }, #endif @@ -778,6 +784,10 @@ int w__setAccelerometerAsJoystick(lua_State *L) { bool enable = (bool) lua_toboolean(L, 1); SDL_SetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, enable ? "1" : "0"); + + if (enable) + love::luax_markdeprecated(L, 1, "accelerometerjoystick", love::API_FIELD, love::DEPRECATED_REPLACED, "love.sensor module"); + return 0; } #endif // LOVE_LEGENDARY_ACCELEROMETER_AS_JOYSTICK_HACK diff --git a/src/modules/physics/box2d/DistanceJoint.cpp b/src/modules/physics/box2d/DistanceJoint.cpp index cee19c707..5d391fe6c 100644 --- a/src/modules/physics/box2d/DistanceJoint.cpp +++ b/src/modules/physics/box2d/DistanceJoint.cpp @@ -56,34 +56,6 @@ float DistanceJoint::getLength() const return Physics::scaleUp(joint->GetLength()); } -void DistanceJoint::setFrequency(float hz) -{ - float stiffness, damping; - b2LinearStiffness(stiffness, damping, hz, getDampingRatio(), joint->GetBodyA(), joint->GetBodyB()); - joint->SetStiffness(stiffness); -} - -float DistanceJoint::getFrequency() const -{ - float frequency, ratio; - Physics::b2LinearFrequency(frequency, ratio, joint->GetStiffness(), joint->GetDamping(), joint->GetBodyA(), joint->GetBodyB()); - return frequency; -} - -void DistanceJoint::setDampingRatio(float ratio) -{ - float stiffness, damping; - b2LinearStiffness(stiffness, damping, getFrequency(), ratio, joint->GetBodyA(), joint->GetBodyB()); - joint->SetDamping(damping); -} - -float DistanceJoint::getDampingRatio() const -{ - float frequency, ratio; - Physics::b2LinearFrequency(frequency, ratio, joint->GetStiffness(), joint->GetDamping(), joint->GetBodyA(), joint->GetBodyB()); - return ratio; -} - void DistanceJoint::setStiffness(float k) { joint->SetStiffness(k); diff --git a/src/modules/physics/box2d/DistanceJoint.h b/src/modules/physics/box2d/DistanceJoint.h index e178dd34c..c054da064 100644 --- a/src/modules/physics/box2d/DistanceJoint.h +++ b/src/modules/physics/box2d/DistanceJoint.h @@ -56,26 +56,6 @@ public: **/ float getLength() const; - /** - * Sets the response speed. Independent of mass - **/ - void setFrequency(float hz); - - /** - * Gets the response speed. Independent of mass - **/ - float getFrequency() const; - - /** - * Set the spring damping ratio. Independent of mass - **/ - void setDampingRatio(float ratio); - - /** - * Get the spring damping ratio. Independent of mass - **/ - float getDampingRatio() const; - /** * Sets the response speed. Dependent of mass **/ diff --git a/src/modules/physics/box2d/MouseJoint.cpp b/src/modules/physics/box2d/MouseJoint.cpp index 9e61f3c1f..65a59c064 100644 --- a/src/modules/physics/box2d/MouseJoint.cpp +++ b/src/modules/physics/box2d/MouseJoint.cpp @@ -49,6 +49,7 @@ MouseJoint::MouseJoint(Body *body1, float x, float y) def.bodyB = body1->body; def.maxForce = 1000.0f * body1->body->GetMass(); def.target = Physics::scaleDown(b2Vec2(x,y)); + Physics::computeLinearStiffness(def.stiffness, def.damping, 5.0, 0.7, def.bodyA, def.bodyB); joint = (b2MouseJoint *)createJoint(&def); } @@ -78,40 +79,6 @@ float MouseJoint::getMaxForce() const return Physics::scaleUp(joint->GetMaxForce()); } -void MouseJoint::setFrequency(float hz) -{ - // This is kind of a crappy check. The Stiffness is used in an internal - // box2d calculation whose result must be > FLT_EPSILON, but other variables - // go into that calculation... - if (hz <= FLT_EPSILON * 2) - throw love::Exception("MouseJoint Stiffness must be a positive number."); - - float stiffness, damping; - b2LinearStiffness(stiffness, damping, hz, getDampingRatio(), joint->GetBodyA(), joint->GetBodyB()); - joint->SetStiffness(stiffness); -} - -float MouseJoint::getFrequency() const -{ - float frequency, ratio; - Physics::b2LinearFrequency(frequency, ratio, joint->GetStiffness(), joint->GetDamping(), joint->GetBodyA(), joint->GetBodyB()); - return frequency; -} - -void MouseJoint::setDampingRatio(float ratio) -{ - float stiffness, damping; - b2LinearStiffness(stiffness, damping, getFrequency(), ratio, joint->GetBodyA(), joint->GetBodyB()); - joint->SetDamping(damping); -} - -float MouseJoint::getDampingRatio() const -{ - float frequency, ratio; - Physics::b2LinearFrequency(frequency, ratio, joint->GetStiffness(), joint->GetDamping(), joint->GetBodyA(), joint->GetBodyB()); - return ratio; -} - void MouseJoint::setStiffness(float k) { // This is kind of a crappy check. The Stiffness is used in an internal diff --git a/src/modules/physics/box2d/Physics.cpp b/src/modules/physics/box2d/Physics.cpp index 3871757f7..f212f8b9e 100644 --- a/src/modules/physics/box2d/Physics.cpp +++ b/src/modules/physics/box2d/Physics.cpp @@ -405,7 +405,12 @@ b2AABB Physics::scaleUp(const b2AABB &aabb) return t; } -void Physics::b2LinearFrequency(float& frequency, float& ratio, float stiffness, float damping, b2Body* bodyA, b2Body* bodyB) +void Physics::computeLinearStiffness(float &stiffness, float &damping, float frequency, float dampingRatio, b2Body *bodyA, b2Body *bodyB) +{ + b2LinearStiffness(stiffness, damping, frequency, dampingRatio, bodyA, bodyB); +} + +void Physics::computeLinearFrequency(float &frequency, float &ratio, float stiffness, float damping, b2Body *bodyA, b2Body *bodyB) { float massA = bodyA->GetMass(); float massB = bodyB->GetMass(); @@ -435,7 +440,12 @@ void Physics::b2LinearFrequency(float& frequency, float& ratio, float stiffness, ratio = damping / (mass * 2.0f * omega); } -void Physics::b2AngularFrequency(float& frequency, float& ratio, float stiffness, float damping, b2Body* bodyA, b2Body* bodyB) +void Physics::computeAngularStiffness(float &stiffness, float &damping, float frequency, float dampingRatio, b2Body *bodyA, b2Body *bodyB) +{ + b2AngularStiffness(stiffness, damping, frequency, dampingRatio, bodyA, bodyB); +} + +void Physics::computeAngularFrequency(float &frequency, float &ratio, float stiffness, float damping, b2Body *bodyA, b2Body *bodyB) { float IA = bodyA->GetInertia(); float IB = bodyB->GetInertia(); diff --git a/src/modules/physics/box2d/Physics.h b/src/modules/physics/box2d/Physics.h index 73e00c8cb..ad551eda9 100644 --- a/src/modules/physics/box2d/Physics.h +++ b/src/modules/physics/box2d/Physics.h @@ -360,18 +360,18 @@ public: static b2AABB scaleUp(const b2AABB& aabb); /** - * Calculates linear frequency and damping radio from stiffness and damping - * @param frequency The output frequency - * @param ratio The output damping ratio - * @param stiffness The joint stiffness - * @param damping The joint damping + * Calculates the stiffness and damping, given the linear frequency, and damping ratio. + * @param stiffness The output stiffness + * @param damping The output damping + * @param frequency The joint linear frequency + * @param dampingRatio The joint damping ratio * @param bodyA The bodyA of the joint * @param bodyB The bodyB of the joint **/ - static void b2LinearFrequency(float& frequency, float& ratio, float stiffness, float damping, b2Body* bodyA, b2Body* bodyB); + static void computeLinearStiffness(float& stiffness, float& damping, float frequency, float dampingRatio, b2Body* bodyA, b2Body* bodyB); /** - * Calculates angular frequency and damping radio from stiffness and damping + * Calculates linear frequency and damping ratio from stiffness and damping * @param frequency The output frequency * @param ratio The output damping ratio * @param stiffness The joint stiffness @@ -379,7 +379,29 @@ public: * @param bodyA The bodyA of the joint * @param bodyB The bodyB of the joint **/ - static void b2AngularFrequency(float& frequency, float& ratio, float stiffness, float damping, b2Body* bodyA, b2Body* bodyB); + static void computeLinearFrequency(float &frequency, float &ratio, float stiffness, float damping, b2Body *bodyA, b2Body *bodyB); + + /** + * Calculates the stiffness and damping, given the angular frequency, and damping ratio. + * @param stiffness The output stiffness + * @param damping The output damping + * @param frequency The joint angular frequency + * @param dampingRatio The joint damping ratio + * @param bodyA The bodyA of the joint + * @param bodyB The bodyB of the joint + **/ + static void computeAngularStiffness(float &stiffness, float &damping, float frequency, float dampingRatio, b2Body *bodyA, b2Body *bodyB); + + /** + * Calculates angular frequency and damping ratio from stiffness and damping + * @param frequency The output frequency + * @param ratio The output damping ratio + * @param stiffness The joint stiffness + * @param damping The joint damping + * @param bodyA The bodyA of the joint + * @param bodyB The bodyB of the joint + **/ + static void computeAngularFrequency(float &frequency, float &ratio, float stiffness, float damping, b2Body *bodyA, b2Body *bodyB); private: diff --git a/src/modules/physics/box2d/WeldJoint.cpp b/src/modules/physics/box2d/WeldJoint.cpp index 222997da1..26ebc7474 100644 --- a/src/modules/physics/box2d/WeldJoint.cpp +++ b/src/modules/physics/box2d/WeldJoint.cpp @@ -66,34 +66,6 @@ void WeldJoint::init(b2WeldJointDef &def, Body *body1, Body *body2, float xA, fl def.collideConnected = collideConnected; } -void WeldJoint::setFrequency(float hz) -{ - float stiffness, damping; - b2LinearStiffness(stiffness, damping, hz, getDampingRatio(), joint->GetBodyA(), joint->GetBodyB()); - joint->SetStiffness(stiffness); -} - -float WeldJoint::getFrequency() const -{ - float frequency, ratio; - Physics::b2LinearFrequency(frequency, ratio, joint->GetStiffness(), joint->GetDamping(), joint->GetBodyA(), joint->GetBodyB()); - return frequency; -} - -void WeldJoint::setDampingRatio(float ratio) -{ - float stiffness, damping; - b2LinearStiffness(stiffness, damping, getFrequency(), ratio, joint->GetBodyA(), joint->GetBodyB()); - joint->SetDamping(damping); -} - -float WeldJoint::getDampingRatio() const -{ - float frequency, ratio; - Physics::b2LinearFrequency(frequency, ratio, joint->GetStiffness(), joint->GetDamping(), joint->GetBodyA(), joint->GetBodyB()); - return ratio; -} - void WeldJoint::setStiffness(float k) { joint->SetStiffness(k); diff --git a/src/modules/physics/box2d/WeldJoint.h b/src/modules/physics/box2d/WeldJoint.h index e159b48ee..22816e55f 100644 --- a/src/modules/physics/box2d/WeldJoint.h +++ b/src/modules/physics/box2d/WeldJoint.h @@ -49,26 +49,6 @@ public: virtual ~WeldJoint(); - /** - * Sets the response speed. Independent of mass - **/ - void setFrequency(float hz); - - /** - * Gets the response speed. Independent of mass - **/ - float getFrequency() const; - - /** - * Set the spring damping ratio. Independent of mass - **/ - void setDampingRatio(float ratio); - - /** - * Get the spring damping ratio. Independent of mass - **/ - float getDampingRatio() const; - /** * Sets the response speed. Dependent of mass **/ diff --git a/src/modules/physics/box2d/WheelJoint.cpp b/src/modules/physics/box2d/WheelJoint.cpp index cb56e4041..621138746 100644 --- a/src/modules/physics/box2d/WheelJoint.cpp +++ b/src/modules/physics/box2d/WheelJoint.cpp @@ -95,34 +95,6 @@ float WheelJoint::getMotorTorque(float inv_dt) const return Physics::scaleUp(Physics::scaleUp(joint->GetMotorTorque(inv_dt))); } -void WheelJoint::setFrequency(float hz) -{ - float stiffness, damping; - b2AngularStiffness(stiffness, damping, hz, getDampingRatio(), joint->GetBodyA(), joint->GetBodyB()); - joint->SetStiffness(stiffness); -} - -float WheelJoint::getFrequency() const -{ - float frequency, ratio; - Physics::b2AngularFrequency(frequency, ratio, joint->GetStiffness(), joint->GetDamping(), joint->GetBodyA(), joint->GetBodyB()); - return frequency; -} - -void WheelJoint::setDampingRatio(float ratio) -{ - float stiffness, damping; - b2AngularStiffness(stiffness, damping, getFrequency(), ratio, joint->GetBodyA(), joint->GetBodyB()); - joint->SetDamping(damping); -} - -float WheelJoint::getDampingRatio() const -{ - float frequency, ratio; - Physics::b2AngularFrequency(frequency, ratio, joint->GetStiffness(), joint->GetDamping(), joint->GetBodyA(), joint->GetBodyB()); - return ratio; -} - void WheelJoint::setStiffness(float k) { joint->SetStiffness(k); diff --git a/src/modules/physics/box2d/WheelJoint.h b/src/modules/physics/box2d/WheelJoint.h index 591398520..c495d6542 100644 --- a/src/modules/physics/box2d/WheelJoint.h +++ b/src/modules/physics/box2d/WheelJoint.h @@ -95,26 +95,6 @@ public: **/ float getMotorTorque(float inv_dt) const; - /** - * Sets the response speed. Independent of mass - **/ - void setFrequency(float hz); - - /** - * Gets the response speed. Independent of mass - **/ - float getFrequency() const; - - /** - * Set the spring damping ratio. Independent of mass - **/ - void setDampingRatio(float ratio); - - /** - * Get the spring damping ratio. Independent of mass - **/ - float getDampingRatio() const; - /** * Sets the response speed. Dependent of mass **/ diff --git a/src/modules/physics/box2d/wrap_DistanceJoint.cpp b/src/modules/physics/box2d/wrap_DistanceJoint.cpp index 80734ab73..4e55881d0 100644 --- a/src/modules/physics/box2d/wrap_DistanceJoint.cpp +++ b/src/modules/physics/box2d/wrap_DistanceJoint.cpp @@ -50,36 +50,6 @@ int w_DistanceJoint_getLength(lua_State *L) return 1; } -int w_DistanceJoint_setFrequency(lua_State *L) -{ - DistanceJoint *t = luax_checkdistancejoint(L, 1); - float arg1 = (float)luaL_checknumber(L, 2); - t->setFrequency(arg1); - return 0; -} - -int w_DistanceJoint_getFrequency(lua_State *L) -{ - DistanceJoint *t = luax_checkdistancejoint(L, 1); - lua_pushnumber(L, t->getFrequency()); - return 1; -} - -int w_DistanceJoint_setDampingRatio(lua_State *L) -{ - DistanceJoint *t = luax_checkdistancejoint(L, 1); - float arg1 = (float)luaL_checknumber(L, 2); - t->setDampingRatio(arg1); - return 0; -} - -int w_DistanceJoint_getDampingRatio(lua_State *L) -{ - DistanceJoint *t = luax_checkdistancejoint(L, 1); - lua_pushnumber(L, t->getDampingRatio()); - return 1; -} - int w_DistanceJoint_setStiffness(lua_State *L) { DistanceJoint *t = luax_checkdistancejoint(L, 1); @@ -114,10 +84,6 @@ static const luaL_Reg w_DistanceJoint_functions[] = { { "setLength", w_DistanceJoint_setLength }, { "getLength", w_DistanceJoint_getLength }, - { "setFrequency", w_DistanceJoint_setFrequency }, - { "getFrequency", w_DistanceJoint_getFrequency }, - { "setDampingRatio", w_DistanceJoint_setDampingRatio }, - { "getDampingRatio", w_DistanceJoint_getDampingRatio }, { "setStiffness", w_DistanceJoint_setStiffness }, { "getStiffness", w_DistanceJoint_getStiffness }, { "setDamping", w_DistanceJoint_setDamping }, diff --git a/src/modules/physics/box2d/wrap_MouseJoint.cpp b/src/modules/physics/box2d/wrap_MouseJoint.cpp index 697c85f78..7258915e0 100644 --- a/src/modules/physics/box2d/wrap_MouseJoint.cpp +++ b/src/modules/physics/box2d/wrap_MouseJoint.cpp @@ -66,36 +66,6 @@ int w_MouseJoint_getMaxForce(lua_State *L) return 1; } -int w_MouseJoint_setFrequency(lua_State *L) -{ - MouseJoint *t = luax_checkmousejoint(L, 1); - float arg1 = (float)luaL_checknumber(L, 2); - luax_catchexcept(L, [&]() { t->setFrequency(arg1); }); - return 0; -} - -int w_MouseJoint_getFrequency(lua_State *L) -{ - MouseJoint *t = luax_checkmousejoint(L, 1); - lua_pushnumber(L, t->getFrequency()); - return 1; -} - -int w_MouseJoint_setDampingRatio(lua_State *L) -{ - MouseJoint *t = luax_checkmousejoint(L, 1); - float arg1 = (float)luaL_checknumber(L, 2); - t->setDampingRatio(arg1); - return 0; -} - -int w_MouseJoint_getDampingRatio(lua_State *L) -{ - MouseJoint *t = luax_checkmousejoint(L, 1); - lua_pushnumber(L, t->getDampingRatio()); - return 1; -} - int w_MouseJoint_setStiffness(lua_State *L) { MouseJoint *t = luax_checkmousejoint(L, 1); @@ -132,10 +102,6 @@ static const luaL_Reg w_MouseJoint_functions[] = { "getTarget", w_MouseJoint_getTarget }, { "setMaxForce", w_MouseJoint_setMaxForce }, { "getMaxForce", w_MouseJoint_getMaxForce }, - { "setFrequency", w_MouseJoint_setFrequency }, - { "getFrequency", w_MouseJoint_getFrequency }, - { "setDampingRatio", w_MouseJoint_setDampingRatio }, - { "getDampingRatio", w_MouseJoint_getDampingRatio }, { "setStiffness", w_MouseJoint_setStiffness }, { "getStiffness", w_MouseJoint_getStiffness }, { "setDamping", w_MouseJoint_setDamping }, diff --git a/src/modules/physics/box2d/wrap_Physics.cpp b/src/modules/physics/box2d/wrap_Physics.cpp index c0a5d0961..292f883f7 100644 --- a/src/modules/physics/box2d/wrap_Physics.cpp +++ b/src/modules/physics/box2d/wrap_Physics.cpp @@ -477,12 +477,97 @@ int w_setMeter(lua_State *L) return 0; } + int w_getMeter(lua_State *L) { lua_pushinteger(L, Physics::getMeter()); return 1; } +int w_computeLinearStiffness(lua_State *L) +{ + float frequency = (float)luaL_checknumber(L, 1); + float dampingRatio = (float)luaL_checknumber(L, 2); + Body *body1 = luax_checkbody(L, 3); + b2Body *other = 0; + + if (lua_isnoneornil(L, 4)) + other = body1->getWorld()->getGroundBody(); + else + other = luax_checkbody(L, 4)->body; + + float stiffness, damping; + Physics::computeLinearStiffness(stiffness, damping, frequency, dampingRatio, body1->body, other); + + lua_pushnumber(L, stiffness); + lua_pushnumber(L, damping); + + return 2; +} + +int w_computeLinearFrequency(lua_State *L) +{ + float stiffness = (float)luaL_checknumber(L, 1); + float damping = (float)luaL_checknumber(L, 2); + Body *body1 = luax_checkbody(L, 3); + b2Body *other = 0; + + if (lua_isnoneornil(L, 4)) + other = body1->getWorld()->getGroundBody(); + else + other = luax_checkbody(L, 4)->body; + + float frequency, dampingRatio; + Physics::computeLinearFrequency(frequency, dampingRatio, stiffness, damping, body1->body, other); + + lua_pushnumber(L, frequency); + lua_pushnumber(L, dampingRatio); + + return 2; +} + +int w_computeAngularStiffness(lua_State *L) +{ + float frequency = (float)luaL_checknumber(L, 1); + float dampingRatio = (float)luaL_checknumber(L, 2); + Body *body1 = luax_checkbody(L, 3); + b2Body *other = 0; + + if (lua_isnoneornil(L, 4)) + other = body1->getWorld()->getGroundBody(); + else + other = luax_checkbody(L, 4)->body; + + float stiffness, damping; + Physics::computeAngularStiffness(stiffness, damping, frequency, dampingRatio, body1->body, other); + + lua_pushnumber(L, stiffness); + lua_pushnumber(L, damping); + + return 2; +} + +int w_computeAngularFrequency(lua_State *L) +{ + float stiffness = (float)luaL_checknumber(L, 1); + float damping = (float)luaL_checknumber(L, 2); + Body *body1 = luax_checkbody(L, 3); + b2Body *other = 0; + + if (lua_isnoneornil(L, 4)) + other = body1->getWorld()->getGroundBody(); + else + other = luax_checkbody(L, 4)->body; + + float frequency, dampingRatio; + Physics::computeAngularFrequency(frequency, dampingRatio, stiffness, damping, body1->body, other); + + lua_pushnumber(L, frequency); + lua_pushnumber(L, dampingRatio); + + return 2; +} + // List of functions to wrap. static const luaL_Reg functions[] = { @@ -508,6 +593,10 @@ static const luaL_Reg functions[] = { "getDistance", w_getDistance }, { "getMeter", w_getMeter }, { "setMeter", w_setMeter }, + { "computeLinearStiffness", w_computeLinearStiffness }, + { "computeLinearFrequency", w_computeLinearFrequency }, + { "computeAngularStiffness", w_computeAngularStiffness }, + { "computeAngularFrequency", w_computeAngularFrequency }, { 0, 0 }, }; diff --git a/src/modules/physics/box2d/wrap_WeldJoint.cpp b/src/modules/physics/box2d/wrap_WeldJoint.cpp index 57251abd0..a5a9c1dac 100644 --- a/src/modules/physics/box2d/wrap_WeldJoint.cpp +++ b/src/modules/physics/box2d/wrap_WeldJoint.cpp @@ -35,36 +35,6 @@ WeldJoint *luax_checkweldjoint(lua_State *L, int idx) return j; } -int w_WeldJoint_setFrequency(lua_State *L) -{ - WeldJoint *t = luax_checkweldjoint(L, 1); - float arg1 = (float)luaL_checknumber(L, 2); - t->setFrequency(arg1); - return 0; -} - -int w_WeldJoint_getFrequency(lua_State *L) -{ - WeldJoint *t = luax_checkweldjoint(L, 1); - lua_pushnumber(L, t->getFrequency()); - return 1; -} - -int w_WeldJoint_setDampingRatio(lua_State *L) -{ - WeldJoint *t = luax_checkweldjoint(L, 1); - float arg1 = (float)luaL_checknumber(L, 2); - t->setDampingRatio(arg1); - return 0; -} - -int w_WeldJoint_getDampingRatio(lua_State *L) -{ - WeldJoint *t = luax_checkweldjoint(L, 1); - lua_pushnumber(L, t->getDampingRatio()); - return 1; -} - int w_WeldJoint_setStiffness(lua_State *L) { WeldJoint *t = luax_checkweldjoint(L, 1); @@ -104,10 +74,6 @@ int w_WeldJoint_getReferenceAngle(lua_State *L) static const luaL_Reg w_WeldJoint_functions[] = { - { "setFrequency", w_WeldJoint_setFrequency }, - { "getFrequency", w_WeldJoint_getFrequency }, - { "setDampingRatio", w_WeldJoint_setDampingRatio }, - { "getDampingRatio", w_WeldJoint_getDampingRatio }, { "setStiffness", w_WeldJoint_setStiffness }, { "getStiffness", w_WeldJoint_getStiffness }, { "setDamping", w_WeldJoint_setDamping }, diff --git a/src/modules/physics/box2d/wrap_WheelJoint.cpp b/src/modules/physics/box2d/wrap_WheelJoint.cpp index 21745047b..1b49b31d0 100644 --- a/src/modules/physics/box2d/wrap_WheelJoint.cpp +++ b/src/modules/physics/box2d/wrap_WheelJoint.cpp @@ -102,36 +102,6 @@ int w_WheelJoint_getMotorTorque(lua_State *L) return 1; } -int w_WheelJoint_setFrequency(lua_State *L) -{ - WheelJoint *t = luax_checkwheeljoint(L, 1); - float arg1 = (float)luaL_checknumber(L, 2); - t->setFrequency(arg1); - return 0; -} - -int w_WheelJoint_getFrequency(lua_State *L) -{ - WheelJoint *t = luax_checkwheeljoint(L, 1); - lua_pushnumber(L, t->getFrequency()); - return 1; -} - -int w_WheelJoint_setDampingRatio(lua_State *L) -{ - WheelJoint *t = luax_checkwheeljoint(L, 1); - float arg1 = (float)luaL_checknumber(L, 2); - t->setDampingRatio(arg1); - return 0; -} - -int w_WheelJoint_getDampingRatio(lua_State *L) -{ - WheelJoint *t = luax_checkwheeljoint(L, 1); - lua_pushnumber(L, t->getDampingRatio()); - return 1; -} - int w_WheelJoint_setStiffness(lua_State *L) { WheelJoint *t = luax_checkwheeljoint(L, 1); @@ -180,18 +150,10 @@ static const luaL_Reg w_WheelJoint_functions[] = { "setMaxMotorTorque", w_WheelJoint_setMaxMotorTorque }, { "getMaxMotorTorque", w_WheelJoint_getMaxMotorTorque }, { "getMotorTorque", w_WheelJoint_getMotorTorque }, - { "setSpringFrequency", w_WheelJoint_setFrequency }, - { "getSpringFrequency", w_WheelJoint_getFrequency }, - { "setSpringDampingRatio", w_WheelJoint_setDampingRatio }, - { "getSpringDampingRatio", w_WheelJoint_getDampingRatio }, { "setSpringStiffness", w_WheelJoint_setStiffness }, { "getSpringStiffness", w_WheelJoint_getStiffness }, { "setSpringDamping", w_WheelJoint_setDamping }, { "getSpringDamping", w_WheelJoint_getDamping }, - { "setFrequency", w_WheelJoint_setFrequency }, - { "getFrequency", w_WheelJoint_getFrequency }, - { "setDampingRatio", w_WheelJoint_setDampingRatio }, - { "getDampingRatio", w_WheelJoint_getDampingRatio }, { "setStiffness", w_WheelJoint_setStiffness }, { "getStiffness", w_WheelJoint_getStiffness }, { "setDamping", w_WheelJoint_setDamping }, diff --git a/src/modules/sensor/Sensor.cpp b/src/modules/sensor/Sensor.cpp new file mode 100644 index 000000000..f6a56ac95 --- /dev/null +++ b/src/modules/sensor/Sensor.cpp @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2006-2022 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +// LOVE +#include "Sensor.h" + +namespace love +{ +namespace sensor +{ + +STRINGMAP_CLASS_BEGIN(Sensor, Sensor::SensorType, Sensor::SENSOR_MAX_ENUM, sensorType) +{ + { "accelerometer", Sensor::SENSOR_ACCELEROMETER }, + { "gyroscope", Sensor::SENSOR_GYROSCOPE }, +} +STRINGMAP_CLASS_END(Sensor, Sensor::SensorType, Sensor::SENSOR_MAX_ENUM, sensorType) + +} // sensor +} // love diff --git a/src/modules/sensor/Sensor.h b/src/modules/sensor/Sensor.h new file mode 100644 index 000000000..5461e86c9 --- /dev/null +++ b/src/modules/sensor/Sensor.h @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2006-2022 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#ifndef LOVE_SENSOR_H +#define LOVE_SENSOR_H + + // LOVE +#include "common/Module.h" +#include "common/StringMap.h" + +namespace love +{ +namespace sensor +{ + +class Sensor: public Module +{ +public: + + enum SensorType + { + SENSOR_ACCELEROMETER, + SENSOR_GYROSCOPE, + SENSOR_MAX_ENUM + }; + + virtual ~Sensor() {} + + // Implements Module. + ModuleType getModuleType() const override { return M_SENSOR; } + + /** + * Check the availability of the sensor. + **/ + virtual bool hasSensor(SensorType type) = 0; + + /** + * Check if the sensor is enabled. + **/ + virtual bool isEnabled(SensorType type) = 0; + + /** + * Enable or disable a sensor. + **/ + virtual void setEnabled(SensorType type, bool enabled) = 0; + + /** + * Get data from sensor. + **/ + virtual std::vector getData(SensorType type) = 0; + + /** + * Get backend-dependent handle of sensor. + **/ + virtual std::vector getHandles() = 0; + + virtual const char *getSensorName(SensorType type) = 0; + + STRINGMAP_CLASS_DECLARE(SensorType); + +}; // Sensor + +} // sensor +} // love + +#endif diff --git a/src/modules/sensor/sdl/Sensor.cpp b/src/modules/sensor/sdl/Sensor.cpp new file mode 100644 index 000000000..1c3406230 --- /dev/null +++ b/src/modules/sensor/sdl/Sensor.cpp @@ -0,0 +1,174 @@ +/** + * Copyright (c) 2006-2022 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +// LOVE +#include "Sensor.h" + +// SDL +#include +#include + +namespace love +{ +namespace sensor +{ +namespace sdl +{ + +Sensor::Sensor() +: sensors() +{ + if (SDL_InitSubSystem(SDL_INIT_SENSOR) < 0) + throw love::Exception("Could not initialize SDL sensor subsystem (%s)", SDL_GetError()); +} + +Sensor::~Sensor() +{ + SDL_QuitSubSystem(SDL_INIT_SENSOR); +} + +const char *Sensor::getName() const +{ + return "love.sensor.sdl"; +} + +bool Sensor::hasSensor(SensorType type) +{ + for (int i = 0; i < SDL_NumSensors(); i++) + { + if (convert(SDL_SensorGetDeviceType(i)) == type) + return true; + } + + return false; +} + +bool Sensor::isEnabled(SensorType type) +{ + return sensors[type]; // nullptr is default +} + +void Sensor::setEnabled(SensorType type, bool enable) +{ + if (sensors[type] && !enable) + { + SDL_SensorClose(sensors[type]); + sensors[type] = nullptr; + } + else if (sensors[type] == nullptr && enable) + { + for (int i = 0; i < SDL_NumSensors(); i++) + { + if (convert(SDL_SensorGetDeviceType(i)) == type) + { + SDL_Sensor *sensorHandle = SDL_SensorOpen(i); + + if (sensorHandle == nullptr) + { + const char *name = nullptr; + getConstant(type, name); + + throw love::Exception("Could not open \"%s\" SDL sensor (%s)", name, SDL_GetError()); + } + + sensors[type] = sensorHandle; + } + } + } +} + +std::vector Sensor::getData(SensorType type) +{ + if (sensors[type] == nullptr) + { + const char *name = nullptr; + getConstant(type, name); + + throw love::Exception("\"%s\" sensor is not enabled", name); + } + + std::vector values(3); + + if (SDL_SensorGetData(sensors[type], values.data(), (int) values.size()) != 0) + { + const char *name = nullptr; + getConstant(type, name); + + throw love::Exception("Could not get \"%s\" SDL sensor data (%s)", name, SDL_GetError()); + } + + return values; +} + +std::vector Sensor::getHandles() +{ + std::vector nativeSensor; + + for (const std::pair &data: sensors) + { + if (data.second) + nativeSensor.push_back(data.second); + } + + return nativeSensor; +} + +const char *Sensor::getSensorName(SensorType type) +{ + if (sensors[type] == nullptr) + { + const char *name = nullptr; + getConstant(type, name); + + throw love::Exception("\"%s\" sensor is not enabled", name); + } + + return SDL_SensorGetName(sensors[type]); +} + +Sensor::SensorType Sensor::convert(SDL_SensorType type) +{ + switch (type) + { + case SDL_SENSOR_ACCEL: + return SENSOR_ACCELEROMETER; + case SDL_SENSOR_GYRO: + return SENSOR_GYROSCOPE; + default: + return SENSOR_MAX_ENUM; + } +} + +SDL_SensorType Sensor::convert(Sensor::SensorType type) +{ + switch (type) + { + case SENSOR_ACCELEROMETER: + return SDL_SENSOR_ACCEL; + case SENSOR_GYROSCOPE: + return SDL_SENSOR_GYRO; + default: + return SDL_SENSOR_UNKNOWN; + } +} + +} +} +} diff --git a/src/modules/sensor/sdl/Sensor.h b/src/modules/sensor/sdl/Sensor.h new file mode 100644 index 000000000..609bd376b --- /dev/null +++ b/src/modules/sensor/sdl/Sensor.h @@ -0,0 +1,68 @@ +/** + * Copyright (c) 2006-2022 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#ifndef LOVE_SENSOR_SDL_SENSOR_H +#define LOVE_SENSOR_SDL_SENSOR_H + +// LOVE +#include "sensor/Sensor.h" + +// SDL +#include + +// std +#include + +namespace love +{ +namespace sensor +{ +namespace sdl +{ + +class Sensor : public love::sensor::Sensor +{ +public: + Sensor(); + ~Sensor() override; + + // Implements Module. + const char *getName() const override; + + bool hasSensor(SensorType type) override; + bool isEnabled(SensorType type) override; + void setEnabled(SensorType type, bool enable) override; + std::vector getData(SensorType type) override; + std::vector getHandles() override; + const char *getSensorName(SensorType type) override; + + static SensorType convert(SDL_SensorType type); + static SDL_SensorType convert(SensorType type); + +private: + std::map sensors; + +}; // Sensor + +} // sdl +} // sensor +} // love + +#endif diff --git a/src/modules/sensor/wrap_Sensor.cpp b/src/modules/sensor/wrap_Sensor.cpp new file mode 100644 index 000000000..cfaf098db --- /dev/null +++ b/src/modules/sensor/wrap_Sensor.cpp @@ -0,0 +1,120 @@ +/** + * Copyright (c) 2006-2022 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + + // LOVE +#include "wrap_Sensor.h" +#include "sdl/Sensor.h" + +namespace love +{ +namespace sensor +{ + +#define instance() (Module::getInstance(Module::M_SENSOR)) + +inline Sensor::SensorType luax_checksensortype(lua_State *L, int i) +{ + const char *sensorType = luaL_checkstring(L, i); + Sensor::SensorType type = Sensor::SENSOR_MAX_ENUM; + + if (!Sensor::getConstant(sensorType, type)) + luax_enumerror(L, "sensor mode", Sensor::getConstants(type), sensorType); + + return type; +} + +static int w_hasSensor(lua_State *L) +{ + Sensor::SensorType type = luax_checksensortype(L, 1); + + lua_pushboolean(L, instance()->hasSensor(type)); + return 1; +} + +static int w_isEnabled(lua_State *L) +{ + Sensor::SensorType type = luax_checksensortype(L, 1); + + lua_pushboolean(L, instance()->isEnabled(type)); + return 1; +} + +static int w_setEnabled(lua_State *L) +{ + Sensor::SensorType type = luax_checksensortype(L, 1); + bool enabled = luax_checkboolean(L, 2); + + luax_catchexcept(L, [&](){ instance()->setEnabled(type, enabled); }); + return 0; +} + +static int w_getData(lua_State *L) +{ + Sensor::SensorType type = luax_checksensortype(L, 1); + + std::vector data; + luax_catchexcept(L, [&](){ data = instance()->getData(type); }); + + for (float f: data) + lua_pushnumber(L, f); + + return (int) data.size(); +} + +static int w_getName(lua_State *L) +{ + Sensor::SensorType type = luax_checksensortype(L, 1); + const char *name = nullptr; + + luax_catchexcept(L, [&](){ name = instance()->getSensorName(type); }); + lua_pushstring(L, name); + return 1; +} + +static const luaL_Reg functions[] = +{ + { "hasSensor", w_hasSensor }, + { "isEnabled", w_isEnabled }, + { "setEnabled", w_setEnabled }, + { "getData", w_getData }, + { "getName", w_getName }, + { nullptr, nullptr } +}; + +extern "C" int luaopen_love_sensor(lua_State * L) +{ + Sensor *instance = instance(); + if (instance == nullptr) + luax_catchexcept(L, [&]() { instance = new love::sensor::sdl::Sensor(); }); + else + instance->retain(); + + WrappedModule w; + w.module = instance; + w.name = "sensor"; + w.type = &Module::type; + w.functions = functions; + w.types = nullptr; + + return luax_register_module(L, w); +} + +} // sensor +} // love diff --git a/src/modules/sensor/wrap_Sensor.h b/src/modules/sensor/wrap_Sensor.h new file mode 100644 index 000000000..05d9f49d0 --- /dev/null +++ b/src/modules/sensor/wrap_Sensor.h @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2006-2022 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#ifndef LOVE_WRAP_SENSOR_H +#define LOVE_WRAP_SENSOR_H + + // LOVE +#include "common/runtime.h" + +namespace love +{ +namespace sensor +{ + +extern "C" LOVE_EXPORT int luaopen_love_sensor(lua_State *L); + +} // sensor +} // love + +#endif diff --git a/src/modules/window/sdl/Window.cpp b/src/modules/window/sdl/Window.cpp index 41f10ab3e..01f44dd76 100644 --- a/src/modules/window/sdl/Window.cpp +++ b/src/modules/window/sdl/Window.cpp @@ -46,6 +46,10 @@ // SDL #include +#ifdef LOVE_GRAPHICS_VULKAN +#include +#endif + #if defined(LOVE_WINDOWS) #include #include @@ -91,7 +95,6 @@ Window::Window() , metalView(nullptr) #endif , displayedWindowError(false) - , hasSDL203orEarlier(false) , contextAttribs() { if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) @@ -99,10 +102,6 @@ Window::Window() // Make sure the screensaver doesn't activate by default. setDisplaySleepEnabled(false); - - SDL_version version = {}; - SDL_GetVersion(&version); - hasSDL203orEarlier = (version.major == 2 && version.minor == 0 && version.patch <= 3); } Window::~Window() @@ -140,16 +139,6 @@ void Window::setGLFramebufferAttributes(bool sRGB) SDL_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, sRGB ? 1 : 0); - const char *driver = SDL_GetCurrentVideoDriver(); - if (driver && strstr(driver, "x11") == driver) - { - // Always disable the sRGB flag when GLX is used with older SDL versions, - // because of this bug: https://bugzilla.libsdl.org/show_bug.cgi?id=2897 - // In practice GLX will always give an sRGB-capable framebuffer anyway. - if (hasSDL203orEarlier) - SDL_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, 0); - } - #if defined(LOVE_WINDOWS) // Avoid the Microsoft OpenGL 1.1 software renderer on Windows. Apparently // older Intel drivers like to use it as a fallback when requesting some @@ -250,14 +239,6 @@ std::vector Window::getContextAttribsList() const if (curdriver && strstr(curdriver, glesdriver) == curdriver) { preferGLES = true; - - // Prior to SDL 2.0.4, backends that use OpenGL ES didn't properly - // ask for a sRGB framebuffer when requested by SDL_GL_SetAttribute. - // This doesn't account for windowing backends that sometimes use - // EGL, e.g. the X11 and windows SDL backends. - if (hasSDL203orEarlier) - graphics::setGammaCorrect(false); - break; } } @@ -588,12 +569,8 @@ bool Window::setWindow(int width, int height, WindowSettings *settings) if (!f.fullscreen) SDL_SetWindowSize(window, width, height); - // On linux systems 2.0.5+ might not be available... - // TODO: require at least 2.0.5? -#if SDL_VERSION_ATLEAST(2, 0, 5) if (this->settings.resizable != f.resizable) SDL_SetWindowResizable(window, f.resizable ? SDL_TRUE : SDL_FALSE); -#endif if (this->settings.borderless != f.borderless) SDL_SetWindowBordered(window, f.borderless ? SDL_FALSE : SDL_TRUE); @@ -688,11 +665,16 @@ bool Window::onSizeChanged(int width, int height) windowWidth = width; windowHeight = height; + // TODO: Use SDL_GetWindowSizeInPixels here when supported. if (glcontext != nullptr) SDL_GL_GetDrawableSize(window, &pixelWidth, &pixelHeight); #ifdef LOVE_GRAPHICS_METAL else if (metalView != nullptr) SDL_Metal_GetDrawableSize(window, &pixelWidth, &pixelHeight); +#endif +#ifdef LOVE_GRAPHICS_VULKAN + else if (windowRenderer == graphics::RENDERER_VULKAN) + SDL_Vulkan_GetDrawableSize(window, &pixelWidth, &pixelHeight); #endif else { @@ -720,12 +702,17 @@ void Window::updateSettings(const WindowSettings &newsettings, bool updateGraphi pixelWidth = windowWidth; pixelHeight = windowHeight; + // TODO: Use SDL_GetWindowSizeInPixels here when supported. if ((wflags & SDL_WINDOW_OPENGL) != 0) SDL_GL_GetDrawableSize(window, &pixelWidth, &pixelHeight); #ifdef LOVE_GRAPHICS_METAL else if ((wflags & SDL_WINDOW_METAL) != 0) SDL_Metal_GetDrawableSize(window, &pixelWidth, &pixelHeight); #endif +#ifdef LOVE_GRAPHICS_VULKAN + else if ((wflags & SDL_WINDOW_VULKAN) != 0) + SDL_Vulkan_GetDrawableSize(window, &pixelWidth, &pixelHeight); +#endif if ((wflags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) { @@ -909,9 +896,6 @@ const char *Window::getDisplayName(int displayindex) const Window::DisplayOrientation Window::getDisplayOrientation(int displayindex) const { - // TODO: We can expose this everywhere, we just need to watch out for the - // SDL binary being older than the headers on Linux. -#if SDL_VERSION_ATLEAST(2, 0, 9) && (defined(LOVE_ANDROID) || !defined(LOVE_LINUX)) switch (SDL_GetDisplayOrientation(displayindex)) { case SDL_ORIENTATION_UNKNOWN: return ORIENTATION_UNKNOWN; @@ -920,9 +904,6 @@ Window::DisplayOrientation Window::getDisplayOrientation(int displayindex) const case SDL_ORIENTATION_PORTRAIT: return ORIENTATION_PORTRAIT; case SDL_ORIENTATION_PORTRAIT_FLIPPED: return ORIENTATION_PORTRAIT_FLIPPED; } -#else - LOVE_UNUSED(displayindex); -#endif return ORIENTATION_UNKNOWN; } @@ -1119,6 +1100,7 @@ void Window::setVSync(int vsync) } #ifdef LOVE_GRAPHICS_VULKAN + // TODO: this doesn't update the swap-chain, but it should. love::graphics::vulkan::Vulkan::setVsync(vsync); #endif @@ -1148,6 +1130,11 @@ int Window::getVSync() const } #endif +#ifdef LOVE_GRAPHICS_VULKAN + if (windowRenderer == love::graphics::RENDERER_VULKAN) + return love::graphics::vulkan::Vulkan::getVsync(); +#endif + return 0; } diff --git a/src/modules/window/sdl/Window.h b/src/modules/window/sdl/Window.h index 902b19838..fac966ce4 100644 --- a/src/modules/window/sdl/Window.h +++ b/src/modules/window/sdl/Window.h @@ -175,7 +175,6 @@ private: graphics::Renderer windowRenderer = graphics::RENDERER_NONE; bool displayedWindowError; - bool hasSDL203orEarlier; ContextAttribs contextAttribs; StrongRef graphics;