diff --git a/.hgtags b/.hgtags index c4cce6364..67d680e02 100644 --- a/.hgtags +++ b/.hgtags @@ -9,3 +9,4 @@ e0f98d53debb62347c6433ca0534a0f77f15f76f 0.8.0 8b113c345e97e7bb7e963e5d67451abdfb05cfde 0.9.1 a5e405cdf14d030b71d09a105086797942ae91a9 0.9.2 14717f0fb5d96d380c10fe6f41b74b7652c7d836 0.10.0 +3cb3559eebb89803c0b7fa83d51d8e48a2b20b7a 0.10.1 diff --git a/changes.txt b/changes.txt index c45db9982..d686553da 100644 --- a/changes.txt +++ b/changes.txt @@ -1,5 +1,39 @@ +LOVE 0.10.1 [Super Toast] +------------------------- + +Released: 2016-02-14 + + * Added a new love.conf flag t.externalstorage, which determines whether files are saved in internal or external storage on Android devices. + * Added a new variant of love.graphics.arc which can draw different types of arcs ("pie", "open", or "closed"). + * Added "lighten" and "darken" BlendModes. They can only be used with the "premultiplied" BlendAlphaMode. + * Added the "lighten" GraphicsFeature constant. + * Added the ability to avoid clearing specific Canvases when calling love.graphics.clear, if multiple Canvases are active at once via love.graphics.setCanvas. + * Added Text:getDimensions. + * Added optional "collideconnected" argument to love.physics.newMotorJoint. + + * Fixed a Lua error in the no-game screen if the window's height is too small. + * Fixed the default error handler to reset the mouse Cursor. + * Fixed love.filesystem functions crashing when called if liblove is used directly without calling love.filesystem.init. + * Fixed audio on Android to pause when the app is inactive, and resume when the app becomes active again. + * Fixed the Video decoding thread hanging after Video:seek or when a Video finishes. + * Fixed Video:isPlaying to always return false after it finishes playing. + * Fixed RandomGenerator:random crashing if a nil 'self' is used. + * Fixed loading BMFont files which have characters with 0 width or height (a space character, for example). + * Fixed love.graphics.newFont causing crashes if FileData is passed in. + * Fixed love.graphics.clear(colortable) causing crashes on OpenGL ES 2 systems when a Canvas is active. + * Fixed a driver bug on some Android devices which caused all objects to show up as black. + * Fixed a driver bug on Windows with AMD graphics cards where love.graphics.clear would not always work. + * Fixed Shader:sendColor incorrectly converting alpha values from sRGB to linear RGB when gamma-correct rendering is enabled. + * Fixed love.graphics.newMesh(vertices) double-converting colors from sRGB to linear RGB when gamma-correct rendering is enabled. + * Fixed love.graphics.new* crashing when there is no graphics context/window. + + * Updated the Windows executable to prefer the high-powered AMD graphics card on systems which have switchable Intel+AMD GPUs. + * Updated love.touch.getTouches to return the list of IDs in the relative order that the touches initially happened, instead of being in a random order. + * Updated the error messages caused by invalid or bad arguments to ImageData and SoundData methods to be more descriptive. + + LOVE 0.10.0 [Super Toast] --------------- +------------------------- Released: 2015-12-22 diff --git a/extra/nsis/game.ico b/extra/nsis/game.ico index 3a0103438..ecc5c0d3d 100644 Binary files a/extra/nsis/game.ico and b/extra/nsis/game.ico differ diff --git a/extra/nsis/left.bmp b/extra/nsis/left.bmp index 227e6a05f..91d5e3a30 100644 Binary files a/extra/nsis/left.bmp and b/extra/nsis/left.bmp differ diff --git a/extra/nsis/love.ico b/extra/nsis/love.ico index 73403aedb..b703c98b8 100644 Binary files a/extra/nsis/love.ico and b/extra/nsis/love.ico differ diff --git a/extra/nsis/top.bmp b/extra/nsis/top.bmp index 99d179aed..bec3e05fd 100644 Binary files a/extra/nsis/top.bmp and b/extra/nsis/top.bmp differ diff --git a/extra/windows/love.ico b/extra/windows/love.ico index 73403aedb..b703c98b8 100644 Binary files a/extra/windows/love.ico and b/extra/windows/love.ico differ diff --git a/platform/unix/application-x-love-game.svg b/platform/unix/application-x-love-game.svg index 19c62362b..a01da96f3 100644 --- a/platform/unix/application-x-love-game.svg +++ b/platform/unix/application-x-love-game.svg @@ -1,1024 +1,793 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + diff --git a/platform/unix/love.svg b/platform/unix/love.svg index 03267f0b6..552ad1781 100644 --- a/platform/unix/love.svg +++ b/platform/unix/love.svg @@ -1,1030 +1,962 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + width="141.73px" height="141.73px" viewBox="0 0 141.73 141.73" enable-background="new 0 0 141.73 141.73" xml:space="preserve"> - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + + + + + + + + + diff --git a/platform/xcode/Images.xcassets/Contents.json b/platform/xcode/Images.xcassets/Contents.json new file mode 100644 index 000000000..da4a164c9 --- /dev/null +++ b/platform/xcode/Images.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/platform/xcode/Images.xcassets/GameIcon.iconset/icon_128x128.png b/platform/xcode/Images.xcassets/GameIcon.iconset/icon_128x128.png new file mode 100644 index 000000000..6aaf64d0a Binary files /dev/null and b/platform/xcode/Images.xcassets/GameIcon.iconset/icon_128x128.png differ diff --git a/platform/xcode/Images.xcassets/GameIcon.iconset/icon_128x128@2x.png b/platform/xcode/Images.xcassets/GameIcon.iconset/icon_128x128@2x.png new file mode 100644 index 000000000..bfbccd330 Binary files /dev/null and b/platform/xcode/Images.xcassets/GameIcon.iconset/icon_128x128@2x.png differ diff --git a/platform/xcode/Images.xcassets/GameIcon.iconset/icon_16x16.png b/platform/xcode/Images.xcassets/GameIcon.iconset/icon_16x16.png new file mode 100644 index 000000000..81b7da9fb Binary files /dev/null and b/platform/xcode/Images.xcassets/GameIcon.iconset/icon_16x16.png differ diff --git a/platform/xcode/Images.xcassets/GameIcon.iconset/icon_16x16@2x.png b/platform/xcode/Images.xcassets/GameIcon.iconset/icon_16x16@2x.png new file mode 100644 index 000000000..e28e79f83 Binary files /dev/null and b/platform/xcode/Images.xcassets/GameIcon.iconset/icon_16x16@2x.png differ diff --git a/platform/xcode/Images.xcassets/GameIcon.iconset/icon_256x256.png b/platform/xcode/Images.xcassets/GameIcon.iconset/icon_256x256.png new file mode 100644 index 000000000..bfbccd330 Binary files /dev/null and b/platform/xcode/Images.xcassets/GameIcon.iconset/icon_256x256.png differ diff --git a/platform/xcode/Images.xcassets/GameIcon.iconset/icon_256x256@2x.png b/platform/xcode/Images.xcassets/GameIcon.iconset/icon_256x256@2x.png new file mode 100644 index 000000000..28054d712 Binary files /dev/null and b/platform/xcode/Images.xcassets/GameIcon.iconset/icon_256x256@2x.png differ diff --git a/platform/xcode/Images.xcassets/GameIcon.iconset/icon_32x32.png b/platform/xcode/Images.xcassets/GameIcon.iconset/icon_32x32.png new file mode 100644 index 000000000..e28e79f83 Binary files /dev/null and b/platform/xcode/Images.xcassets/GameIcon.iconset/icon_32x32.png differ diff --git a/platform/xcode/Images.xcassets/GameIcon.iconset/icon_32x32@2x.png b/platform/xcode/Images.xcassets/GameIcon.iconset/icon_32x32@2x.png new file mode 100644 index 000000000..75847d1ee Binary files /dev/null and b/platform/xcode/Images.xcassets/GameIcon.iconset/icon_32x32@2x.png differ diff --git a/platform/xcode/Images.xcassets/GameIcon.iconset/icon_512x512.png b/platform/xcode/Images.xcassets/GameIcon.iconset/icon_512x512.png new file mode 100644 index 000000000..28054d712 Binary files /dev/null and b/platform/xcode/Images.xcassets/GameIcon.iconset/icon_512x512.png differ diff --git a/platform/xcode/Images.xcassets/GameIcon.iconset/icon_512x512@2x.png b/platform/xcode/Images.xcassets/GameIcon.iconset/icon_512x512@2x.png new file mode 100644 index 000000000..08683780f Binary files /dev/null and b/platform/xcode/Images.xcassets/GameIcon.iconset/icon_512x512@2x.png differ diff --git a/platform/xcode/Images.xcassets/OS X AppIcon.appiconset/1024.png b/platform/xcode/Images.xcassets/OS X AppIcon.appiconset/1024.png new file mode 100644 index 000000000..6c52a9deb Binary files /dev/null and b/platform/xcode/Images.xcassets/OS X AppIcon.appiconset/1024.png differ diff --git a/platform/xcode/Images.xcassets/OS X AppIcon.appiconset/128.png b/platform/xcode/Images.xcassets/OS X AppIcon.appiconset/128.png new file mode 100644 index 000000000..82c74bcdb Binary files /dev/null and b/platform/xcode/Images.xcassets/OS X AppIcon.appiconset/128.png differ diff --git a/platform/xcode/Images.xcassets/OS X AppIcon.appiconset/16.png b/platform/xcode/Images.xcassets/OS X AppIcon.appiconset/16.png new file mode 100644 index 000000000..1b310d3f9 Binary files /dev/null and b/platform/xcode/Images.xcassets/OS X AppIcon.appiconset/16.png differ diff --git a/platform/xcode/Images.xcassets/OS X AppIcon.appiconset/256.png b/platform/xcode/Images.xcassets/OS X AppIcon.appiconset/256.png new file mode 100644 index 000000000..cd0212152 Binary files /dev/null and b/platform/xcode/Images.xcassets/OS X AppIcon.appiconset/256.png differ diff --git a/platform/xcode/Images.xcassets/OS X AppIcon.appiconset/32.png b/platform/xcode/Images.xcassets/OS X AppIcon.appiconset/32.png new file mode 100644 index 000000000..5c0890d21 Binary files /dev/null and b/platform/xcode/Images.xcassets/OS X AppIcon.appiconset/32.png differ diff --git a/platform/xcode/Images.xcassets/OS X AppIcon.appiconset/512.png b/platform/xcode/Images.xcassets/OS X AppIcon.appiconset/512.png new file mode 100644 index 000000000..17915d68a Binary files /dev/null and b/platform/xcode/Images.xcassets/OS X AppIcon.appiconset/512.png differ diff --git a/platform/xcode/Images.xcassets/OS X AppIcon.appiconset/64.png b/platform/xcode/Images.xcassets/OS X AppIcon.appiconset/64.png new file mode 100644 index 000000000..be300b35d Binary files /dev/null and b/platform/xcode/Images.xcassets/OS X AppIcon.appiconset/64.png differ diff --git a/platform/xcode/Images.xcassets/OS X AppIcon.appiconset/Contents.json b/platform/xcode/Images.xcassets/OS X AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..79b9cddac --- /dev/null +++ b/platform/xcode/Images.xcassets/OS X AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "16.png", + "scale" : "1x" + }, + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "32.png", + "scale" : "2x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "32.png", + "scale" : "1x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "64.png", + "scale" : "2x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "128.png", + "scale" : "1x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "256.png", + "scale" : "2x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "256.png", + "scale" : "1x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "512.png", + "scale" : "2x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "512.png", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "1024.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/Contents.json b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/Contents.json similarity index 68% rename from platform/xcode/ios/Images.xcassets/AppIcon.appiconset/Contents.json rename to platform/xcode/Images.xcassets/iOS AppIcon.appiconset/Contents.json index d58677a9b..f1a9e0970 100644 --- a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/Contents.json @@ -3,121 +3,121 @@ { "size" : "29x29", "idiom" : "iphone", - "filename" : "pig-29pt@1x.png", + "filename" : "icon-29pt@1x.png", "scale" : "1x" }, { "size" : "29x29", "idiom" : "iphone", - "filename" : "pig-29pt@2x.png", + "filename" : "icon-29pt@2x.png", "scale" : "2x" }, { "size" : "29x29", "idiom" : "iphone", - "filename" : "pig-29pt@3x.png", + "filename" : "icon-29pt@3x.png", "scale" : "3x" }, { "size" : "40x40", "idiom" : "iphone", - "filename" : "pig-40pt@2x.png", + "filename" : "icon-40pt@2x.png", "scale" : "2x" }, { "size" : "40x40", "idiom" : "iphone", - "filename" : "pig-40pt@3x.png", + "filename" : "icon-40pt@3x.png", "scale" : "3x" }, { "size" : "57x57", "idiom" : "iphone", - "filename" : "pig-57pt@1x.png", + "filename" : "icon-57pt@1x.png", "scale" : "1x" }, { "size" : "57x57", "idiom" : "iphone", - "filename" : "pig-57pt@2x.png", + "filename" : "icon-57pt@2x.png", "scale" : "2x" }, { "size" : "60x60", "idiom" : "iphone", - "filename" : "pig-60pt@2x.png", + "filename" : "icon-60pt@2x.png", "scale" : "2x" }, { "size" : "60x60", "idiom" : "iphone", - "filename" : "pig-60pt@3x.png", + "filename" : "icon-60pt@3x.png", "scale" : "3x" }, { "size" : "29x29", "idiom" : "ipad", - "filename" : "pig-29pt@1x.png", + "filename" : "icon-29pt@1x.png", "scale" : "1x" }, { "size" : "29x29", "idiom" : "ipad", - "filename" : "pig-29pt@2x.png", + "filename" : "icon-29pt@2x.png", "scale" : "2x" }, { "size" : "40x40", "idiom" : "ipad", - "filename" : "pig-40pt@1x.png", + "filename" : "icon-40pt@1x.png", "scale" : "1x" }, { "size" : "40x40", "idiom" : "ipad", - "filename" : "pig-40pt@2x.png", + "filename" : "icon-40pt@2x.png", "scale" : "2x" }, { "size" : "50x50", "idiom" : "ipad", - "filename" : "pig-50pt@1x.png", + "filename" : "icon-50pt@1x.png", "scale" : "1x" }, { "size" : "50x50", "idiom" : "ipad", - "filename" : "pig-50pt@2x.png", + "filename" : "icon-50pt@2x.png", "scale" : "2x" }, { "size" : "72x72", "idiom" : "ipad", - "filename" : "pig-72pt@1x.png", + "filename" : "icon-72pt@1x.png", "scale" : "1x" }, { "size" : "72x72", "idiom" : "ipad", - "filename" : "pig-72pt@2x.png", + "filename" : "icon-72pt@2x.png", "scale" : "2x" }, { "size" : "76x76", "idiom" : "ipad", - "filename" : "pig-76pt@1x.png", + "filename" : "icon-76pt@1x.png", "scale" : "1x" }, { "size" : "76x76", "idiom" : "ipad", - "filename" : "pig-76pt@2x.png", + "filename" : "icon-76pt@2x.png", "scale" : "2x" }, { "size" : "83.5x83.5", "idiom" : "ipad", - "filename" : "pig-83.5pt@2x.png", + "filename" : "icon-83.5pt@2x.png", "scale" : "2x" } ], @@ -125,4 +125,4 @@ "version" : 1, "author" : "xcode" } -} \ No newline at end of file +} diff --git a/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-29pt@1x.png b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-29pt@1x.png new file mode 100644 index 000000000..8b548ef9b Binary files /dev/null and b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-29pt@1x.png differ diff --git a/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-29pt@2x.png b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-29pt@2x.png new file mode 100644 index 000000000..1fcc4be30 Binary files /dev/null and b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-29pt@2x.png differ diff --git a/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-29pt@3x.png b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-29pt@3x.png new file mode 100644 index 000000000..d7a8b6000 Binary files /dev/null and b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-29pt@3x.png differ diff --git a/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-40pt@1x.png b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-40pt@1x.png new file mode 100644 index 000000000..aa936450e Binary files /dev/null and b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-40pt@1x.png differ diff --git a/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-40pt@2x.png b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-40pt@2x.png new file mode 100644 index 000000000..6705cbfa9 Binary files /dev/null and b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-40pt@2x.png differ diff --git a/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-40pt@3x.png b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-40pt@3x.png new file mode 100644 index 000000000..54ca124f3 Binary files /dev/null and b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-40pt@3x.png differ diff --git a/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-50pt@1x.png b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-50pt@1x.png new file mode 100644 index 000000000..8b9b1118d Binary files /dev/null and b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-50pt@1x.png differ diff --git a/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-50pt@2x.png b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-50pt@2x.png new file mode 100644 index 000000000..9806b7083 Binary files /dev/null and b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-50pt@2x.png differ diff --git a/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-57pt@1x.png b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-57pt@1x.png new file mode 100644 index 000000000..02d7cc98c Binary files /dev/null and b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-57pt@1x.png differ diff --git a/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-57pt@2x.png b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-57pt@2x.png new file mode 100644 index 000000000..68f898502 Binary files /dev/null and b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-57pt@2x.png differ diff --git a/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-60pt@2x.png b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-60pt@2x.png new file mode 100644 index 000000000..54ca124f3 Binary files /dev/null and b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-60pt@2x.png differ diff --git a/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-60pt@3x.png b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-60pt@3x.png new file mode 100644 index 000000000..c93997c00 Binary files /dev/null and b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-60pt@3x.png differ diff --git a/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-72pt@1x.png b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-72pt@1x.png new file mode 100644 index 000000000..a47c6d10e Binary files /dev/null and b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-72pt@1x.png differ diff --git a/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-72pt@2x.png b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-72pt@2x.png new file mode 100644 index 000000000..0850319f1 Binary files /dev/null and b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-72pt@2x.png differ diff --git a/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-76pt@1x.png b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-76pt@1x.png new file mode 100644 index 000000000..f90a1360f Binary files /dev/null and b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-76pt@1x.png differ diff --git a/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-76pt@2x.png b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-76pt@2x.png new file mode 100644 index 000000000..c2cba8cc3 Binary files /dev/null and b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-76pt@2x.png differ diff --git a/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-83.5pt@2x.png b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-83.5pt@2x.png new file mode 100644 index 000000000..ac90e1bb7 Binary files /dev/null and b/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/icon-83.5pt@2x.png differ diff --git a/platform/xcode/ios/Images.xcassets/LaunchImage.launchimage/Contents.json b/platform/xcode/Images.xcassets/iOS LaunchImage.launchimage/Contents.json similarity index 100% rename from platform/xcode/ios/Images.xcassets/LaunchImage.launchimage/Contents.json rename to platform/xcode/Images.xcassets/iOS LaunchImage.launchimage/Contents.json diff --git a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-29pt@1x.png b/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-29pt@1x.png deleted file mode 100644 index 7b2ef1872..000000000 Binary files a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-29pt@1x.png and /dev/null differ diff --git a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-29pt@2x.png b/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-29pt@2x.png deleted file mode 100644 index a67fca032..000000000 Binary files a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-29pt@2x.png and /dev/null differ diff --git a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-29pt@3x.png b/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-29pt@3x.png deleted file mode 100644 index 9fcc1ee0a..000000000 Binary files a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-29pt@3x.png and /dev/null differ diff --git a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-40pt@1x.png b/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-40pt@1x.png deleted file mode 100644 index 599212d2b..000000000 Binary files a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-40pt@1x.png and /dev/null differ diff --git a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-40pt@2x.png b/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-40pt@2x.png deleted file mode 100644 index fbb029b5f..000000000 Binary files a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-40pt@2x.png and /dev/null differ diff --git a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-40pt@3x.png b/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-40pt@3x.png deleted file mode 100644 index de29613e9..000000000 Binary files a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-40pt@3x.png and /dev/null differ diff --git a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-50pt@1x.png b/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-50pt@1x.png deleted file mode 100644 index 87a29dd2e..000000000 Binary files a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-50pt@1x.png and /dev/null differ diff --git a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-50pt@2x.png b/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-50pt@2x.png deleted file mode 100644 index 0fb257a35..000000000 Binary files a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-50pt@2x.png and /dev/null differ diff --git a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-57pt@1x.png b/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-57pt@1x.png deleted file mode 100644 index d5c81e2e2..000000000 Binary files a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-57pt@1x.png and /dev/null differ diff --git a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-57pt@2x.png b/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-57pt@2x.png deleted file mode 100644 index 77bc3086d..000000000 Binary files a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-57pt@2x.png and /dev/null differ diff --git a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-60pt@2x.png b/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-60pt@2x.png deleted file mode 100644 index de29613e9..000000000 Binary files a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-60pt@2x.png and /dev/null differ diff --git a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-60pt@3x.png b/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-60pt@3x.png deleted file mode 100644 index 0d31db7f1..000000000 Binary files a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-60pt@3x.png and /dev/null differ diff --git a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-72pt@1x.png b/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-72pt@1x.png deleted file mode 100644 index e9648ceb9..000000000 Binary files a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-72pt@1x.png and /dev/null differ diff --git a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-72pt@2x.png b/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-72pt@2x.png deleted file mode 100644 index 4227fd6a5..000000000 Binary files a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-72pt@2x.png and /dev/null differ diff --git a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-76pt@1x.png b/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-76pt@1x.png deleted file mode 100644 index 4e40fe0bf..000000000 Binary files a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-76pt@1x.png and /dev/null differ diff --git a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-76pt@2x.png b/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-76pt@2x.png deleted file mode 100644 index d5fcbe95a..000000000 Binary files a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-76pt@2x.png and /dev/null differ diff --git a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-83.5pt@2x.png b/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-83.5pt@2x.png deleted file mode 100644 index 78c9f8c88..000000000 Binary files a/platform/xcode/ios/Images.xcassets/AppIcon.appiconset/pig-83.5pt@2x.png and /dev/null differ diff --git a/platform/xcode/ios/Launch Screen.xib b/platform/xcode/ios/Launch Screen.xib index 91013a3de..45fffdbdb 100644 --- a/platform/xcode/ios/Launch Screen.xib +++ b/platform/xcode/ios/Launch Screen.xib @@ -1,8 +1,8 @@ - + - + diff --git a/platform/xcode/love.xcodeproj/project.pbxproj b/platform/xcode/love.xcodeproj/project.pbxproj index 823472763..a1cfe0367 100644 --- a/platform/xcode/love.xcodeproj/project.pbxproj +++ b/platform/xcode/love.xcodeproj/project.pbxproj @@ -20,10 +20,9 @@ FA0797991BF480A200034B7C /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA0797981BF480A200034B7C /* GameController.framework */; }; FA08F69616C766E000F007B5 /* love.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA08F69116C765A200F007B5 /* love.framework */; }; FA08F69716C766E700F007B5 /* love.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = FA08F69116C765A200F007B5 /* love.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; - FA0B78D21A95814A000E1D17 /* love.icns in Resources */ = {isa = PBXBuildFile; fileRef = FA0B78D01A95814A000E1D17 /* love.icns */; }; - FA0B78D31A95814A000E1D17 /* lovedocument.icns in Resources */ = {isa = PBXBuildFile; fileRef = FA0B78D11A95814A000E1D17 /* lovedocument.icns */; }; FA0B7F301A95AC7D000E1D17 /* love.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A93E6A3410420AC0007D418B /* love.cpp */; }; FA27B3CB1B498696008A9DCE /* Theora.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA27B3CA1B498696008A9DCE /* Theora.framework */; }; + FA5933751C6D625B000EC779 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FA5D249A1A96CF4300C6FC8F /* Images.xcassets */; }; FA5D24821A96CA1800C6FC8F /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA5D24811A96CA1800C6FC8F /* OpenAL.framework */; }; FA5D24841A96CA2700C6FC8F /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA5D24831A96CA2700C6FC8F /* OpenGLES.framework */; }; FA5D24881A96CA8A00C6FC8F /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA5D24871A96CA8A00C6FC8F /* UIKit.framework */; }; @@ -113,8 +112,6 @@ A9F169A6109E824900FC83D1 /* mpg123.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = mpg123.framework; path = /Library/Frameworks/mpg123.framework; sourceTree = ""; }; FA0797981BF480A200034B7C /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.1.sdk/System/Library/Frameworks/GameController.framework; sourceTree = DEVELOPER_DIR; }; FA08F69116C765A200F007B5 /* love.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = love.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - FA0B78D01A95814A000E1D17 /* love.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = love.icns; path = macosx/love.icns; sourceTree = ""; }; - FA0B78D11A95814A000E1D17 /* lovedocument.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = lovedocument.icns; path = macosx/lovedocument.icns; sourceTree = ""; }; FA0B7F061A95AAF3000E1D17 /* love.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = love.app; sourceTree = BUILT_PRODUCTS_DIR; }; FA27B3CA1B498696008A9DCE /* Theora.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Theora.framework; path = /Library/Frameworks/Theora.framework; sourceTree = ""; }; FA577A9316C7217800860150 /* liblove.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = liblove.xcodeproj; sourceTree = ""; }; @@ -127,7 +124,7 @@ FA5D24931A96CABA00C6FC8F /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.1.sdk/usr/lib/libz.dylib; sourceTree = DEVELOPER_DIR; }; FA5D24951A96CAC200C6FC8F /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.1.sdk/System/Library/Frameworks/CoreMotion.framework; sourceTree = DEVELOPER_DIR; }; FA5D24971A96CE1E00C6FC8F /* love-ios.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "love-ios.plist"; path = "ios/love-ios.plist"; sourceTree = ""; }; - FA5D249A1A96CF4300C6FC8F /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = ios/Images.xcassets; sourceTree = ""; }; + FA5D249A1A96CF4300C6FC8F /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; FA5D24C11A96D78000C6FC8F /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.1.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; FA7C63691A9C49570000FD29 /* Launch Screen.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = "Launch Screen.xib"; path = "ios/Launch Screen.xib"; sourceTree = ""; }; FA9B4A0916E1579F00074F42 /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = /Library/Frameworks/SDL2.framework; sourceTree = ""; }; @@ -206,8 +203,6 @@ isa = PBXGroup; children = ( FAC1A448196F5DC600125284 /* license.txt */, - FA0B78D01A95814A000E1D17 /* love.icns */, - FA0B78D11A95814A000E1D17 /* lovedocument.icns */, ); name = Resources; sourceTree = ""; @@ -379,9 +374,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + FA5933751C6D625B000EC779 /* Images.xcassets in Resources */, FAC1A449196F5DC600125284 /* license.txt in Resources */, - FA0B78D31A95814A000E1D17 /* lovedocument.icns in Resources */, - FA0B78D21A95814A000E1D17 /* love.icns in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -432,6 +426,7 @@ C01FCF4B08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = "OS X AppIcon"; COMBINE_HIDPI_IMAGES = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -458,6 +453,7 @@ C01FCF4C08A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = "OS X AppIcon"; COMBINE_HIDPI_IMAGES = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; FRAMEWORK_SEARCH_PATHS = ( @@ -597,8 +593,8 @@ FA0B7F261A95AAF4000E1D17 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + ASSETCATALOG_COMPILER_APPICON_NAME = "iOS AppIcon"; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = "iOS LaunchImage"; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; @@ -643,8 +639,8 @@ FA0B7F271A95AAF4000E1D17 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + ASSETCATALOG_COMPILER_APPICON_NAME = "iOS AppIcon"; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = "iOS LaunchImage"; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; @@ -685,8 +681,8 @@ FA0B7F281A95AAF4000E1D17 /* Distribution */ = { isa = XCBuildConfiguration; buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + ASSETCATALOG_COMPILER_APPICON_NAME = "iOS AppIcon"; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = "iOS LaunchImage"; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; @@ -786,6 +782,7 @@ FA5326C718971A0900F7BBF4 /* Distribution */ = { isa = XCBuildConfiguration; buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = "OS X AppIcon"; COMBINE_HIDPI_IMAGES = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; FRAMEWORK_SEARCH_PATHS = ( diff --git a/platform/xcode/macosx/love-macosx.plist b/platform/xcode/macosx/love-macosx.plist index f90396a75..b5a9adf0e 100644 --- a/platform/xcode/macosx/love-macosx.plist +++ b/platform/xcode/macosx/love-macosx.plist @@ -8,7 +8,7 @@ CFBundleTypeIconFile - lovedocument + GameIcon CFBundleTypeName LÖVE Project CFBundleTypeRole @@ -47,8 +47,6 @@ CFBundleExecutable love - CFBundleIconFile - love.icns CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion @@ -79,7 +77,7 @@ UTTypeDescription LÖVE Project UTTypeIconFile - lovedocument + GameIcon UTTypeIdentifier org.love2d.love-game UTTypeReferenceURL diff --git a/platform/xcode/macosx/love.icns b/platform/xcode/macosx/love.icns deleted file mode 100644 index 483712ea0..000000000 Binary files a/platform/xcode/macosx/love.icns and /dev/null differ diff --git a/platform/xcode/macosx/lovedocument.icns b/platform/xcode/macosx/lovedocument.icns deleted file mode 100644 index 1dede26b8..000000000 Binary files a/platform/xcode/macosx/lovedocument.icns and /dev/null differ diff --git a/src/common/Variant.cpp b/src/common/Variant.cpp index 32e9ba5ea..b26a368ef 100644 --- a/src/common/Variant.cpp +++ b/src/common/Variant.cpp @@ -26,35 +26,21 @@ namespace love static love::Type extractudatatype(lua_State *L, int idx) { - Type t = INVALID_ID; - if (!lua_isuserdata(L, idx)) - return t; - if (luaL_getmetafield(L, idx, "type") == 0) - return t; - lua_pushvalue(L, idx); - int result = lua_pcall(L, 1, 1, 0); - if (result == 0) - getTypeName(lua_tostring(L, -1), t); - if (result == 0 || result == LUA_ERRRUN) - lua_pop(L, 1); - return t; -} + Proxy *u = (Proxy *)lua_touserdata(L, idx); -static inline void delete_table(std::vector > *table) -{ - while (!table->empty()) - { - std::pair &kv = table->back(); - kv.first->release(); - kv.second->release(); - table->pop_back(); - } - delete table; + if (u == nullptr || u->type <= INVALID_ID || u->type >= TYPE_MAX_ENUM) + return INVALID_ID; + + // We could get rid of the dynamic_cast for more performance, but it would + // be less safe... + if (dynamic_cast(u->object) != nullptr) + return u->type; + + return INVALID_ID; } Variant::Variant() : type(NIL) - , data() { } @@ -71,19 +57,18 @@ Variant::Variant(double number) } Variant::Variant(const char *string, size_t len) - : type(STRING) { - char *buf = new char[len+1]; - memset(buf, 0, len+1); - memcpy(buf, string, len); - data.string.str = buf; - data.string.len = len; -} - -Variant::Variant(char c) - : type(CHARACTER) -{ - data.character = c; + if (len <= MAX_SMALL_STRING_LENGTH) + { + type = SMALLSTRING; + memcpy(data.smallstring.str, string, len); + data.smallstring.len = (uint8) len; + } + else + { + type = STRING; + data.string = new SharedString(string, len); + } } Variant::Variant(void *userdata) @@ -107,10 +92,23 @@ Variant::Variant(love::Type udatatype, void *userdata) } // Variant gets ownership of the vector. -Variant::Variant(std::vector > *table) +Variant::Variant(std::vector> *table) : type(TABLE) { - data.table = table; + data.table = new SharedTable(table); +} + +Variant::Variant(const Variant &v) + : type(v.type) + , udatatype(v.udatatype) + , data(v.data) +{ + if (type == STRING) + data.string->retain(); + else if (type == FUSERDATA) + ((love::Object *) data.userdata)->retain(); + else if (type == TABLE) + data.table->retain(); } Variant::~Variant() @@ -118,102 +116,126 @@ Variant::~Variant() switch (type) { case STRING: - delete[] data.string.str; + data.string->release(); break; case FUSERDATA: ((love::Object *) data.userdata)->release(); break; case TABLE: - delete_table(data.table); + data.table->release(); + break; default: break; } } -Variant *Variant::fromLua(lua_State *L, int n, bool allowTables) +Variant &Variant::operator = (const Variant &v) +{ + if (v.type == STRING) + v.data.string->retain(); + else if (v.type == FUSERDATA) + ((love::Object *) v.data.userdata)->retain(); + else if (v.type == TABLE) + v.data.table->retain(); + + if (type == STRING) + data.string->release(); + else if (type == FUSERDATA) + ((love::Object *) v.data.userdata)->release(); + else if (type == TABLE) + data.table->release(); + + type = v.type; + data = v.data; + udatatype = v.udatatype; + + return *this; +} + +bool Variant::fromLua(lua_State *L, int n, Variant *v, bool allowTables) { - Variant *v = nullptr; size_t len; const char *str; + if (n < 0) // Fix the stack position, we might modify it later n += lua_gettop(L) + 1; switch (lua_type(L, n)) { case LUA_TBOOLEAN: - v = new Variant(luax_toboolean(L, n)); - break; + *v = Variant(luax_toboolean(L, n)); + return true; case LUA_TNUMBER: - v = new Variant(lua_tonumber(L, n)); - break; + *v = Variant(lua_tonumber(L, n)); + return true; case LUA_TSTRING: str = lua_tolstring(L, n, &len); - v = new Variant(str, len); - break; + *v = Variant(str, len); + return true; case LUA_TLIGHTUSERDATA: - v = new Variant(lua_touserdata(L, n)); - break; + *v = Variant(lua_touserdata(L, n)); + return true; case LUA_TUSERDATA: - v = new Variant(extractudatatype(L, n), lua_touserdata(L, n)); - break; + *v = Variant(extractudatatype(L, n), lua_touserdata(L, n)); + return true; case LUA_TNIL: - v = new Variant(); - break; + *v = Variant(); + return true; case LUA_TTABLE: if (allowTables) { bool success = true; - std::vector> *table = new std::vector>(); + std::vector> *table = new std::vector>(); + std::pair pair; + + size_t len = luax_objlen(L, -1); + if (len > 0) + table->reserve(len); + lua_pushnil(L); + while (lua_next(L, n)) { - Variant *key = fromLua(L, -2, false); - if (!key) + if (!fromLua(L, -2, &pair.first, false) || !fromLua(L, -1, &pair.second, false)) { success = false; lua_pop(L, 2); break; } - Variant *value = fromLua(L, -1, false); - if (!value) - { - delete key; - success = false; - lua_pop(L, 2); - break; - } - - table->push_back(std::make_pair(key, value)); - + table->push_back(pair); lua_pop(L, 1); } if (success) - v = new Variant(table); + { + *v = Variant(table); + return true; + } else - delete_table(table); + delete table; } break; } - return v; + + return false; } -void Variant::toLua(lua_State *L) +void Variant::toLua(lua_State *L) const { switch (type) { case BOOLEAN: lua_pushboolean(L, data.boolean); break; - case CHARACTER: - lua_pushlstring(L, &data.character, 1); - break; case NUMBER: lua_pushnumber(L, data.number); break; case STRING: - lua_pushlstring(L, data.string.str, data.string.len); + lua_pushlstring(L, data.string->str, data.string->len); + break; + case SMALLSTRING: + lua_pushlstring(L, data.smallstring.str, data.smallstring.len); break; case LUSERDATA: lua_pushlightuserdata(L, data.userdata); @@ -228,15 +250,20 @@ void Variant::toLua(lua_State *L) // I can do (at the moment). break; case TABLE: - lua_createtable(L, 0, (int) data.table->size()); - for (size_t i = 0; i < data.table->size(); ++i) + { + std::vector> *table = data.table->table; + lua_createtable(L, 0, (int) table->size()); + + for (size_t i = 0; i < table->size(); ++i) { - std::pair &kv = data.table->at(i); - kv.first->toLua(L); - kv.second->toLua(L); + std::pair &kv = table->at(i); + kv.first.toLua(L); + kv.second.toLua(L); lua_settable(L, -3); } + break; + } case NIL: default: lua_pushnil(L); diff --git a/src/common/Variant.h b/src/common/Variant.h index ce7dad08e..9a860a73c 100644 --- a/src/common/Variant.h +++ b/src/common/Variant.h @@ -23,15 +23,15 @@ #include "common/runtime.h" #include "common/Object.h" +#include "common/int.h" #include #include -#include namespace love { -class Variant : public love::Object +class Variant { public: @@ -39,44 +39,81 @@ public: Variant(bool boolean); Variant(double number); Variant(const char *string, size_t len); - Variant(char c); Variant(void *userdata); Variant(love::Type udatatype, void *userdata); - Variant(std::vector > *table); - virtual ~Variant(); + Variant(std::vector> *table); + Variant(const Variant &v); + ~Variant(); - static Variant *fromLua(lua_State *L, int n, bool allowTables = true); - void toLua(lua_State *L); + Variant &operator = (const Variant &v); + + static bool fromLua(lua_State *L, int n, Variant *v, bool allowTables = true); + void toLua(lua_State *L) const; + +private: + + class SharedString : public love::Object + { + public: + + SharedString(const char *string, size_t len) + : len(len) + { + str = new char[len+1]; + memcpy(str, string, len); + } + virtual ~SharedString() { delete[] str; } + + char *str; + size_t len; + }; + + class SharedTable : public love::Object + { + public: + + SharedTable(std::vector> *table) + : table(table) + { + } + + virtual ~SharedTable() { delete table; } + + std::vector> *table; + }; enum Type { UNKNOWN = 0, BOOLEAN, NUMBER, - CHARACTER, STRING, + SMALLSTRING, LUSERDATA, FUSERDATA, NIL, TABLE - } type; - union + }; + + static const int MAX_SMALL_STRING_LENGTH = 15; + + Type type; + love::Type udatatype; + + union Data { bool boolean; - char character; double number; + SharedString *string; + void *userdata; + SharedTable *table; struct { - const char *str; - size_t len; - } string; - void *userdata; - std::vector> *table; + char str[MAX_SMALL_STRING_LENGTH]; + uint8 len; + } smallstring; } data; -private: - love::Type udatatype; - }; // Variant } // love diff --git a/src/common/runtime.h b/src/common/runtime.h index 08020d7c7..9072c99db 100644 --- a/src/common/runtime.h +++ b/src/common/runtime.h @@ -445,7 +445,7 @@ T *luax_checktype(lua_State *L, int idx, love::Type type) Proxy *u = (Proxy *)lua_touserdata(L, idx); - if (!typeFlags[u->type][type]) + if (u->type <= INVALID_ID || u->type >= TYPE_MAX_ENUM || !typeFlags[u->type][type]) { const char *name = "Invalid"; getTypeName(type, name); @@ -469,7 +469,7 @@ T *luax_getmodule(lua_State *L, love::Type type) Proxy *u = (Proxy *)lua_touserdata(L, -1); - if (!typeFlags[u->type][type]) + if (u->type <= INVALID_ID || u->type >= TYPE_MAX_ENUM || !typeFlags[u->type][type]) luaL_error(L, "Incorrect module %s", name); lua_pop(L, 2); diff --git a/src/modules/audio/openal/Source.cpp b/src/modules/audio/openal/Source.cpp index 3f0b1a802..b9fb49a36 100644 --- a/src/modules/audio/openal/Source.cpp +++ b/src/modules/audio/openal/Source.cpp @@ -574,7 +574,7 @@ void Source::setRelative(bool enable) throw SpatialSupportException(); if (valid) - alSourcei(source, AL_SOURCE_RELATIVE, relative ? AL_TRUE : AL_FALSE); + alSourcei(source, AL_SOURCE_RELATIVE, enable ? AL_TRUE : AL_FALSE); relative = enable; } diff --git a/src/modules/event/Event.cpp b/src/modules/event/Event.cpp index d35f533d2..af5d86b08 100644 --- a/src/modules/event/Event.cpp +++ b/src/modules/event/Event.cpp @@ -28,7 +28,7 @@ namespace love namespace event { -Message::Message(const std::string &name, const std::vector> &vargs) +Message::Message(const std::string &name, const std::vector &vargs) : name(name) , args(vargs) { @@ -42,13 +42,8 @@ int Message::toLua(lua_State *L) { luax_pushstring(L, name); - for (const StrongRef &v : args) - { - if (v.get() != nullptr) - v->toLua(L); - else - lua_pushnil(L); - } + for (const Variant &v : args) + v.toLua(L); return (int) args.size() + 1; } @@ -56,26 +51,26 @@ int Message::toLua(lua_State *L) Message *Message::fromLua(lua_State *L, int n) { std::string name = luax_checkstring(L, n); - std::vector> vargs; + std::vector vargs; int count = lua_gettop(L) - n; n++; + Variant varg; + for (int i = 0; i < count; i++) { if (lua_isnoneornil(L, n+i)) break; - vargs.push_back(Variant::fromLua(L, n+i)); - - if (!vargs.back().get()) + if (!Variant::fromLua(L, n+i, &varg)) { vargs.clear(); luaL_error(L, "Argument %d can't be stored safely\nExpected boolean, number, string or userdata.", n+i); return nullptr; } - vargs.back()->release(); // fromLua gave a +1 ref. + vargs.push_back(varg); } return new Message(name, vargs); diff --git a/src/modules/event/Event.h b/src/modules/event/Event.h index 1ca6e947e..d597855e9 100644 --- a/src/modules/event/Event.h +++ b/src/modules/event/Event.h @@ -43,7 +43,7 @@ class Message : public Object { public: - Message(const std::string &name, const std::vector> &vargs = {}); + Message(const std::string &name, const std::vector &vargs = {}); ~Message(); int toLua(lua_State *L); @@ -52,7 +52,7 @@ public: private: std::string name; - std::vector> args; + std::vector args; }; // Message diff --git a/src/modules/event/sdl/Event.cpp b/src/modules/event/sdl/Event.cpp index 04125db8a..52caa11ca 100644 --- a/src/modules/event/sdl/Event.cpp +++ b/src/modules/event/sdl/Event.cpp @@ -150,7 +150,7 @@ Message *Event::convert(const SDL_Event &e) const { Message *msg = nullptr; - std::vector> vargs; + std::vector vargs; vargs.reserve(4); love::filesystem::Filesystem *filesystem = nullptr; @@ -192,9 +192,9 @@ Message *Event::convert(const SDL_Event &e) const if (!love::keyboard::Keyboard::getConstant(scancode, txt2)) txt2 = "unknown"; - vargs.push_back(new Variant(txt, strlen(txt))); - vargs.push_back(new Variant(txt2, strlen(txt2))); - vargs.push_back(new Variant(e.key.repeat != 0)); + vargs.emplace_back(txt, strlen(txt)); + vargs.emplace_back(txt2, strlen(txt2)); + vargs.emplace_back(e.key.repeat != 0); msg = new Message("keypressed", vargs); break; case SDL_KEYUP: @@ -209,20 +209,20 @@ Message *Event::convert(const SDL_Event &e) const if (!love::keyboard::Keyboard::getConstant(scancode, txt2)) txt2 = "unknown"; - vargs.push_back(new Variant(txt, strlen(txt))); - vargs.push_back(new Variant(txt2, strlen(txt2))); + vargs.emplace_back(txt, strlen(txt)); + vargs.emplace_back(txt2, strlen(txt2)); msg = new Message("keyreleased", vargs); break; case SDL_TEXTINPUT: txt = e.text.text; - vargs.push_back(new Variant(txt, strlen(txt))); + vargs.emplace_back(txt, strlen(txt)); msg = new Message("textinput", vargs); break; case SDL_TEXTEDITING: txt = e.edit.text; - vargs.push_back(new Variant(txt, strlen(txt))); - vargs.push_back(new Variant((double) e.edit.start)); - vargs.push_back(new Variant((double) e.edit.length)); + vargs.emplace_back(txt, strlen(txt)); + vargs.emplace_back((double) e.edit.start); + vargs.emplace_back((double) e.edit.length); msg = new Message("textedited", vargs); break; case SDL_MOUSEMOTION: @@ -233,11 +233,11 @@ Message *Event::convert(const SDL_Event &e) const double yrel = (double) e.motion.yrel; windowToPixelCoords(&x, &y); windowToPixelCoords(&xrel, &yrel); - vargs.push_back(new Variant(x)); - vargs.push_back(new Variant(y)); - vargs.push_back(new Variant(xrel)); - vargs.push_back(new Variant(yrel)); - vargs.push_back(new Variant(e.motion.which == SDL_TOUCH_MOUSEID)); + vargs.emplace_back(x); + vargs.emplace_back(y); + vargs.emplace_back(xrel); + vargs.emplace_back(yrel); + vargs.emplace_back(e.motion.which == SDL_TOUCH_MOUSEID); msg = new Message("mousemoved", vargs); } break; @@ -260,18 +260,18 @@ Message *Event::convert(const SDL_Event &e) const double x = (double) e.button.x; double y = (double) e.button.y; windowToPixelCoords(&x, &y); - vargs.push_back(new Variant(x)); - vargs.push_back(new Variant(y)); - vargs.push_back(new Variant((double) button)); - vargs.push_back(new Variant(e.button.which == SDL_TOUCH_MOUSEID)); + vargs.emplace_back(x); + vargs.emplace_back(y); + vargs.emplace_back((double) button); + vargs.emplace_back(e.button.which == SDL_TOUCH_MOUSEID); msg = new Message((e.type == SDL_MOUSEBUTTONDOWN) ? "mousepressed" : "mousereleased", vargs); } break; case SDL_MOUSEWHEEL: - vargs.push_back(new Variant((double) e.wheel.x)); - vargs.push_back(new Variant((double) e.wheel.y)); + vargs.emplace_back((double) e.wheel.x); + vargs.emplace_back((double) e.wheel.y); msg = new Message("wheelmoved", vargs); break; case SDL_FINGERDOWN: @@ -316,12 +316,12 @@ Message *Event::convert(const SDL_Event &e) const // bits as can fit in a pointer (for now.) // We use lightuserdata instead of a lua_Number (double) because doubles // can't represent all possible id values on 64-bit systems. - vargs.push_back(new Variant((void *) (intptr_t) touchinfo.id)); - vargs.push_back(new Variant(touchinfo.x)); - vargs.push_back(new Variant(touchinfo.y)); - vargs.push_back(new Variant(touchinfo.dx)); - vargs.push_back(new Variant(touchinfo.dy)); - vargs.push_back(new Variant(touchinfo.pressure)); + vargs.emplace_back((void *) (intptr_t) touchinfo.id); + vargs.emplace_back(touchinfo.x); + vargs.emplace_back(touchinfo.y); + vargs.emplace_back(touchinfo.dx); + vargs.emplace_back(touchinfo.dy); + vargs.emplace_back(touchinfo.pressure); if (e.type == SDL_FINGERDOWN) txt = "touchpressed"; @@ -356,7 +356,7 @@ Message *Event::convert(const SDL_Event &e) const if (filesystem->isRealDirectory(e.drop.file)) { - vargs.push_back(new Variant(e.drop.file, strlen(e.drop.file))); + vargs.emplace_back(e.drop.file, strlen(e.drop.file)); msg = new Message("directorydropped", vargs); } else @@ -364,7 +364,7 @@ Message *Event::convert(const SDL_Event &e) const Proxy proxy; proxy.object = new love::filesystem::DroppedFile(e.drop.file); proxy.type = FILESYSTEM_DROPPED_FILE_ID; - vargs.push_back(new Variant(proxy.type, &proxy)); + vargs.emplace_back(proxy.type, &proxy); msg = new Message("filedropped", vargs); proxy.object->release(); } @@ -382,13 +382,6 @@ Message *Event::convert(const SDL_Event &e) const break; } - // We gave +1 refs to the StrongRef list, so we should release them. - for (const StrongRef &v : vargs) - { - if (v.get() != nullptr) - v->release(); - } - return msg; } @@ -400,7 +393,7 @@ Message *Event::convertJoystickEvent(const SDL_Event &e) const Message *msg = nullptr; - std::vector> vargs; + std::vector vargs; vargs.reserve(4); Proxy proxy; @@ -418,8 +411,8 @@ Message *Event::convertJoystickEvent(const SDL_Event &e) const if (!proxy.object) break; - vargs.push_back(new Variant(proxy.type, (void *) &proxy)); - vargs.push_back(new Variant((double)(e.jbutton.button+1))); + vargs.emplace_back(proxy.type, (void *) &proxy); + vargs.emplace_back((double)(e.jbutton.button+1)); msg = new Message((e.type == SDL_JOYBUTTONDOWN) ? "joystickpressed" : "joystickreleased", vargs); @@ -431,10 +424,10 @@ Message *Event::convertJoystickEvent(const SDL_Event &e) const if (!proxy.object) break; - vargs.push_back(new Variant(proxy.type, (void *) &proxy)); - vargs.push_back(new Variant((double)(e.jaxis.axis+1))); + vargs.emplace_back(proxy.type, (void *) &proxy); + vargs.emplace_back((double)(e.jaxis.axis+1)); float value = joystick::Joystick::clampval(e.jaxis.value / 32768.0f); - vargs.push_back(new Variant((double) value)); + vargs.emplace_back((double) value); msg = new Message("joystickaxis", vargs); } break; @@ -447,9 +440,9 @@ Message *Event::convertJoystickEvent(const SDL_Event &e) const if (!proxy.object) break; - vargs.push_back(new Variant(proxy.type, (void *) &proxy)); - vargs.push_back(new Variant((double)(e.jhat.hat+1))); - vargs.push_back(new Variant(txt, strlen(txt))); + vargs.emplace_back(proxy.type, (void *) &proxy); + vargs.emplace_back((double)(e.jhat.hat+1)); + vargs.emplace_back(txt, strlen(txt)); msg = new Message("joystickhat", vargs); break; case SDL_CONTROLLERBUTTONDOWN: @@ -465,8 +458,8 @@ Message *Event::convertJoystickEvent(const SDL_Event &e) const if (!proxy.object) break; - vargs.push_back(new Variant(proxy.type, (void *) &proxy)); - vargs.push_back(new Variant(txt, strlen(txt))); + vargs.emplace_back(proxy.type, (void *) &proxy); + vargs.emplace_back(txt, strlen(txt)); msg = new Message(e.type == SDL_CONTROLLERBUTTONDOWN ? "gamepadpressed" : "gamepadreleased", vargs); break; @@ -481,11 +474,11 @@ Message *Event::convertJoystickEvent(const SDL_Event &e) const if (!proxy.object) break; - vargs.push_back(new Variant(proxy.type, (void *) &proxy)); + vargs.emplace_back(proxy.type, (void *) &proxy); - vargs.push_back(new Variant(txt, strlen(txt))); + vargs.emplace_back(txt, strlen(txt)); float value = joystick::Joystick::clampval(e.caxis.value / 32768.0f); - vargs.push_back(new Variant((double) value)); + vargs.emplace_back((double) value); msg = new Message("gamepadaxis", vargs); } break; @@ -495,7 +488,7 @@ Message *Event::convertJoystickEvent(const SDL_Event &e) const proxy.type = JOYSTICK_JOYSTICK_ID; if (proxy.object) { - vargs.push_back(new Variant(proxy.type, (void *) &proxy)); + vargs.emplace_back(proxy.type, (void *) &proxy); msg = new Message("joystickadded", vargs); } break; @@ -506,37 +499,14 @@ Message *Event::convertJoystickEvent(const SDL_Event &e) const if (proxy.object) { joymodule->removeJoystick((joystick::Joystick *) proxy.object); - vargs.push_back(new Variant(proxy.type, (void *) &proxy)); + vargs.emplace_back(proxy.type, (void *) &proxy); msg = new Message("joystickremoved", vargs); } break; -#ifdef LOVE_ANDROID - case SDL_WINDOWEVENT_MINIMIZED: - { - auto audio = Module::getInstance(Module::M_AUDIO); - if (audio) - audio->pause(); - } - break; - case SDL_WINDOWEVENT_RESTORED: - { - auto audio = Module::getInstance(Module::M_AUDIO); - if (audio) - audio->resume(); - } - break; -#endif default: break; } - // We gave +1 refs to the StrongRef list, so we should release them. - for (const StrongRef &v : vargs) - { - if (v.get() != nullptr) - v->release(); - } - return msg; } @@ -544,7 +514,7 @@ Message *Event::convertWindowEvent(const SDL_Event &e) const { Message *msg = nullptr; - std::vector> vargs; + std::vector vargs; vargs.reserve(4); window::Window *win = nullptr; @@ -556,17 +526,17 @@ Message *Event::convertWindowEvent(const SDL_Event &e) const { case SDL_WINDOWEVENT_FOCUS_GAINED: case SDL_WINDOWEVENT_FOCUS_LOST: - vargs.push_back(new Variant(e.window.event == SDL_WINDOWEVENT_FOCUS_GAINED)); + vargs.emplace_back(e.window.event == SDL_WINDOWEVENT_FOCUS_GAINED); msg = new Message("focus", vargs); break; case SDL_WINDOWEVENT_ENTER: case SDL_WINDOWEVENT_LEAVE: - vargs.push_back(new Variant(e.window.event == SDL_WINDOWEVENT_ENTER)); + vargs.emplace_back(e.window.event == SDL_WINDOWEVENT_ENTER); msg = new Message("mousefocus", vargs); break; case SDL_WINDOWEVENT_SHOWN: case SDL_WINDOWEVENT_HIDDEN: - vargs.push_back(new Variant(e.window.event == SDL_WINDOWEVENT_SHOWN)); + vargs.emplace_back(e.window.event == SDL_WINDOWEVENT_SHOWN); msg = new Message("visible", vargs); break; case SDL_WINDOWEVENT_RESIZED: @@ -578,10 +548,10 @@ Message *Event::convertWindowEvent(const SDL_Event &e) const if (sdlwin) SDL_GL_GetDrawableSize(sdlwin, &px_w, &px_h); - vargs.push_back(new Variant((double) px_w)); - vargs.push_back(new Variant((double) px_h)); - vargs.push_back(new Variant((double) e.window.data1)); - vargs.push_back(new Variant((double) e.window.data2)); + vargs.emplace_back((double) px_w); + vargs.emplace_back((double) px_h); + vargs.emplace_back((double) e.window.data1); + vargs.emplace_back((double) e.window.data2); msg = new Message("resize", vargs); } break; @@ -590,13 +560,21 @@ Message *Event::convertWindowEvent(const SDL_Event &e) const if (win) win->onSizeChanged(e.window.data1, e.window.data2); break; - } - - // We gave +1 refs to the StrongRef list, so we should release them. - for (const StrongRef &v : vargs) + case SDL_WINDOWEVENT_MINIMIZED: + case SDL_WINDOWEVENT_RESTORED: +#ifdef LOVE_ANDROID { - if (v.get() != nullptr) - v->release(); + auto audio = Module::getInstance(Module::M_AUDIO); + if (audio) + { + if (e.window.event == SDL_WINDOWEVENT_MINIMIZED) + audio->pause(); + else if (e.window.event == SDL_WINDOWEVENT_RESTORED) + audio->resume(); + } + } +#endif + break; } return msg; diff --git a/src/modules/event/wrap_Event.cpp b/src/modules/event/wrap_Event.cpp index 06aa53a30..efe8191df 100644 --- a/src/modules/event/wrap_Event.cpp +++ b/src/modules/event/wrap_Event.cpp @@ -95,14 +95,11 @@ int w_clear(lua_State *) int w_quit(lua_State *L) { - std::vector> args; + std::vector args; - Variant *v = Variant::fromLua(L, 1); - if (v) - { + Variant v; + if (Variant::fromLua(L, 1, &v)) args.push_back(v); - v->release(); - } Message *m = new Message("quit", args); instance()->push(m); diff --git a/src/modules/graphics/opengl/Canvas.h b/src/modules/graphics/opengl/Canvas.h index 69cd22e73..7f7a9ec84 100644 --- a/src/modules/graphics/opengl/Canvas.h +++ b/src/modules/graphics/opengl/Canvas.h @@ -117,6 +117,7 @@ public: return actual_samples; } + static Format getSizedFormat(Format format); static bool isSupported(); static bool isMultiFormatMultiCanvasSupported(); static bool isFormatSupported(Format format); @@ -143,7 +144,6 @@ private: void drawv(const Matrix4 &t, const Vertex *v); - static Format getSizedFormat(Format format); static void convertFormat(Format format, GLenum &internalformat, GLenum &externalformat, GLenum &type); static size_t getFormatBitsPerPixel(Format format); diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index fd2ae0838..cd53bb458 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -459,17 +459,23 @@ void Graphics::clear(const std::vector &colors) if (colors.size() == 0) return; - if (states.back().canvases.size() == 0) + size_t numcanvases = states.back().canvases.size(); + + if (numcanvases > 0 && colors.size() != numcanvases) + throw love::Exception("Number of clear colors must match the number of active canvases (%ld)", states.back().canvases.size()); + + // We want to take the single-color codepath if there's no active Canvas, or + // if there's only one active Canvas. The multi-color codepath (in the loop + // below) assumes MRT functions are available, and also may call more + // expensive GL functions which are unnecessary if only one Canvas is active. + if (numcanvases <= 1) { if (colors[0].enabled) - clear({colors[0].r, colors[0].g, colors[0].b, colors[0].a}); + clear(colors[0].toColor()); return; } - if (colors.size() != states.back().canvases.size()) - throw love::Exception("Number of clear colors must match the number of active canvases (%ld)", states.back().canvases.size()); - bool drawbuffermodified = false; for (int i = 0; i < (int) colors.size(); i++) @@ -840,11 +846,14 @@ ParticleSystem *Graphics::newParticleSystem(Texture *texture, int size) Canvas *Graphics::newCanvas(int width, int height, Canvas::Format format, int msaa) { + if (!Canvas::isSupported()) + throw love::Exception("Canvases are not supported by your OpenGL drivers!"); + if (!Canvas::isFormatSupported(format)) { const char *fstr = "rgba8"; - Canvas::getConstant(format, fstr); - throw love::Exception("The %s canvas format is not supported by your OpenGL implementation.", fstr); + Canvas::getConstant(Canvas::getSizedFormat(format), fstr); + throw love::Exception("The %s canvas format is not supported by your OpenGL drivers.", fstr); } if (width > gl.getMaxTextureSize()) @@ -868,7 +877,7 @@ Canvas *Graphics::newCanvas(int width, int height, Canvas::Format format, int ms switch (err) { case GL_FRAMEBUFFER_UNSUPPORTED: - error_string << "Not supported by your OpenGL implementation."; + error_string << "Not supported by your OpenGL drivers."; break; case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: error_string << "Texture format cannot be rendered to on this system."; @@ -879,14 +888,14 @@ Canvas *Graphics::newCanvas(int width, int height, Canvas::Format format, int ms case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: - error_string << "Error in implementation."; + error_string << "Error in graphics driver."; break; default: // my intel hda card wrongly returns 0 to glCheckFramebufferStatus() but sets // no error flag. I think it meant to return GL_FRAMEBUFFER_UNSUPPORTED, but who // knows. if (glGetError() == GL_NO_ERROR) - error_string << "May not be supported by your OpenGL implementation."; + error_string << "May not be supported by your OpenGL drivers."; // the remaining error is an indication of a serious fuckup since it should // only be returned if glCheckFramebufferStatus() was called with the wrong // arguments. diff --git a/src/modules/graphics/opengl/Graphics.h b/src/modules/graphics/opengl/Graphics.h index 12517504a..bd70fea55 100644 --- a/src/modules/graphics/opengl/Graphics.h +++ b/src/modules/graphics/opengl/Graphics.h @@ -66,6 +66,8 @@ public: { float r, g, b, a; bool enabled; + + Colorf toColor() const { return Colorf(r, g, b, a); } }; Graphics(); diff --git a/src/modules/graphics/opengl/wrap_Graphics.cpp b/src/modules/graphics/opengl/wrap_Graphics.cpp index 44510be08..68a7d0322 100644 --- a/src/modules/graphics/opengl/wrap_Graphics.cpp +++ b/src/modules/graphics/opengl/wrap_Graphics.cpp @@ -47,6 +47,13 @@ namespace opengl #define instance() (Module::getInstance(Module::M_GRAPHICS)) +static int luax_checkgraphicscreated(lua_State *L) +{ + if (!instance()->isCreated()) + return luaL_error(L, "love.graphics cannot function without a window!"); + return 0; +} + int w_reset(lua_State *) { instance()->reset(); @@ -290,6 +297,8 @@ static const char *imageFlagName(Image::FlagType flagtype) int w_newImage(lua_State *L) { + luax_checkgraphicscreated(L); + std::vector data; std::vector cdata; @@ -400,6 +409,8 @@ int w_newImage(lua_State *L) int w_newQuad(lua_State *L) { + luax_checkgraphicscreated(L); + Quad::Viewport v; v.x = luaL_checknumber(L, 1); v.y = luaL_checknumber(L, 2); @@ -417,6 +428,8 @@ int w_newQuad(lua_State *L) int w_newFont(lua_State *L) { + luax_checkgraphicscreated(L); + Font *font = nullptr; // Convert to Rasterizer, if necessary. @@ -443,6 +456,8 @@ int w_newFont(lua_State *L) int w_newImageFont(lua_State *L) { + luax_checkgraphicscreated(L); + // filter for glyphs Texture::Filter filter = instance()->getDefaultFilter(); @@ -483,6 +498,8 @@ int w_newImageFont(lua_State *L) int w_newSpriteBatch(lua_State *L) { + luax_checkgraphicscreated(L); + Texture *texture = luax_checktexture(L, 1); int size = (int) luaL_optnumber(L, 2, 1000); Mesh::Usage usage = Mesh::USAGE_DYNAMIC; @@ -505,6 +522,8 @@ int w_newSpriteBatch(lua_State *L) int w_newParticleSystem(lua_State *L) { + luax_checkgraphicscreated(L); + Texture *texture = luax_checktexture(L, 1); lua_Number size = luaL_optnumber(L, 2, 1000); ParticleSystem *t = 0; @@ -522,6 +541,8 @@ int w_newParticleSystem(lua_State *L) int w_newCanvas(lua_State *L) { + luax_checkgraphicscreated(L); + // check if width and height are given. else default to screen dimensions. int width = (int) luaL_optnumber(L, 1, instance()->getWidth()); int height = (int) luaL_optnumber(L, 2, instance()->getHeight()); @@ -547,6 +568,8 @@ int w_newCanvas(lua_State *L) int w_newShader(lua_State *L) { + luax_checkgraphicscreated(L); + // clamp stack to 2 elements lua_settop(L, 2); @@ -848,6 +871,8 @@ static Mesh *newCustomMesh(lua_State *L) int w_newMesh(lua_State *L) { + luax_checkgraphicscreated(L); + // Check first argument: table or number of vertices. int arg1type = lua_type(L, 1); if (arg1type != LUA_TTABLE && arg1type != LUA_TNUMBER) @@ -868,6 +893,8 @@ int w_newMesh(lua_State *L) int w_newText(lua_State *L) { + luax_checkgraphicscreated(L); + Font *font = luax_checkfont(L, 1); Text *t = nullptr; @@ -888,6 +915,8 @@ int w_newText(lua_State *L) int w_newVideo(lua_State *L) { + luax_checkgraphicscreated(L); + if (!luax_istype(L, 1, VIDEO_VIDEO_STREAM_ID)) luax_convobj(L, 1, "video", "newVideoStream"); diff --git a/src/modules/keyboard/sdl/Keyboard.cpp b/src/modules/keyboard/sdl/Keyboard.cpp index 9cb27c917..84219a0b3 100644 --- a/src/modules/keyboard/sdl/Keyboard.cpp +++ b/src/modules/keyboard/sdl/Keyboard.cpp @@ -55,6 +55,7 @@ bool Keyboard::isDown(const std::vector &keylist) const for (Key key : keylist) { SDL_Scancode scancode = SDL_GetScancodeFromKey(keymap[key]); + if (state[scancode]) return true; } @@ -68,11 +69,9 @@ bool Keyboard::isScancodeDown(const std::vector &scancodelist) const for (Scancode scancode : scancodelist) { - SDL_Scancode sdlscancode = SDL_SCANCODE_UNKNOWN; - if (!scancodes.find(scancode, sdlscancode)) - continue; + SDL_Scancode sdlcode = SDL_SCANCODE_UNKNOWN; - if (state[sdlscancode]) + if (scancodes.find(scancode, sdlcode) && state[sdlcode]) return true; } diff --git a/src/modules/physics/box2d/MotorJoint.cpp b/src/modules/physics/box2d/MotorJoint.cpp index 152502688..3902fe38b 100644 --- a/src/modules/physics/box2d/MotorJoint.cpp +++ b/src/modules/physics/box2d/MotorJoint.cpp @@ -42,7 +42,7 @@ MotorJoint::MotorJoint(Body *body1, Body *body2) joint = (b2MotorJoint *) createJoint(&def); } -MotorJoint::MotorJoint(Body *body1, Body *body2, float correctionFactor) +MotorJoint::MotorJoint(Body *body1, Body *body2, float correctionFactor, bool collideConnected) : Joint(body1, body2) , joint(NULL) { @@ -50,6 +50,7 @@ MotorJoint::MotorJoint(Body *body1, Body *body2, float correctionFactor) def.Initialize(body1->body, body2->body); def.correctionFactor = correctionFactor; + def.collideConnected = collideConnected; joint = (b2MotorJoint *) createJoint(&def); } diff --git a/src/modules/physics/box2d/MotorJoint.h b/src/modules/physics/box2d/MotorJoint.h index ac4ad65f1..69d9432ee 100644 --- a/src/modules/physics/box2d/MotorJoint.h +++ b/src/modules/physics/box2d/MotorJoint.h @@ -41,7 +41,7 @@ class MotorJoint : public Joint public: MotorJoint(Body *body1, Body* body2); - MotorJoint(Body *body1, Body* body2, float correctionFactor); + MotorJoint(Body *body1, Body* body2, float correctionFactor, bool collideConnected); virtual ~MotorJoint(); /// Set/get the target linear offset, in frame A, in meters. diff --git a/src/modules/physics/box2d/Physics.cpp b/src/modules/physics/box2d/Physics.cpp index 99c1c9125..8673c1ada 100644 --- a/src/modules/physics/box2d/Physics.cpp +++ b/src/modules/physics/box2d/Physics.cpp @@ -268,9 +268,9 @@ MotorJoint *Physics::newMotorJoint(Body *body1, Body *body2) return new MotorJoint(body1, body2); } -MotorJoint *Physics::newMotorJoint(Body *body1, Body *body2, float correctionFactor) +MotorJoint *Physics::newMotorJoint(Body *body1, Body *body2, float correctionFactor, bool collideConnected) { - return new MotorJoint(body1, body2, correctionFactor); + return new MotorJoint(body1, body2, correctionFactor, collideConnected); } diff --git a/src/modules/physics/box2d/Physics.h b/src/modules/physics/box2d/Physics.h index 92db477ae..113506379 100644 --- a/src/modules/physics/box2d/Physics.h +++ b/src/modules/physics/box2d/Physics.h @@ -257,7 +257,7 @@ public: * and body2. **/ MotorJoint *newMotorJoint(Body *body1, Body *body2); - MotorJoint *newMotorJoint(Body *body1, Body *body2, float correctionFactor); + MotorJoint *newMotorJoint(Body *body1, Body *body2, float correctionFactor, bool collideConnected); /** * Creates a new Fixture attaching shape to body. diff --git a/src/modules/physics/box2d/wrap_Physics.cpp b/src/modules/physics/box2d/wrap_Physics.cpp index 18fc49eeb..ef6327c67 100644 --- a/src/modules/physics/box2d/wrap_Physics.cpp +++ b/src/modules/physics/box2d/wrap_Physics.cpp @@ -419,8 +419,9 @@ int w_newMotorJoint(lua_State *L) if (!lua_isnoneornil(L, 3)) { float correctionFactor = (float)luaL_checknumber(L, 3); + bool collideConnected = luax_optboolean(L, 4, false); luax_catchexcept(L, [&]() { - j = instance()->newMotorJoint(body1, body2, correctionFactor); + j = instance()->newMotorJoint(body1, body2, correctionFactor, collideConnected); }); } else diff --git a/src/modules/thread/Channel.cpp b/src/modules/thread/Channel.cpp index e86d018bf..e36e69db7 100644 --- a/src/modules/thread/Channel.cpp +++ b/src/modules/thread/Channel.cpp @@ -88,12 +88,6 @@ Channel::Channel(const std::string &name) Channel::~Channel() { - while (!queue.empty()) - { - queue.front()->release(); - queue.pop(); - } - delete mutex; delete cond; @@ -101,13 +95,9 @@ Channel::~Channel() namedChannels.erase(name); } -unsigned long Channel::push(Variant *var) +unsigned long Channel::push(const Variant &var) { - if (!var) - return 0; - Lock l(mutex); - var->retain(); // Keep a reference to ourselves // if we're non-empty and named. @@ -120,11 +110,8 @@ unsigned long Channel::push(Variant *var) return ++sent; } -void Channel::supply(Variant *var) +void Channel::supply(const Variant &var) { - if (!var) - return; - Lock l(mutex); unsigned long id = push(var); @@ -132,13 +119,14 @@ void Channel::supply(Variant *var) cond->wait(mutex); } -Variant *Channel::pop() +bool Channel::pop(Variant *var) { Lock l(mutex); - if (queue.empty()) - return 0; - Variant *var = queue.front(); + if (queue.empty()) + return false; + + *var = queue.front(); queue.pop(); received++; @@ -149,28 +137,26 @@ Variant *Channel::pop() if (named && queue.empty()) release(); - return var; -} // NOTE: Returns a retained Variant - -Variant *Channel::demand() -{ - Variant *var; - Lock l(mutex); - while (!(var = pop())) - cond->wait(mutex); - - return var; + return true; } -Variant *Channel::peek() +void Channel::demand(Variant *var) { Lock l(mutex); - if (queue.empty()) - return 0; - Variant *var = queue.front(); - var->retain(); - return var; + while (!pop(var)) + cond->wait(mutex); +} + +bool Channel::peek(Variant *var) +{ + Lock l(mutex); + + if (queue.empty()) + return false; + + *var = queue.front(); + return true; } int Channel::getCount() @@ -188,10 +174,7 @@ void Channel::clear() return; while (!queue.empty()) - { - queue.front()->release(); queue.pop(); - } // Finish all the supply waits received = sent; diff --git a/src/modules/thread/Channel.h b/src/modules/thread/Channel.h index d034ef095..b7ddedc74 100644 --- a/src/modules/thread/Channel.h +++ b/src/modules/thread/Channel.h @@ -37,8 +37,6 @@ namespace thread class Channel : public love::Object { // FOR WRAPPER USE ONLY -friend void retainVariant(Channel *, Variant *); -friend void releaseVariant(Channel *, Variant *); friend int w_Channel_performAtomic(lua_State *); public: @@ -48,11 +46,11 @@ public: static Channel *getChannel(const std::string &name); - unsigned long push(Variant *var); - void supply(Variant *var); // blocking push - Variant *pop(); - Variant *demand(); // blocking pop - Variant *peek(); + unsigned long push(const Variant &var); + void supply(const Variant &var); // blocking push + bool pop(Variant *var); + void demand(Variant *var); // blocking pop + bool peek(Variant *var); int getCount(); void clear(); @@ -67,7 +65,7 @@ private: Mutex *mutex; Conditional *cond; - std::queue queue; + std::queue queue; bool named; std::string name; diff --git a/src/modules/thread/LuaThread.cpp b/src/modules/thread/LuaThread.cpp index c61594fda..0c5b096ae 100644 --- a/src/modules/thread/LuaThread.cpp +++ b/src/modules/thread/LuaThread.cpp @@ -33,18 +33,12 @@ namespace thread LuaThread::LuaThread(const std::string &name, love::Data *code) : code(code) , name(name) - , args(nullptr) - , nargs(0) { threadName = name; } LuaThread::~LuaThread() { - // No args should still exist at this point, - // but you never know. - for (int i = 0; i < nargs; ++i) - args[i]->release(); } void LuaThread::threadFunction() @@ -74,16 +68,12 @@ void LuaThread::threadFunction() error = luax_tostring(L, -1); else { - int pushedargs = nargs; - for (int i = 0; i < nargs; ++i) - { - args[i]->toLua(L); - args[i]->release(); - } - // Set both args and nargs to nil, prevents the deconstructor from - // accessing it again. - nargs = 0; - args = nullptr; + int pushedargs = (int) args.size(); + + for (int i = 0; i < pushedargs; i++) + args[i].toLua(L); + + args.clear(); if (lua_pcall(L, pushedargs, 0, 0) != 0) error = luax_tostring(L, -1); @@ -97,14 +87,9 @@ void LuaThread::threadFunction() this->release(); } -bool LuaThread::start(Variant **args, int nargs) +bool LuaThread::start(const std::vector &args) { - for (int i = 0; i < this->nargs; ++i) - this->args[i]->release(); - this->args = args; - this->nargs = nargs; - return Threadable::start(); } @@ -126,16 +111,12 @@ void LuaThread::onError() p.type = THREAD_THREAD_ID; p.object = this; - std::vector> vargs = { - new Variant(THREAD_THREAD_ID, &p), - new Variant(error.c_str(), error.length()) + std::vector vargs = { + Variant(p.type, &p), + Variant(error.c_str(), error.length()) }; event::Message *msg = new event::Message("threaderror", vargs); - - for (const StrongRef &v : vargs) - v->release(); - eventmodule->push(msg); msg->release(); } diff --git a/src/modules/thread/LuaThread.h b/src/modules/thread/LuaThread.h index be8c1b84e..a3ce4729a 100644 --- a/src/modules/thread/LuaThread.h +++ b/src/modules/thread/LuaThread.h @@ -23,6 +23,7 @@ // STL #include +#include // LOVE #include "common/Data.h" @@ -44,7 +45,7 @@ public: void threadFunction(); const std::string &getError() const; - bool start(Variant **args, int nargs); + bool start(const std::vector &args); private: @@ -54,8 +55,7 @@ private: std::string name; std::string error; - Variant **args; - int nargs; + std::vector args; }; // LuaThread diff --git a/src/modules/thread/wrap_Channel.cpp b/src/modules/thread/wrap_Channel.cpp index 0885e319b..ff11fb304 100644 --- a/src/modules/thread/wrap_Channel.cpp +++ b/src/modules/thread/wrap_Channel.cpp @@ -25,20 +25,6 @@ namespace love namespace thread { -void retainVariant(Channel *c, Variant *v) -{ - c->lockMutex(); - v->retain(); - c->unlockMutex(); -} - -void releaseVariant(Channel *c, Variant *v) -{ - c->lockMutex(); - v->release(); - c->unlockMutex(); -} - Channel *luax_checkchannel(lua_State *L, int idx) { return luax_checktype(L, idx, THREAD_CHANNEL_ID); @@ -47,34 +33,29 @@ Channel *luax_checkchannel(lua_State *L, int idx) int w_Channel_push(lua_State *L) { Channel *c = luax_checkchannel(L, 1); - Variant *var = lua_isnoneornil(L, 2) ? 0 : Variant::fromLua(L, 2); - if (!var) + Variant var; + if (!Variant::fromLua(L, 2, &var)) return luaL_argerror(L, 2, "boolean, number, string, love type, or flat table expected"); c->push(var); - releaseVariant(c, var); return 0; } int w_Channel_supply(lua_State *L) { Channel *c = luax_checkchannel(L, 1); - Variant *var = lua_isnoneornil(L, 2) ? 0 : Variant::fromLua(L, 2); - if (!var) + Variant var; + if (!Variant::fromLua(L, 2, &var)) return luaL_argerror(L, 2, "boolean, number, string, love type, or flat table expected"); c->supply(var); - releaseVariant(c, var); return 0; } int w_Channel_pop(lua_State *L) { Channel *c = luax_checkchannel(L, 1); - Variant *var = c->pop(); - if (var) - { - var->toLua(L); - releaseVariant(c, var); - } + Variant var; + if (c->pop(&var)) + var.toLua(L); else lua_pushnil(L); return 1; @@ -83,21 +64,18 @@ int w_Channel_pop(lua_State *L) int w_Channel_demand(lua_State *L) { Channel *c = luax_checkchannel(L, 1); - Variant *var = c->demand(); - var->toLua(L); - releaseVariant(c, var); + Variant var; + c->demand(&var); + var.toLua(L); return 1; } int w_Channel_peek(lua_State *L) { Channel *c = luax_checkchannel(L, 1); - Variant *var = c->peek(); - if (var) - { - var->toLua(L); - releaseVariant(c, var); - } + Variant var; + if (c->peek(&var)) + var.toLua(L); else lua_pushnil(L); return 1; diff --git a/src/modules/thread/wrap_LuaThread.cpp b/src/modules/thread/wrap_LuaThread.cpp index ee2e4d6a0..9fe432047 100644 --- a/src/modules/thread/wrap_LuaThread.cpp +++ b/src/modules/thread/wrap_LuaThread.cpp @@ -33,26 +33,22 @@ LuaThread *luax_checkthread(lua_State *L, int idx) int w_Thread_start(lua_State *L) { LuaThread *t = luax_checkthread(L, 1); + std::vector args; int nargs = lua_gettop(L) - 1; - Variant **args = 0; - if (nargs > 0) + Variant v; + for (int i = 0; i < nargs; ++i) { - args = new Variant*[nargs]; - for (int i = 0; i < nargs; ++i) + if (!Variant::fromLua(L, i+2, &v)) { - args[i] = Variant::fromLua(L, i+2); - if (!args[i]) - { - for (int j = i; j >= 0; j--) - delete args[j]; - delete[] args; - return luaL_argerror(L, i+2, "boolean, number, string, love type, or flat table expected"); - } + args.clear(); + return luaL_argerror(L, i+2, "boolean, number, string, love type, or flat table expected"); } + + args.push_back(v); } - luax_pushboolean(L, t->start(args, nargs)); + luax_pushboolean(L, t->start(args)); return 1; }