diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b081e684aa..518e3087fa 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -3,6 +3,7 @@ on: [push, pull_request] env: HAXE_VERSION: 4.2.5 + HXCPP_COMPILE_CACHE: ${{ github.workspace }}/.hxcpp_cache jobs: @@ -10,7 +11,7 @@ jobs: runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: submodules: true @@ -34,10 +35,7 @@ jobs: haxelib install ../hxcpp-4.3.45.zip --quiet haxelib install format --quiet haxelib install hxp --quiet - - - name: Enable HXCPP compile cache - run: | - echo "HXCPP_COMPILE_CACHE=~/.hxcpp" >> $GITHUB_ENV + haxelib install utest --quiet - name: Rebuild Lime tools run: | @@ -47,11 +45,11 @@ jobs: - name: Rebuild Lime (Linux) run: | - lime rebuild linux -32 -release -nocolor -verbose -nocffi - lime rebuild linux -64 -release -nocolor -verbose -nocffi + lime rebuild linux -32 -clean -release -nocolor -verbose -nocffi + lime rebuild linux -64 -clean -release -nocolor -verbose -nocffi lime rebuild hl -clean -release -nocolor -verbose -nocffi - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: Linux-NDLL path: | @@ -59,7 +57,7 @@ jobs: !**/.gitignore if-no-files-found: error - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: Linux64-NDLL path: | @@ -67,13 +65,20 @@ jobs: !**/.gitignore if-no-files-found: error - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: Linux64-Hashlink path: | templates/bin/hl/Linux64 if-no-files-found: error + - name: Run unit tests + working-directory: tests/unit + run: | + lime test neko -release -verbose -nocolor + lime test hl -release -verbose -nocolor + lime test linux -release -verbose -nocolor + - name: Install samples run: | haxelib git lime-samples https://github.com/openfl/lime-samples --quiet @@ -97,7 +102,7 @@ jobs: runs-on: ubuntu-22.04-arm steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: submodules: true @@ -128,6 +133,7 @@ jobs: haxelib install ../hxcpp-4.3.45.zip --quiet haxelib install format --quiet haxelib install hxp --quiet + haxelib install utest --quiet - name: Enable HXCPP compile cache run: | @@ -141,9 +147,9 @@ jobs: - name: Rebuild Lime (Linux ARM64) run: | - lime rebuild linux -release -nocolor -verbose -nocffi + lime rebuild linux -clean -release -nocolor -verbose -nocffi - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: LinuxArm64-NDLL path: | @@ -151,6 +157,12 @@ jobs: !**/.gitignore if-no-files-found: error + - name: Run unit tests + working-directory: tests/unit + run: | + lime test neko -release -verbose -nocolor + lime test linux -release -verbose -nocolor + - name: Install samples run: | haxelib git lime-samples https://github.com/openfl/lime-samples --quiet @@ -174,7 +186,7 @@ jobs: runs-on: macos-14 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: submodules: true @@ -205,10 +217,7 @@ jobs: haxelib install ../hxcpp-4.3.45.zip --quiet haxelib install format --quiet haxelib install hxp --quiet - - - name: Enable HXCPP compile cache - run: | - echo "HXCPP_COMPILE_CACHE=~/.hxcpp" >> $GITHUB_ENV + haxelib install utest --quiet - name: Rebuild Lime tools run: | @@ -222,7 +231,7 @@ jobs: lime rebuild macos -clean -release -arm64 -nocolor -verbose -nocffi lime rebuild hl -clean -release -nocolor -verbose -nocffi - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: Mac64-NDLL path: | @@ -230,7 +239,7 @@ jobs: !**/.gitignore if-no-files-found: error - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: MacArm64-NDLL path: | @@ -238,13 +247,20 @@ jobs: !**/.gitignore if-no-files-found: error - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: Mac64-Hashlink path: | templates/bin/hl/Mac64 if-no-files-found: error + - name: Run unit tests + working-directory: tests/unit + run: | + lime test neko -release -verbose -nocolor + lime test hl -release -verbose -nocolor + lime test mac -release -verbose -nocolor + - name: Install samples run: | haxelib git lime-samples https://github.com/openfl/lime-samples --quiet @@ -268,7 +284,7 @@ jobs: runs-on: windows-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: submodules: true @@ -276,6 +292,11 @@ jobs: with: haxe-version: ${{ env.HAXE_VERSION }} + - uses: joshtynjala/setup-adobe-air-action@v2 + with: + air-version: "33.1" + accept-license: true + - name: Set HAXEPATH run: | echo "HAXEPATH=$Env:HAXE_STD_PATH\.." >> $Env:GITHUB_ENV @@ -286,24 +307,22 @@ jobs: haxelib install ../hxcpp-4.3.45.zip --quiet haxelib install format --quiet haxelib install hxp --quiet - - - name: Enable HXCPP compile cache - run: | - echo "HXCPP_COMPILE_CACHE=C:\.hxcpp" >> $Env:GITHUB_ENV + haxelib install utest --quiet - name: Rebuild Lime tools run: | haxelib dev lime ${{ github.workspace }} haxelib run lime rebuild tools -nocolor -verbose -nocffi haxelib run lime setup -alias -y -nocffi + haxelib run lime config AIR_SDK ${{ env.AIR_HOME }} -eval - name: Rebuild Lime (Windows) run: | - lime rebuild windows -32 -release -nocolor -verbose -nocffi - lime rebuild windows -64 -release -nocolor -verbose -nocffi + lime rebuild windows -32 -clean -release -nocolor -verbose -nocffi + lime rebuild windows -64 -clean -release -nocolor -verbose -nocffi lime rebuild hl -clean -release -nocolor -verbose -nocffi - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: Windows-NDLL path: | @@ -311,7 +330,7 @@ jobs: !**/.gitignore if-no-files-found: error - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: Windows64-NDLL path: | @@ -319,19 +338,27 @@ jobs: !**/.gitignore if-no-files-found: error - # - uses: actions/upload-artifact@v4 + # - uses: actions/upload-artifact@v7 # with: # name: Windows-Hashlink # path: | # templates/bin/hl/Windows # if-no-files-found: error - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: Windows64-Hashlink path: | templates/bin/hl/Windows64 if-no-files-found: error + - name: Run unit tests + working-directory: tests/unit + run: | + lime test neko -release -verbose -nocolor + lime test hl -release -verbose -nocolor + lime test air -release -verbose -nocolor + lime test windows -release -verbose -nocolor + - name: Install samples run: | haxelib git lime-samples https://github.com/openfl/lime-samples --quiet @@ -356,7 +383,7 @@ jobs: rm ndll/Windows64/* lime rebuild windows -Dmingw -D MINGW_ROOT=C:\mingw64 -64 -clean -release -nocolor -verbose -nocffi - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: Windows64-MinGW-NDLL path: | @@ -372,7 +399,7 @@ jobs: fail-fast: false steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: submodules: true @@ -383,7 +410,7 @@ jobs: with: ndk-version: ${{ matrix.ndk-version }} - - uses: actions/setup-java@v4 + - uses: actions/setup-java@v5 with: distribution: "zulu" java-version: 17 @@ -403,10 +430,6 @@ jobs: haxelib install format --quiet haxelib install hxp --quiet - - name: Enable HXCPP compile cache - run: | - echo "HXCPP_COMPILE_CACHE=~/.hxcpp" >> $GITHUB_ENV - - name: Prepare Lime run: | haxelib dev lime ${{ github.workspace }} @@ -426,7 +449,7 @@ jobs: run: | lime rebuild android -release -nocolor -verbose -nocffi -eval - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: Android-NDLL path: | @@ -457,7 +480,7 @@ jobs: runs-on: macos-14 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: submodules: true @@ -476,10 +499,6 @@ jobs: haxelib install format --quiet haxelib install hxp --quiet - - name: Enable HXCPP compile cache - run: | - echo "HXCPP_COMPILE_CACHE=~/.hxcpp" >> $GITHUB_ENV - - name: Prepare Lime run: | haxelib dev lime ${{ github.workspace }} @@ -489,7 +508,7 @@ jobs: run: | lime rebuild ios -clean -release -verbose -nocolor -eval - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: iPhone-NDLL path: | @@ -521,7 +540,7 @@ jobs: runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: submodules: true @@ -542,10 +561,6 @@ jobs: haxelib install svg --quiet haxelib install openfl --quiet - - name: Enable HXCPP compile cache - run: | - echo "HXCPP_COMPILE_CACHE=~/.hxcpp" >> $GITHUB_ENV - - name: Rebuild Lime tools run: | haxelib dev lime ${{ github.workspace }} @@ -557,62 +572,62 @@ jobs: cp project/lib/hashlink/src/hl.h templates/bin/hl/include/hl.h cp project/lib/hashlink/src/hlc_main.c templates/bin/hl/include/hlc_main.c - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v8 with: name: Android-NDLL path: ndll/Android/ - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v8 with: name: iPhone-NDLL path: ndll/iPhone/ - # - uses: actions/download-artifact@v4 + # - uses: actions/download-artifact@v8 # with: # name: Linux-NDLL # path: ndll/Linux/ - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v8 with: name: Linux64-NDLL path: ndll/Linux64/ - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v8 with: name: Mac64-NDLL path: ndll/Mac64/ - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v8 with: name: MacArm64-NDLL path: ndll/MacArm64/ - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v8 with: name: Windows-NDLL path: ndll/Windows/ - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v8 with: name: Windows64-NDLL path: ndll/Windows64/ - # - uses: actions/download-artifact@v4 + # - uses: actions/download-artifact@v8 # with: # name: Windows-Hashlink # path: templates/bin/hl/Windows - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v8 with: name: Windows64-Hashlink path: templates/bin/hl/Windows64 - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v8 with: name: Mac64-Hashlink path: templates/bin/hl/Mac64 - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v8 with: name: Linux64-Hashlink path: templates/bin/hl/Linux64 @@ -627,7 +642,7 @@ jobs: run: | haxe svg.hxml - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: lime-haxelib path: | @@ -636,13 +651,14 @@ jobs: !haxe-*-*/ !neko-*-*/ !.git/ + compression-level: 9 if-no-files-found: error docs: runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - uses: krdlab/setup-haxe@v2 with: @@ -662,7 +678,7 @@ jobs: run: | haxe build.hxml - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: lime-docs path: docs/pages @@ -672,7 +688,7 @@ jobs: runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - uses: krdlab/setup-haxe@v2 with: @@ -715,7 +731,7 @@ jobs: haxe-version: [4.0.5, 4.1.5, 4.2.5, 4.3.6] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: submodules: true @@ -786,7 +802,7 @@ jobs: run: | haxelib git lime-samples https://github.com/openfl/lime-samples --quiet - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v8 with: name: lime-haxelib path: lime-haxelib @@ -836,7 +852,7 @@ jobs: run: | haxelib git lime-samples https://github.com/openfl/lime-samples --quiet - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v8 with: name: lime-haxelib path: lime-haxelib @@ -869,7 +885,7 @@ jobs: haxe-version: [3.4.7, 4.0.5, 4.1.5, 4.2.5, 4.3.6] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - uses: krdlab/setup-haxe@v2 with: @@ -884,7 +900,7 @@ jobs: haxelib install genes --quiet haxelib git lime-samples https://github.com/openfl/lime-samples --quiet - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v8 with: name: lime-haxelib path: lime-haxelib @@ -953,7 +969,7 @@ jobs: run: | haxelib git lime-samples https://github.com/openfl/lime-samples --quiet - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v8 with: name: lime-haxelib path: lime-haxelib diff --git a/.gitignore b/.gitignore index 37e1b844d6..f7090b0ddc 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,4 @@ package-lock.json node_modules !templates/**/node_modules .vscode/ +tests/**/bin/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b508f05bc..93cd071c24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,336 +1,360 @@ Changelog ========= +8.3.1 (02/16/2026) +------------------ + +- Added validation for `ANDROID_SDK`, `ANDROID_NDK_ROOT`, `JAVA_HOME` and `AIR_SDK` paths to ensure that they exist and are directories. +- Added verbose log message when rebuilding a Haxelib's tools to show the name of the Haxelib. +- Added warning log message when rebuilding a Haxelib's tools when no rebuild script is found. +- Added warning log message when `` value is unrecognized. +- Added error when attemping to rebuild HashLink for ARM64. +- Added internal exception message to error reported when NDLL loading fails. +- Fixed exception on some targets in `AudioBuffer` when trying to read codec signature string from bytes. +- Fixed `length` value of `Bytes` on HTML5 target when using `Bytes.fromBytes()`. +- Fixed _lime.ndll_ build on systems with GCC 15 compiler. +- Fixed _lime.ndll_ build on ARM64 Linux distributions other than Raspberry Pi OS. +- Fixed `--no-output` behavior in Android build that exited before all architectures were handled. +- Fixed `JNISafety` to make it safe for macro context. +- Fixed warnings when building pixman with Android NDKs before r22. +- Fixed _lime.ndll_ build when using MinGW compiler. +- Fixed format of `PLATFORM` define for Android. +- Fixed support for spaces in paths when building for iOS or tvOS. +- Fixed DCE incorrectly disabling orientation change listeners on Android. +- Fixed value of `context.attributes.hardware` for `HTML5Window` when creating context. +- Fixed SDL submodule build for some Linux distributions including Raspberry Pi OS. +- Fixed emulated `sys.io.File` on Adobe AIR to use `File.workingDirectory` for relative paths, if available. + 8.3.0 (11/11/2025) ------------------ -* Added `onDisplayOrientation` and `onDeviceOrientation` events to `Application` to detect mobile device orientation changes. -* Added `safeArea` property to `Display` to detect region safe from cutouts and rounded corners. -* Added `rumble()` method to `Gamepad`. -* Added `-json` flag, which works similarly to the `-xml` flag, but outputs types in JSON format. -* Added `layoutInDisplayCutoutMode` to ``, which may be set to `default`, `always`, `never`, or `shortEdges`. -* Added support for Windows resource file to set metadata in executable. -* Added `pannerAttr()` method to `Howler` to configure panner node's attributes for a sound or group of sounds. -* Added `addString()` method to `HBBuffer` to properly handle encoding conversions in native code. -* Added `screensize` and `screenDPI` to `` to customize the mobile simulator. -* Added `onUncaughtError` event to `ThreadPool` to allow main thread to handle exceptions in `doWork`. -* Added `strikethroughPosition` and `strikethroughThickness` to `Font`. -* Added separate `lime-openalsoft` and `lime-mojoal` defines to help detect which library is used. -* Added `gradle-properties` to `` to customize properties for Android Gradle builds. -* Fixed missing `hl-ver` define to configure the Haxe compiler to target Lime's bundled HashLink (unless a custom `HL_PATH` is set). -* Fixed display of preload progress for packed asset libraries. -* Fixed mouse move and mouse up event failing to dispatch outside window bounds when mouse button is down. -* Fixed `hardware` attribute not being set on context creation. -* Fixed some window properties not getting set properly from attributes on window creation. -* Fixed performance issues in `ThreadPool` by overhauling job scheduling. -* Fixed exception on Windows when exiting program by using `SDL_QuitSubSystem` in native code. -* Fixed separate private variables for `visible` and `hidden` that got out of sync. -* Fixed crash on HashLink when passing `NULL` device to OpenAL bindings. -* Fixed many variables that defaulted to `Dynamic` because they did not declare a type and were not initialized. -* Fixed `ThreadPool` throwing an exception when `Application.current` is `null`. -* Fixed old _run.n_ in Haxelib because the CI server did not build it. -* Changed Android rebuild to use NDK r28c for Haxelib to support new 16KB native library aligment requirement. -* Changed Android target SDK version to 35. May require updating to JDK 17 or newer. -* Changed default Android architecture for x86 from x86_32 to x86_64 (can still rebuild x86_32 manually). -* Changed default Android emulator architectures to include ARM64 to better support ARM64 on macOS. -* Changed default Adobe AIR SDK version from 28.0 to 32.0 because 28.0 is no longer available for download from Adobe. -* Changed `minimum-sdk-version` in `` to customize the `PLATFORM` or `PLATFORM_NUMBER` values used by Android builds. -* Changed _index.html_ template to use `mobile-web-app-capable` instead of deprecated `apple-mobile-web-app-capable`. -* Removed Linux x86_32 binaries from Haxelib (but can still rebuild them manually). -* Removed custom implementation of `haxe.io.Bytes`. -* Updated bundled HashLink executable version to 1.14. -* Updated SDL submodule to version 2.30.12. +- Added `onDisplayOrientation` and `onDeviceOrientation` events to `Application` to detect mobile device orientation changes. +- Added `safeArea` property to `Display` to detect region safe from cutouts and rounded corners. +- Added `rumble()` method to `Gamepad`. +- Added `-json` flag, which works similarly to the `-xml` flag, but outputs types in JSON format. +- Added `layoutInDisplayCutoutMode` to ``, which may be set to `default`, `always`, `never`, or `shortEdges`. +- Added support for Windows resource file to set metadata in executable. +- Added `pannerAttr()` method to `Howler` to configure panner node's attributes for a sound or group of sounds. +- Added `addString()` method to `HBBuffer` to properly handle encoding conversions in native code. +- Added `screensize` and `screenDPI` to `` to customize the mobile simulator. +- Added `onUncaughtError` event to `ThreadPool` to allow main thread to handle exceptions in `doWork`. +- Added `strikethroughPosition` and `strikethroughThickness` to `Font`. +- Added separate `lime-openalsoft` and `lime-mojoal` defines to help detect which library is used. +- Added `gradle-properties` to `` to customize properties for Android Gradle builds. +- Fixed missing `hl-ver` define to configure the Haxe compiler to target Lime's bundled HashLink (unless a custom `HL_PATH` is set). +- Fixed display of preload progress for packed asset libraries. +- Fixed mouse move and mouse up event failing to dispatch outside window bounds when mouse button is down. +- Fixed `hardware` attribute not being set on context creation. +- Fixed some window properties not getting set properly from attributes on window creation. +- Fixed performance issues in `ThreadPool` by overhauling job scheduling. +- Fixed exception on Windows when exiting program by using `SDL_QuitSubSystem` in native code. +- Fixed separate private variables for `visible` and `hidden` that got out of sync. +- Fixed crash on HashLink when passing `NULL` device to OpenAL bindings. +- Fixed many variables that defaulted to `Dynamic` because they did not declare a type and were not initialized. +- Fixed `ThreadPool` throwing an exception when `Application.current` is `null`. +- Fixed old _run.n_ in Haxelib because the CI server did not build it. +- Changed Android rebuild to use NDK r28c for Haxelib to support new 16KB native library aligment requirement. +- Changed Android target SDK version to 35. May require updating to JDK 17 or newer. +- Changed default Android architecture for x86 from x86_32 to x86_64 (can still rebuild x86_32 manually). +- Changed default Android emulator architectures to include ARM64 to better support ARM64 on macOS. +- Changed default Adobe AIR SDK version from 28.0 to 32.0 because 28.0 is no longer available for download from Adobe. +- Changed `minimum-sdk-version` in `` to customize the `PLATFORM` or `PLATFORM_NUMBER` values used by Android builds. +- Changed _index.html_ template to use `mobile-web-app-capable` instead of deprecated `apple-mobile-web-app-capable`. +- Removed Linux x86_32 binaries from Haxelib (but can still rebuild them manually). +- Removed custom implementation of `haxe.io.Bytes`. +- Updated bundled HashLink executable version to 1.14. +- Updated SDL submodule to version 2.30.12. 8.2.3 (10/01/2025) ------------------ -* Fixed JPEG rendering on 32-bit platforms. -* Fixed application hang in `FileDialog` on Windows by forcing `SINGLE_THREADED` flag. -* Fixed iOS device installation on versions older than iOS 16. -* Fixed how iOS 16 and newer devices are selected for testing to support more available devices. -* Fixed ability to specify the version of a Haxelib when using a local _.haxelib_ repository. -* Fixed exception when initializing vibration on Android and permission was disabled. -* Fixed parent directory incorrectly opened in `FileDialog` if the default path is a directory. -* Fixed Unicode system path conversions on Linux. -* Fixed `password`, `alias`, and `aliasPassword` being assigned incorrectly in Lime tools. -* Fixed crash in `AudioManager` when `alc.openDevice()` returns `null`. -* Fixed references to certain types for stricter rules in Haxe 5. -* Fixed `FFECT_AUTOWAH` typo by adding correct `EFFECT_AUTOWAH` value. -* Fixed exception in `HTML5HTTPRequest` in some environments when `request.upload` is `null`. -* Fixed `EXC_BAD_ACCESS` when decoding PNGs and the bytes are `null` or length is `0`. -* Fixed iOS app sometimes running in iPhone simulator when `` is specified. -* Fixed iOS app sometimes not starting in simulator by recognizing more valid simulator IDs. -* Fixed incorrect request for confirmation when `-alias` or `-cli` flags are specified. -* Fixed conversions between key codes and scan codes in both directions. -* Fixed memory leak in cURL bindings from header values not getting freed. -* Added `CURLOPT_ACCEPT_ENCODING` option for native HTTP requests. -* Fixed missing macos define when using cpp target on macOS. -* Fixed compatibility with Haxe 3 in `HTML5Thread` and Lime tools. -* Fixed failed static build linking on Windows caused by missing _.lib_ file. -* Fixed failed static builds caused by conflicts between hxcpp's and Lime's mbedtls versions. -* Fixed missing UTF-8 conversion in `hb_buffer_add_utf8`. -* Fixed `Font.getGlyphs()` returning an array of zeroes on HashLink. -* Fixed `Font.getGlyphs()` getting stuck in an infinite loop on encountering an invalid character. -* Fixed `System.getDirectory()` UTF-16 encoding. -* Fixed error not getting displayed when NDK 20 or newer is required for Android. -* Fixed OpenAL Soft build on Android by adding `-std=c++11` option. -* Fixed deprecation warning on Android caused by using deprecated no-arg constructor in `android.os.Handler`. -* Fixed unnecessary `untyped __js__` in `ImageCanvasUtil` because externs are now available. -* Fixed crashes when SDL functions return `NULL` on some targets. -* Fixed `Timer.stop()` performing redundant iterations. -* Added `-cli`, `-alias`, and `-noalias` flags to usage instructions. -* Added instructions to use `lime config remove HL_PATH` to clear a custom HashLink version. -* Changed `non-exempt-encryption` default for iOS from `true` to `false`. -* Removed usage of legacy `MAC_USE_CURRENT_SDK` define in Lime tools when targeting macOS. -* Updated Cairo submodule to version 1.18.2 from a snapshot release. -* Updated HarfBuzz submodule to version 10.2.0. -* Updated cURL submodule to version 7.87.0. -* Updated zlib submodule to version 1.2.13. -* Updated png submodule to version 1.6.46. -* Updated efsw submodule to version 1.4.1. -* Updated tinyfiledialogs submodule to version 3.19.1 and fix compatibility with zenity. +- Fixed JPEG rendering on 32-bit platforms. +- Fixed application hang in `FileDialog` on Windows by forcing `SINGLE_THREADED` flag. +- Fixed iOS device installation on versions older than iOS 16. +- Fixed how iOS 16 and newer devices are selected for testing to support more available devices. +- Fixed ability to specify the version of a Haxelib when using a local _.haxelib_ repository. +- Fixed exception when initializing vibration on Android and permission was disabled. +- Fixed parent directory incorrectly opened in `FileDialog` if the default path is a directory. +- Fixed Unicode system path conversions on Linux. +- Fixed `password`, `alias`, and `aliasPassword` being assigned incorrectly in Lime tools. +- Fixed crash in `AudioManager` when `alc.openDevice()` returns `null`. +- Fixed references to certain types for stricter rules in Haxe 5. +- Fixed `FFECT_AUTOWAH` typo by adding correct `EFFECT_AUTOWAH` value. +- Fixed exception in `HTML5HTTPRequest` in some environments when `request.upload` is `null`. +- Fixed `EXC_BAD_ACCESS` when decoding PNGs and the bytes are `null` or length is `0`. +- Fixed iOS app sometimes running in iPhone simulator when `` is specified. +- Fixed iOS app sometimes not starting in simulator by recognizing more valid simulator IDs. +- Fixed incorrect request for confirmation when `-alias` or `-cli` flags are specified. +- Fixed conversions between key codes and scan codes in both directions. +- Fixed memory leak in cURL bindings from header values not getting freed. +- Added `CURLOPT_ACCEPT_ENCODING` option for native HTTP requests. +- Fixed missing macos define when using cpp target on macOS. +- Fixed compatibility with Haxe 3 in `HTML5Thread` and Lime tools. +- Fixed failed static build linking on Windows caused by missing _.lib_ file. +- Fixed failed static builds caused by conflicts between hxcpp's and Lime's mbedtls versions. +- Fixed missing UTF-8 conversion in `hb_buffer_add_utf8`. +- Fixed `Font.getGlyphs()` returning an array of zeroes on HashLink. +- Fixed `Font.getGlyphs()` getting stuck in an infinite loop on encountering an invalid character. +- Fixed `System.getDirectory()` UTF-16 encoding. +- Fixed error not getting displayed when NDK 20 or newer is required for Android. +- Fixed OpenAL Soft build on Android by adding `-std=c++11` option. +- Fixed deprecation warning on Android caused by using deprecated no-arg constructor in `android.os.Handler`. +- Fixed unnecessary `untyped __js__` in `ImageCanvasUtil` because externs are now available. +- Fixed crashes when SDL functions return `NULL` on some targets. +- Fixed `Timer.stop()` performing redundant iterations. +- Added `-cli`, `-alias`, and `-noalias` flags to usage instructions. +- Added instructions to use `lime config remove HL_PATH` to clear a custom HashLink version. +- Changed `non-exempt-encryption` default for iOS from `true` to `false`. +- Removed usage of legacy `MAC_USE_CURRENT_SDK` define in Lime tools when targeting macOS. +- Updated Cairo submodule to version 1.18.2 from a snapshot release. +- Updated HarfBuzz submodule to version 10.2.0. +- Updated cURL submodule to version 7.87.0. +- Updated zlib submodule to version 1.2.13. +- Updated png submodule to version 1.6.46. +- Updated efsw submodule to version 1.4.1. +- Updated tinyfiledialogs submodule to version 3.19.1 and fix compatibility with zenity. 8.2.2 (12/19/2024) ------------------ -* Fixed broken breakpoints in HTML5 debug builds. -* Fixed unecessary operations in `Promise` by inlining some getter functions. -* Fixed failure to read `gradle-plugin` attribute in `` tag. -* Fixed failed installation of app on iOS Simulator by choosing only simulators that are considered available. -* Fixed `lime test ios` to install and launch on a device when using Xcode 16 or newer. -* Fixed reported version of OpenAL library. -* Fixed memory cleanup when encoding PNG and JPEG images. -* Fixed error reporting `@rpath/libhl.dylib` not found on macOS when using HashLink nightly build. -* Fixed building HashLink on macOS that required cleaning between compiles. -* Fixed `embedBytes()` macro incorrectly running when `embedByteArray()` macro was also running. -* Fixed `ImageDataUtil.copyPixels()` causing crash on HashLink. -* Fixed missing `neko` target flag when cross-compiling to Windows without `-mingw` or `-cpp` flags. -* Fixed occasional failure running Lime tools by switching certain paths from relative to absolute. -* Fixed missing warning when `lime rebuild` commands fail because C++ source is not available from Haxelib. -* Fixed command instructions to specify requirement for absolute paths when setting up a platform. -* Added detection of `-cpp` flag when cross-compiling to Windows, which works like `-mingw`. -* Updated FreeType submodule to version 2.12.1 again. Resolved issues encountered when using this version in Lime 8.2.0. +- Fixed broken breakpoints in HTML5 debug builds. +- Fixed unecessary operations in `Promise` by inlining some getter functions. +- Fixed failure to read `gradle-plugin` attribute in `` tag. +- Fixed failed installation of app on iOS Simulator by choosing only simulators that are considered available. +- Fixed `lime test ios` to install and launch on a device when using Xcode 16 or newer. +- Fixed reported version of OpenAL library. +- Fixed memory cleanup when encoding PNG and JPEG images. +- Fixed error reporting `@rpath/libhl.dylib` not found on macOS when using HashLink nightly build. +- Fixed building HashLink on macOS that required cleaning between compiles. +- Fixed `embedBytes()` macro incorrectly running when `embedByteArray()` macro was also running. +- Fixed `ImageDataUtil.copyPixels()` causing crash on HashLink. +- Fixed missing `neko` target flag when cross-compiling to Windows without `-mingw` or `-cpp` flags. +- Fixed occasional failure running Lime tools by switching certain paths from relative to absolute. +- Fixed missing warning when `lime rebuild` commands fail because C++ source is not available from Haxelib. +- Fixed command instructions to specify requirement for absolute paths when setting up a platform. +- Added detection of `-cpp` flag when cross-compiling to Windows, which works like `-mingw`. +- Updated FreeType submodule to version 2.12.1 again. Resolved issues encountered when using this version in Lime 8.2.0. 8.2.1 (11/01/2024) ------------------ -* Fixed `Sys.exit()` causing hang instead of exiting application. -* Fixed paths for _.ndll_ files when targeting Raspberry Pi. -* Fixed compiling `BackgroundWorker` when targeting HashLink before Haxe 4. -* Fixed errors compiling `ThreadPool` for HashLink with Haxe 4.0 and 4.1. -* Fixed `Font.renderGlyph` to support 32-bit colors, including alpha. -* Fixed OpenFL line height issues by rolling back FreeType submodule to version 2.9.1. +- Fixed `Sys.exit()` causing hang instead of exiting application. +- Fixed paths for _.ndll_ files when targeting Raspberry Pi. +- Fixed compiling `BackgroundWorker` when targeting HashLink before Haxe 4. +- Fixed errors compiling `ThreadPool` for HashLink with Haxe 4.0 and 4.1. +- Fixed `Font.renderGlyph` to support 32-bit colors, including alpha. +- Fixed OpenFL line height issues by rolling back FreeType submodule to version 2.9.1. 8.2.0 (10/21/2024) ------------------ -* Added Apple Silicon (ARM64) support for macOS target. -* Added new `hlc` target to support compiling for HashLink/C. Both generates C code and compiles to an executable (requires Haxe 4.3.4 or newer). -* Added support for inserting attributes into the `` or `` elements of _AndroidManifest.xml_ -* Added `createPerspective()` to `Matrix4`. -* Added `removeLibrary()` to `lime.utils.Assets`, which removes a library, but makes unloading optional. -* Added `SINGLE_THREADED` mode to `ThreadPool`, which is used by default when threading is not available. -* Added `workLoad` property to `ThreadPool` to limit total time spent per frame on green threads. -* Added optional `-noalias` flag to `lime setup` to skip creating the **lime** executable alias. -* Added optional `-nosign` flag to `lime build ios` to skip code signing when targeting iOS. -* Added support for `-64` flag to force compiling for 64-bit Raspberry Pi.without requiring a custom template. -* Added option to configure `preserveDrawingBuffer` on HTML5 target. -* Added LZMA compression to HTML5 target. -* Added automatic deletion of "stale" assets and dependency files. -* Added `VIEW` intents on Android target. -* Added support for `-mingw` flag when cross-compiling to Windows from another operating system. -* Added support for `-cpp` flag when cross-compiling to Linux from another operating system (requires homebrew-macos-cross-toolchains on macOS). -* Added support for `tsa` option in `` to pass timestamp URL to Adobe AIR's adt tool. -* Fixed `lime display` command incorrectly printing old _.hxml_ content after _project.xml_ file has been modified, skipping requirement to build project or restart editor to get valid code intelligence. -* Fixed HashLink _.app_ bundles on macOS to include all Homebrew library dependencies, so that they run on computers without Homebrew. -* Fixed `@android:style/Theme.NoTitleBarnull` in generated _AndroidManifest.xml_. -* Fixed `Image` in a web worker by storing it as `DATA` type. -* Fixed cURL C++ to Haxe callbacks when targeting HashLink. -* Fixed icon generation for Android target with `accept-file-intent` config. -* Fixed exception in Lime tools when resolving full path of Neko _.n_ file. -* Fixed keyboard input incorrectly getting enabled by default when creating a new window, which could show an IME when unexpected. -* Fixed `ALC.getContextsDevice()` when targeting HashLink. -* Fixed potentially uninitialized values in `Matrix3`. -* Fixed wrong type for `Socket.objectEncoding` in Flash/AIR externs. -* Fixed `BackgroundWorker` not using threads on HashLink. -* Improved support for Raspberry Pi 64-bit builds. -* Changed custom `haxe.Timer` to fall back to the original in a macro context. -* Changed `Promise` to remove `@:generic` when in a macro context. -* Changed `Matrix3` to be an abstract over `Float32Array`, similar to `Matrix4`. -* Changed Raspberry Pi keyboard shortcut to exit to Ctrl + Esc. -* Changed `-64` and `-32` flags for Intel architectures to `-x86_64` and `-x86_32` to make their purpose more clear (the old flags still work, for now). -* Removed Joystick trackball APIs because they is supported only on Linux, with a single piece of hardware, and will be removed from SDL 3. -* Removed ARMV5 architecture from Android rebuilds by default because hxcpp doesn't support it with NDK versions >= 20. -* Removed 32-bit _liblime.iphonesim.a_ as a default binary because 32-bit iOS is no longer supported by Apple. -* Updated Cairo submodule to version 1.17.6 and point to upstream repository instead of fork. -* Updated cURL submodule to version 7.83.1 and point to upstream repository instead of fork. -* Updated efsw submodule to version 1.2.0 and point to upstream repository instead of fork. -* Updated FreeType submodule to version 2.12.1 and point to upstream repository instead of fork. -* Updated HarfBuzz submodule to version 6.0.0 and point to upstream repository instead of fork. -* Updated libpng submodule to version 1.6.37 and point to upstream repository instead of fork. -* Updated libjpg-turbo submodule to version 2.1.3 and point to upstream repository instead of fork. -* Updated libvpx submodule to version 1.11.0 and point to upstream repository instead of fork. -* Updated libwebm submodule to version 1.0.0.28 and point to upstream repository instead of fork. -* Updated Mbed TLS submodule to version 2.28.7 and point to upstream repository instead of fork. -* Updated MojoAL submodule to commit e08dbf3 and point to upstream repository instead of fork. -* Updated Ogg submodule to version 1.3.5 and point to upstream repository instead of fork. -* Updated OpenAL-Soft submodule to version 1.20.1 and point to upstream repository instead of fork. -* Updated Pixman submodule to version 0.42.2 and point to upstream repository instead of fork. -* Updated SDL submodule to version 2.24.0 and point to upstream repository instead of fork. -* Updated Tinyfiledialogs submodule to version 3.8.8 (still uses fork due to SourceForge limitationss). -* Updated Vorbis submodule to version 1.3.7 and point to upstream repository instead of fork. -* Updated zlib submodule to version 1.2.12 and point to upstream repository instead of fork. +- Added Apple Silicon (ARM64) support for macOS target. +- Added new `hlc` target to support compiling for HashLink/C. Both generates C code and compiles to an executable (requires Haxe 4.3.4 or newer). +- Added support for inserting attributes into the `` or `` elements of _AndroidManifest.xml_ +- Added `createPerspective()` to `Matrix4`. +- Added `removeLibrary()` to `lime.utils.Assets`, which removes a library, but makes unloading optional. +- Added `SINGLE_THREADED` mode to `ThreadPool`, which is used by default when threading is not available. +- Added `workLoad` property to `ThreadPool` to limit total time spent per frame on green threads. +- Added optional `-noalias` flag to `lime setup` to skip creating the **lime** executable alias. +- Added optional `-nosign` flag to `lime build ios` to skip code signing when targeting iOS. +- Added support for `-64` flag to force compiling for 64-bit Raspberry Pi.without requiring a custom template. +- Added option to configure `preserveDrawingBuffer` on HTML5 target. +- Added LZMA compression to HTML5 target. +- Added automatic deletion of "stale" assets and dependency files. +- Added `VIEW` intents on Android target. +- Added support for `-mingw` flag when cross-compiling to Windows from another operating system. +- Added support for `-cpp` flag when cross-compiling to Linux from another operating system (requires homebrew-macos-cross-toolchains on macOS). +- Added support for `tsa` option in `` to pass timestamp URL to Adobe AIR's adt tool. +- Fixed `lime display` command incorrectly printing old _.hxml_ content after _project.xml_ file has been modified, skipping requirement to build project or restart editor to get valid code intelligence. +- Fixed HashLink _.app_ bundles on macOS to include all Homebrew library dependencies, so that they run on computers without Homebrew. +- Fixed `@android:style/Theme.NoTitleBarnull` in generated _AndroidManifest.xml_. +- Fixed `Image` in a web worker by storing it as `DATA` type. +- Fixed cURL C++ to Haxe callbacks when targeting HashLink. +- Fixed icon generation for Android target with `accept-file-intent` config. +- Fixed exception in Lime tools when resolving full path of Neko _.n_ file. +- Fixed keyboard input incorrectly getting enabled by default when creating a new window, which could show an IME when unexpected. +- Fixed `ALC.getContextsDevice()` when targeting HashLink. +- Fixed potentially uninitialized values in `Matrix3`. +- Fixed wrong type for `Socket.objectEncoding` in Flash/AIR externs. +- Fixed `BackgroundWorker` not using threads on HashLink. +- Improved support for Raspberry Pi 64-bit builds. +- Changed custom `haxe.Timer` to fall back to the original in a macro context. +- Changed `Promise` to remove `@:generic` when in a macro context. +- Changed `Matrix3` to be an abstract over `Float32Array`, similar to `Matrix4`. +- Changed Raspberry Pi keyboard shortcut to exit to Ctrl + Esc. +- Changed `-64` and `-32` flags for Intel architectures to `-x86_64` and `-x86_32` to make their purpose more clear (the old flags still work, for now). +- Removed Joystick trackball APIs because they is supported only on Linux, with a single piece of hardware, and will be removed from SDL 3. +- Removed ARMV5 architecture from Android rebuilds by default because hxcpp doesn't support it with NDK versions >= 20. +- Removed 32-bit _liblime.iphonesim.a_ as a default binary because 32-bit iOS is no longer supported by Apple. +- Updated Cairo submodule to version 1.17.6 and point to upstream repository instead of fork. +- Updated cURL submodule to version 7.83.1 and point to upstream repository instead of fork. +- Updated efsw submodule to version 1.2.0 and point to upstream repository instead of fork. +- Updated FreeType submodule to version 2.12.1 and point to upstream repository instead of fork. +- Updated HarfBuzz submodule to version 6.0.0 and point to upstream repository instead of fork. +- Updated libpng submodule to version 1.6.37 and point to upstream repository instead of fork. +- Updated libjpg-turbo submodule to version 2.1.3 and point to upstream repository instead of fork. +- Updated libvpx submodule to version 1.11.0 and point to upstream repository instead of fork. +- Updated libwebm submodule to version 1.0.0.28 and point to upstream repository instead of fork. +- Updated Mbed TLS submodule to version 2.28.7 and point to upstream repository instead of fork. +- Updated MojoAL submodule to commit e08dbf3 and point to upstream repository instead of fork. +- Updated Ogg submodule to version 1.3.5 and point to upstream repository instead of fork. +- Updated OpenAL-Soft submodule to version 1.20.1 and point to upstream repository instead of fork. +- Updated Pixman submodule to version 0.42.2 and point to upstream repository instead of fork. +- Updated SDL submodule to version 2.24.0 and point to upstream repository instead of fork. +- Updated Tinyfiledialogs submodule to version 3.8.8 (still uses fork due to SourceForge limitationss). +- Updated Vorbis submodule to version 1.3.7 and point to upstream repository instead of fork. +- Updated zlib submodule to version 1.2.12 and point to upstream repository instead of fork. 8.1.3 (07/22/2024) ------------------ -* Fixed Unicode conversion issues with various APIs, including as clipboard, window text, file dialogs, and fonts. -* Fixed Android builds with the `-emulator` flag that broke when using newer Android SDKs. -* Fixed "Could not link to neko" error message on macOS when lime.ndll is built with Xcode 15. -* Fixed system environment variables with the same name as common targets conflicting with other targets. -* Fixed `` and `` output confusing Haxe's completion server. Now skipped when `display` is defined. -* Fixed `Clipboard.text` incorrectly getting cleared to null when targeting HTML5. -* Fixed integer value parsing in _project.xml_, including immediately reporting errors for invalid values. -* Fixed incorrect path discovery for NDLL files that found source directory instead. -* Fixed missing error message if HXP project class name does not match file name. -* Fixed unspecified behavior from `null` keys in `ObjectPool`. -* Fixed some issues when running Haxe built natively for Apple Silicon. -* Fixed missing cancellation of vibration on Android when app is paused or destroyed. -* Fixed static linking of native curl library on macOS. -* Fixed deprecation warnings in Android Gradle builds. +- Fixed Unicode conversion issues with various APIs, including as clipboard, window text, file dialogs, and fonts. +- Fixed Android builds with the `-emulator` flag that broke when using newer Android SDKs. +- Fixed "Could not link to neko" error message on macOS when lime.ndll is built with Xcode 15. +- Fixed system environment variables with the same name as common targets conflicting with other targets. +- Fixed `` and `` output confusing Haxe's completion server. Now skipped when `display` is defined. +- Fixed `Clipboard.text` incorrectly getting cleared to null when targeting HTML5. +- Fixed integer value parsing in _project.xml_, including immediately reporting errors for invalid values. +- Fixed incorrect path discovery for NDLL files that found source directory instead. +- Fixed missing error message if HXP project class name does not match file name. +- Fixed unspecified behavior from `null` keys in `ObjectPool`. +- Fixed some issues when running Haxe built natively for Apple Silicon. +- Fixed missing cancellation of vibration on Android when app is paused or destroyed. +- Fixed static linking of native curl library on macOS. +- Fixed deprecation warnings in Android Gradle builds. 8.1.2 (03/13/2024) ------------------ -* Fixed error handling when failing to get joystick information in html5. -* Fixed error handling when creating `openfl` alias on Linux. -* Fixed error handling when getting information about Haxelibs. -* Fixed error when loading fonts in HL. -* Fixed error when loading grouped music/sound assets. -* Fixed errors when building on Apple Silicon without Rosetta. -* Fixed assets not being loaded when using nested asset tags (e.g., ` `). -* Fixed VC runtime potentially not being bundled into HL apps built on Windows. -* Fixed error in `AssetsMacro` when building with Haxe 4.3.4 or newer. -* Fixed crash on iOS during network operations. -* Updated howler.js to 2.2.3. -* Removed ARMv7 architecture from Android default architectures. -* Removed deprecated ARMv7 architecture from iOS default architectures. +- Fixed error handling when failing to get joystick information in html5. +- Fixed error handling when creating `openfl` alias on Linux. +- Fixed error handling when getting information about Haxelibs. +- Fixed error when loading fonts in HL. +- Fixed error when loading grouped music/sound assets. +- Fixed errors when building on Apple Silicon without Rosetta. +- Fixed assets not being loaded when using nested asset tags (e.g., ` `). +- Fixed VC runtime potentially not being bundled into HL apps built on Windows. +- Fixed error in `AssetsMacro` when building with Haxe 4.3.4 or newer. +- Fixed crash on iOS during network operations. +- Updated howler.js to 2.2.3. +- Removed ARMv7 architecture from Android default architectures. +- Removed deprecated ARMv7 architecture from iOS default architectures. 8.1.1 (11/08/2023) ------------------ -* Fixed subset of characters escaped in file paths to fix Android builds on Windows. -* Fixed playback of very long sounds by changing arithmetic to avoid integer overflow. +- Fixed subset of characters escaped in file paths to fix Android builds on Windows. +- Fixed playback of very long sounds by changing arithmetic to avoid integer overflow. 8.1.0 (10/16/2023) ------------------ -* Added `visible` property to `Window` to allow it to be shown and hidden -* Added `opacity` property to `Window` -* Added `minWidth`, `minHeight`, `maxWidth`, `maxHeight`, `setMinSize()`, and `setMaxSize()` to `Window` -* Added new `onShow` and `onHide` events to `Window` -* Added support for _include.hxp_ file in libraries, similar to _include.xml_ -* Added support for multiple file extension filters on `FileDialog` operations -* Added `-eval` option to run Lime tools without Neko -* Added `-terser` option to Lime tools for html5 builds to optionally use Terser minifier -* Added `-npx` option to Lime tools to run minifiers, or Electron, using `npx` instead of the bundled versions -* Updated the bundled version of Node.js to 18 LTS for the html5 target's HTTP server -* Exposed more information to _project.xml_, such as `${project.host}` and `${config.android.target-sdk-version}` -* Updated the Android Gradle plugin -* Disabled pointer tagging on Android -* Fixed issues in `emscripten` target and renamed it to `webassembly` -* Fixed unpopulated `responseData` on `HTTPRequest` when server returns error status code -* Fixed `Clipboard` contents being empty when app starts up on Windows and macOS -* Fixed Unicode string conversion for `alert()` method on `Window` on HashLink target -* Fixed asset cache clearing when unloading asset library -* Fixed incorrect timer pause and resume behavior when window goes into background and back to foreground -* Fixed _.app_ file extension for macOS when building Adobe AIR captive runtime bundle -* Fixed incorrect "Lime Application" window title for Adobe AIR applications -* Fixed null check when opening file with `FileDialog` -* Fixed expired Adobe AIR debug certificate -* Fixed Haxe 3 compatibility for enum abstracts -* Fixed running native apps with current working directory that does not match the program directory -* Fixed assets being incorrectly located from `Sys.programPath()` instead of `System.applicationDirectory` -* Fixed timing on html5 target by using `performance.now()` so that system clock changes don't cause issues -* Fixed parsing of JNI class names -* Fixed cleanup when windows are closed and the Lime application exits -* Removed the defunct Kha backend +- Added `visible` property to `Window` to allow it to be shown and hidden +- Added `opacity` property to `Window` +- Added `minWidth`, `minHeight`, `maxWidth`, `maxHeight`, `setMinSize()`, and `setMaxSize()` to `Window` +- Added new `onShow` and `onHide` events to `Window` +- Added support for _include.hxp_ file in libraries, similar to _include.xml_ +- Added support for multiple file extension filters on `FileDialog` operations +- Added `-eval` option to run Lime tools without Neko +- Added `-terser` option to Lime tools for html5 builds to optionally use Terser minifier +- Added `-npx` option to Lime tools to run minifiers, or Electron, using `npx` instead of the bundled versions +- Updated the bundled version of Node.js to 18 LTS for the html5 target's HTTP server +- Exposed more information to _project.xml_, such as `${project.host}` and `${config.android.target-sdk-version}` +- Updated the Android Gradle plugin +- Disabled pointer tagging on Android +- Fixed issues in `emscripten` target and renamed it to `webassembly` +- Fixed unpopulated `responseData` on `HTTPRequest` when server returns error status code +- Fixed `Clipboard` contents being empty when app starts up on Windows and macOS +- Fixed Unicode string conversion for `alert()` method on `Window` on HashLink target +- Fixed asset cache clearing when unloading asset library +- Fixed incorrect timer pause and resume behavior when window goes into background and back to foreground +- Fixed _.app_ file extension for macOS when building Adobe AIR captive runtime bundle +- Fixed incorrect "Lime Application" window title for Adobe AIR applications +- Fixed null check when opening file with `FileDialog` +- Fixed expired Adobe AIR debug certificate +- Fixed Haxe 3 compatibility for enum abstracts +- Fixed running native apps with current working directory that does not match the program directory +- Fixed assets being incorrectly located from `Sys.programPath()` instead of `System.applicationDirectory` +- Fixed timing on html5 target by using `performance.now()` so that system clock changes don't cause issues +- Fixed parsing of JNI class names +- Fixed cleanup when windows are closed and the Lime application exits +- Removed the defunct Kha backend 8.0.2 (05/31/2023) ------------------ -* Resolve new `@:enum abstract` warnings for Haxe 4.3 by replacing with `enum abstract`, if current Haxe version supports it -* Resolve new `@:extern` warnings for Haxe 4.3 by replacing with `extern`, if current Haxe version supports it -* Fixed HTTPS requests failing on macOS by updating cURL and mbedtls dependencies -* Fixed calling `JNI.callMember()` and `JNI.callStatic()` with more than 7 arguments -* Fixed DPI detection on Android by using `getDisplayMetrics()` -* Fixed passing `null` or empty string for default library to `Assets.registerLibrary()` to be more consistent with other APIs -* Fixed failed Lime tools build with some Haxe versions by removing `-D no-inline` -* Fixed Haxe argument type of OpenAL `alFilteri` wrapper that should be `Int` instead of `Dynamic` -* Fixed bad UTF string conversion for `FileDialog` that sometimes displayed incorrect characters on some platforms -* Fixed HTTP request status 400 being incorrectly treated as successful on html5 target -* Fixed failed Adobe AIR for iOS build on Windows by removing check for simulators, which are available on macOS only -* Fixed detection of default iPhone simulator to avoid exceptions and support future versions of Xcode -* Fixed conflict between `window.Image` and `lime.graphics.Image` when using Genes on html5 target -* Fixed exception in Lime tools if assets directory does not exist -* Removed legacy `armv7` from default iOS target architectures because it now results in an error (now defaults to `arm64`) -* AIR for iOS or Android may specify `listen="port"` in `` element to use USB debugging instead of wifi debugging -* Improved fix for text fields updating properly on Android devices with html5 target -* Replaced "Could not find Neko API interface" error message with more detailed explanation and instructions +- Resolve new `@:enum abstract` warnings for Haxe 4.3 by replacing with `enum abstract`, if current Haxe version supports it +- Resolve new `@:extern` warnings for Haxe 4.3 by replacing with `extern`, if current Haxe version supports it +- Fixed HTTPS requests failing on macOS by updating cURL and mbedtls dependencies +- Fixed calling `JNI.callMember()` and `JNI.callStatic()` with more than 7 arguments +- Fixed DPI detection on Android by using `getDisplayMetrics()` +- Fixed passing `null` or empty string for default library to `Assets.registerLibrary()` to be more consistent with other APIs +- Fixed failed Lime tools build with some Haxe versions by removing `-D no-inline` +- Fixed Haxe argument type of OpenAL `alFilteri` wrapper that should be `Int` instead of `Dynamic` +- Fixed bad UTF string conversion for `FileDialog` that sometimes displayed incorrect characters on some platforms +- Fixed HTTP request status 400 being incorrectly treated as successful on html5 target +- Fixed failed Adobe AIR for iOS build on Windows by removing check for simulators, which are available on macOS only +- Fixed detection of default iPhone simulator to avoid exceptions and support future versions of Xcode +- Fixed conflict between `window.Image` and `lime.graphics.Image` when using Genes on html5 target +- Fixed exception in Lime tools if assets directory does not exist +- Removed legacy `armv7` from default iOS target architectures because it now results in an error (now defaults to `arm64`) +- AIR for iOS or Android may specify `listen="port"` in `` element to use USB debugging instead of wifi debugging +- Improved fix for text fields updating properly on Android devices with html5 target +- Replaced "Could not find Neko API interface" error message with more detailed explanation and instructions 8.0.1 (02/21/2023) ------------------ -* Fixed error where low-priority SVG icons (such as the Flixel icon) would override normal- or high-priority PNGs -* Fixed `NativeHTTPRequest` buffer management for neko -* Fixed text field losing focus after copying in HTML5 -* Fixed extra or missing slashes in certain cases when loading assets -* Fixed `Assets.isLocal(null)` not checking all asset types -* Fixed getting `Clipboard.text` on Linux -* Fixed building `-static -debug` Windows apps -* Fixed sounds playing twice on iOS -* Fixed command line arguments not being passed to HashLink on macOS -* Fixed a null pointer exception when setting sound position in HTML5 -* Fixed cURL not resending data if there's a redirect -* Fixed `FileDialog` behavior when filtering by multiple file extensions, or 0 file extensions -* Fixed error when importing `JNI` during a macro while building for Android -* Fixed building `-static` Linux apps -* Fixed crash when compiling iOS apps with no background color -* Fixed `System.openFile()` on Linux -* Fixed requiring a keystore to sign AIR apps -* Fixed requiring a path to create a keystore -* Fixed HTML5 text fields not updating promptly on Android devices +- Fixed error where low-priority SVG icons (such as the Flixel icon) would override normal- or high-priority PNGs +- Fixed `NativeHTTPRequest` buffer management for neko +- Fixed text field losing focus after copying in HTML5 +- Fixed extra or missing slashes in certain cases when loading assets +- Fixed `Assets.isLocal(null)` not checking all asset types +- Fixed getting `Clipboard.text` on Linux +- Fixed building `-static -debug` Windows apps +- Fixed sounds playing twice on iOS +- Fixed command line arguments not being passed to HashLink on macOS +- Fixed a null pointer exception when setting sound position in HTML5 +- Fixed cURL not resending data if there's a redirect +- Fixed `FileDialog` behavior when filtering by multiple file extensions, or 0 file extensions +- Fixed error when importing `JNI` during a macro while building for Android +- Fixed building `-static` Linux apps +- Fixed crash when compiling iOS apps with no background color +- Fixed `System.openFile()` on Linux +- Fixed requiring a keystore to sign AIR apps +- Fixed requiring a path to create a keystore +- Fixed HTML5 text fields not updating promptly on Android devices 8.0.0 (08/30/2022) ------------------ -* Updated HashLink to version 1.12 -* Updated Android minimum SDK version to 21 -* Updated Electron template to version 18 -* Updated HTML5 to high DPI by default -* Added `--template` command line option to Lime tools -* Added `--appstore` and `--adhoc` command line options for AIR on iOS to Lime tools (to match iOS native) -* Added `-air-simulator` command line option for AIR to Lime tools (avoids packaging full AIR app) -* Added `` to optionally support custom AIR profiles in simulator -* Added `setTextInputRect` to `Window` to specify a rectangle that has focus for text input -* Added `JNISafety` to improve JNI communication on Android -* Added `manageCookies` to `HTTPRequest` to support cookies on native platforms (only session for now) -* Added `pitch` property to `AudioSource` -* Added `-Delectron` flag to Electron builds so that it's possible to use `#if electron` -* Added icon priorities to allow a library to provide a default icon that the user can override -* Improved HashLink _.app_ file generation on macOS -* Improved performance of `HTTPRequest` on native platforms with better buffer management -* Improved support for Android 12 (SDK 31) and newer -* Improved output file size if no assets are defined (sets `disable_preloader_assets` define) -* Improved stage sizing on Electron (defaults to `0` for fluid width/height, same as regular browsers) -* Fixed garbage collector crash issue on iOS 12 -* Fixed iOS build that failed because of missing _Metal.framework_ dependency -* Fixed switching between light and dark modes on Android destroying the Lime activity -* Fixed `getCurrentTime` on `AudioSource` for streaming sounds on native platforms -* Fixed wrong types on `NativeMenuItem` Flash externs -* Fixed set clipboard when `null` is passed (now changes to an empty string automatically) -* Fixed warnings for deprecated "devicemotion" events on Firefox -* Fixed incompatibility with "genes" Haxelib to allow generating JS Modules +- Updated HashLink to version 1.12 +- Updated Android minimum SDK version to 21 +- Updated Electron template to version 18 +- Updated HTML5 to high DPI by default +- Added `--template` command line option to Lime tools +- Added `--appstore` and `--adhoc` command line options for AIR on iOS to Lime tools (to match iOS native) +- Added `-air-simulator` command line option for AIR to Lime tools (avoids packaging full AIR app) +- Added `` to optionally support custom AIR profiles in simulator +- Added `setTextInputRect` to `Window` to specify a rectangle that has focus for text input +- Added `JNISafety` to improve JNI communication on Android +- Added `manageCookies` to `HTTPRequest` to support cookies on native platforms (only session for now) +- Added `pitch` property to `AudioSource` +- Added `-Delectron` flag to Electron builds so that it's possible to use `#if electron` +- Added icon priorities to allow a library to provide a default icon that the user can override +- Improved HashLink _.app_ file generation on macOS +- Improved performance of `HTTPRequest` on native platforms with better buffer management +- Improved support for Android 12 (SDK 31) and newer +- Improved output file size if no assets are defined (sets `disable_preloader_assets` define) +- Improved stage sizing on Electron (defaults to `0` for fluid width/height, same as regular browsers) +- Fixed garbage collector crash issue on iOS 12 +- Fixed iOS build that failed because of missing _Metal.framework_ dependency +- Fixed switching between light and dark modes on Android destroying the Lime activity +- Fixed `getCurrentTime` on `AudioSource` for streaming sounds on native platforms +- Fixed wrong types on `NativeMenuItem` Flash externs +- Fixed set clipboard when `null` is passed (now changes to an empty string automatically) +- Fixed warnings for deprecated "devicemotion" events on Firefox +- Fixed incompatibility with "genes" Haxelib to allow generating JS Modules 7.9.0 (03/10/2021) ------------------ @@ -339,1918 +363,1918 @@ _Notice: We are moving from our custom build server to Github Actions for releas _As a result, official releases support only current macOS versions. Earlier macOS_ _releases are still supported when building Lime from the source._ -* Updated support for Haxe 4.2 -* Updated the default iOS deployment to 9.0 -* Updated `ios-deploy` tool to support newer iOS and Xcode versions -* Added `failIfMajorPerformanceCaveat` setting for window (default false) -* Added bindings for OGG Vorbis on the HashLink target -* Improved iOS target to exclude Core Bluetooth framework -* Improved the performance for AIR application boot times -* Improved error message when attempting to use HashLink target on Haxe 3 -* Fixed support for Android screen orientation -* Fixed touch support on Android hardware that return unusual touch IDs -* Fixed an issue with excess bytes saved from `FileDialog` on HTML5 -* Fixed null-termination issues on strings returned from `lime.system.System` -* Fixed support for IEM input text on HTML5 -* Fixed audio stutter on HTML5 when `force-html-audio` is defined +- Updated support for Haxe 4.2 +- Updated the default iOS deployment to 9.0 +- Updated `ios-deploy` tool to support newer iOS and Xcode versions +- Added `failIfMajorPerformanceCaveat` setting for window (default false) +- Added bindings for OGG Vorbis on the HashLink target +- Improved iOS target to exclude Core Bluetooth framework +- Improved the performance for AIR application boot times +- Improved error message when attempting to use HashLink target on Haxe 3 +- Fixed support for Android screen orientation +- Fixed touch support on Android hardware that return unusual touch IDs +- Fixed an issue with excess bytes saved from `FileDialog` on HTML5 +- Fixed null-termination issues on strings returned from `lime.system.System` +- Fixed support for IEM input text on HTML5 +- Fixed audio stutter on HTML5 when `force-html-audio` is defined 7.8.0 (06/24/2020) ------------------ -* Updated to SDL 2.0.12 -* Updated Google Closure to v20200315 -* Added support for *.xcframework dependencies on iOS -* Added support for merging "-Info.plist" files from native extensions on iOS -* Fixed warnings when compiling on HTML5 using Haxe 4.1 -* Fixed HTML5 focus to return to previous element after using `lime.app.Clipboard` -* Fixed an unnecessary `setTextInputEnabled` workaround on Android -* Fixed return type for `gl.getParameter(GL.RENDERBUFFER_BINDING)` -* Fixed old default iOS simulator version -* Fixed the search string for HaxeObject/JNI to be more precise -* Fixed support for building using `-Djs-es=6` +- Updated to SDL 2.0.12 +- Updated Google Closure to v20200315 +- Added support for *.xcframework dependencies on iOS +- Added support for merging "-Info.plist" files from native extensions on iOS +- Fixed warnings when compiling on HTML5 using Haxe 4.1 +- Fixed HTML5 focus to return to previous element after using `lime.app.Clipboard` +- Fixed an unnecessary `setTextInputEnabled` workaround on Android +- Fixed return type for `gl.getParameter(GL.RENDERBUFFER_BINDING)` +- Fixed old default iOS simulator version +- Fixed the search string for HaxeObject/JNI to be more precise +- Fixed support for building using `-Djs-es=6` 7.7.0 (01/27/2020) ------------------ -* Updated SDL with a patch for high DPI resolution on macOS -* Updated tinyfiledialogs with a Unicode patch on Windows -* Updated macOS to use OpenAL-Soft (rather than deprecated Apple OpenAL library) -* Added missing properties/methods to `lime.utils.ArrayBuffer` -* Added support for NVX_gpu_memory_info OpenGL extension -* Added support for using launch storyboards instead of launch images on iOS -* Updated Android template to use Gradle 5.6.3 and Android Gradle Plugin 3.5.1 -* Improved `Assets.unloadLibrary` to allow unloading the default asset library -* Improved HTML5 WebGL to fallback to canvas if "major performance caveat" -* Improved the Electron output template to work without `-lib hxelectron` -* Improved support for x86-64 on Android target -* Improved handling of asset library root paths -* Improved garbage collection performance on `GLRenderbuffer` -* Fixed "auto" window orientation in the AIR template -* Fixed launch of iOS simulator on some systems -* Fixed support for `Clipboard` on HTML5 -* Fixed minimize/maximize on some desktop windows that are not resizable -* Fixed `Image.fromBitmapData` to set `buffer.transparent` -* Fixed some issues when toggling fullscreen on Android -* Fixed a potential crash when getting the system locale on iOS or macOS -* Fixed cleanup of Howler.js sounds after they are stopped -* Fixed `FileDialog` to not return as completed if the path is an empty string -* Fixed the default launch screen sizes on the iOS target -* Fixed Gradle paths to jcenter/Google for HTTPS support +- Updated SDL with a patch for high DPI resolution on macOS +- Updated tinyfiledialogs with a Unicode patch on Windows +- Updated macOS to use OpenAL-Soft (rather than deprecated Apple OpenAL library) +- Added missing properties/methods to `lime.utils.ArrayBuffer` +- Added support for NVX_gpu_memory_info OpenGL extension +- Added support for using launch storyboards instead of launch images on iOS +- Updated Android template to use Gradle 5.6.3 and Android Gradle Plugin 3.5.1 +- Improved `Assets.unloadLibrary` to allow unloading the default asset library +- Improved HTML5 WebGL to fallback to canvas if "major performance caveat" +- Improved the Electron output template to work without `-lib hxelectron` +- Improved support for x86-64 on Android target +- Improved handling of asset library root paths +- Improved garbage collection performance on `GLRenderbuffer` +- Fixed "auto" window orientation in the AIR template +- Fixed launch of iOS simulator on some systems +- Fixed support for `Clipboard` on HTML5 +- Fixed minimize/maximize on some desktop windows that are not resizable +- Fixed `Image.fromBitmapData` to set `buffer.transparent` +- Fixed some issues when toggling fullscreen on Android +- Fixed a potential crash when getting the system locale on iOS or macOS +- Fixed cleanup of Howler.js sounds after they are stopped +- Fixed `FileDialog` to not return as completed if the path is an empty string +- Fixed the default launch screen sizes on the iOS target +- Fixed Gradle paths to jcenter/Google for HTTPS support 7.6.3 (09/11/2019) ------------------ -* Fixed copying of 64-bit binaries when using Neko on Windows with Haxe 4 -* Fixed support for both 32- and 64-bit Neko on Windows (for Haxe 3 and 4) -* Fixed support for loading `HTTPRequest` data using the HL target +- Fixed copying of 64-bit binaries when using Neko on Windows with Haxe 4 +- Fixed support for both 32- and 64-bit Neko on Windows (for Haxe 3 and 4) +- Fixed support for loading `HTTPRequest` data using the HL target 7.6.2 (09/05/2019) ------------------ -* Fixed support for 64-bit Neko on Windows (included in Haxe 4 RC 4) +- Fixed support for 64-bit Neko on Windows (included in Haxe 4 RC 4) 7.6.1 (09/04/2019) ------------------ -* Fixed support for array-based form parameters when making HTTP requests -* Fixed incorrect default root path for asset manifests on some platforms -* Fixed a crash on the HL target when pasting non-text data +- Fixed support for array-based form parameters when making HTTP requests +- Fixed incorrect default root path for asset manifests on some platforms +- Fixed a crash on the HL target when pasting non-text data 7.6.0 (08/20/2019) ------------------ -* Updated support for Haxe 4 dev versions -* Updated SDL to 2.10 -* Updated the default Android target API to 28 (per Google guidelines) -* Updated HashLink support to 1.10 (requires Haxe 4 RC3 or greater) -* Added official support for Android ARM64 architecture -* Added ARM64 as a default architecture in Android builds -* Added `lime.utils.AssetBundle` for standard compressed libraries -* Added support for pure JSON-based asset manifest data -* Added AMD support to generated JavaScript output -* Added `remove` to `lime.utils.ObjectPool` -* Added initial support for `window.onMove` on the AIR target -* Improved the performance of `Image.loadFromBytes` on HTML5 -* Improved `DataPointer` to be a more reliable implementation in JavaScript -* Improved support for pre-generated asset libraries -* Improved the same origin check for `HTTPRequest` data-based URIs -* Improved the native main loop behavior on the Android target -* Fixed a compile error when using `flash.system.SystemIdleMode` -* Fixed issues with WebGL on the HTML5 target caused by `DataPointer` -* Fixed an issue where antialiasing was always enabled on HTML5 -* Fixed the behavior of `image.copyPixels` in a few cases -* Fixed minor issues when using the `-npm` HTML5 template +- Updated support for Haxe 4 dev versions +- Updated SDL to 2.10 +- Updated the default Android target API to 28 (per Google guidelines) +- Updated HashLink support to 1.10 (requires Haxe 4 RC3 or greater) +- Added official support for Android ARM64 architecture +- Added ARM64 as a default architecture in Android builds +- Added `lime.utils.AssetBundle` for standard compressed libraries +- Added support for pure JSON-based asset manifest data +- Added AMD support to generated JavaScript output +- Added `remove` to `lime.utils.ObjectPool` +- Added initial support for `window.onMove` on the AIR target +- Improved the performance of `Image.loadFromBytes` on HTML5 +- Improved `DataPointer` to be a more reliable implementation in JavaScript +- Improved support for pre-generated asset libraries +- Improved the same origin check for `HTTPRequest` data-based URIs +- Improved the native main loop behavior on the Android target +- Fixed a compile error when using `flash.system.SystemIdleMode` +- Fixed issues with WebGL on the HTML5 target caused by `DataPointer` +- Fixed an issue where antialiasing was always enabled on HTML5 +- Fixed the behavior of `image.copyPixels` in a few cases +- Fixed minor issues when using the `-npm` HTML5 template 7.5.0 (05/14/2019) ------------------ -* Update version +- Update version 7.4.0 (05/14/2019) ------------------ -* Renamed the "ndll" folder to "lib" -* Updated SDL to latest development version -* Updated the minimum target Android API from 14 to 16 -* Added support for CMYK JPEG decoding on native platforms -* Added an `-npm` option for HTML5 to use Webpack -* Added "hashlink" as an alias for the HL target -* Improved the Zlib default compression level -* Improved support for WinRT applications -* Improved the internal blur implementation -* Improved support for native joystick connection/disconnection -* Improved the output HTML5 script wrapper with better Haxe 3.2 support -* Fixed the values in `lime.ui.MouseButton` to match Lime's historic values (zero based) -* Fixed issues effecting proper `Image` pixel-level APIs when targeting HL -* Fixed a missing button value when dispatching HL mouse events +- Renamed the "ndll" folder to "lib" +- Updated SDL to latest development version +- Updated the minimum target Android API from 14 to 16 +- Added support for CMYK JPEG decoding on native platforms +- Added an `-npm` option for HTML5 to use Webpack +- Added "hashlink" as an alias for the HL target +- Improved the Zlib default compression level +- Improved support for WinRT applications +- Improved the internal blur implementation +- Improved support for native joystick connection/disconnection +- Improved the output HTML5 script wrapper with better Haxe 3.2 support +- Fixed the values in `lime.ui.MouseButton` to match Lime's historic values (zero based) +- Fixed issues effecting proper `Image` pixel-level APIs when targeting HL +- Fixed a missing button value when dispatching HL mouse events 7.3.0 (04/01/2019) ------------------ -* Updated support for Haxe 4 dev versions -* Updated SDL to 2.0.9 -* Updated howler.js to 2.1.1 -* Added initial display options to improve debugging with VS Code -* Added initial HashLink 1.9 support (requires Haxe 4 dev) -* Added initial support for embedding HTML5 projects in unique isolated JS closures -* Added support for appending dependency JS scripts to the application file -* Added initial support for haptic feedback on HTML5 -* Improved `lime display` when `lime build` has not been called -* Improved support for WinRT native builds -* Improved the behavior of `URLRequest` to re-use `Bytes` when writing -* Improved the performance of `URLRequest` on native platforms -* Improved `window.onDropFile` with an initial workaround for HTML5 support -* Moved internal code style to use the Haxe "formatter" library for consistency -* Fixed possible incorrect names in generated package.json for Electron output -* Fixed support for building for Android using ARMv5 or ARMv6 only -* Fixed the event types in `lime.system.ThreadPool` -* Fixed a possible rounding error when calculating application update times -* Fixed cases where HTML5 canvas was not properly enabling image smoothing -* Fixed the behavior of `threadPool.minThreads` to keep threads active -* Fixed incorrect extern in "lime/graphics/opengl/ext" classes on HTML5 -* Fixed incorrect `imageBuffer.bitsPerPixel` handling in `Font.renderGlyph` -* Fixed incorrect offset when using `image.copyPixels` with an alpha image -* Fixed Java `HaxeObject.create` to return `null` if handle is `null` -* Fixed exposure of generated `__ASSET__` classes to display completion +- Updated support for Haxe 4 dev versions +- Updated SDL to 2.0.9 +- Updated howler.js to 2.1.1 +- Added initial display options to improve debugging with VS Code +- Added initial HashLink 1.9 support (requires Haxe 4 dev) +- Added initial support for embedding HTML5 projects in unique isolated JS closures +- Added support for appending dependency JS scripts to the application file +- Added initial support for haptic feedback on HTML5 +- Improved `lime display` when `lime build` has not been called +- Improved support for WinRT native builds +- Improved the behavior of `URLRequest` to re-use `Bytes` when writing +- Improved the performance of `URLRequest` on native platforms +- Improved `window.onDropFile` with an initial workaround for HTML5 support +- Moved internal code style to use the Haxe "formatter" library for consistency +- Fixed possible incorrect names in generated package.json for Electron output +- Fixed support for building for Android using ARMv5 or ARMv6 only +- Fixed the event types in `lime.system.ThreadPool` +- Fixed a possible rounding error when calculating application update times +- Fixed cases where HTML5 canvas was not properly enabling image smoothing +- Fixed the behavior of `threadPool.minThreads` to keep threads active +- Fixed incorrect extern in "lime/graphics/opengl/ext" classes on HTML5 +- Fixed incorrect `imageBuffer.bitsPerPixel` handling in `Font.renderGlyph` +- Fixed incorrect offset when using `image.copyPixels` with an alpha image +- Fixed Java `HaxeObject.create` to return `null` if handle is `null` +- Fixed exposure of generated `__ASSET__` classes to display completion 7.2.1 (01/07/2019) ------------------ -* Updated howler.js to 2.1.0 -* Improved the internal HTTP request limit for better transfer speed on HTML5 -* Improved the performance for native HTTP requests -* Improved the quality of embedded font meta-data on the HTML5 target -* Improved `lime.utils.Assets` to allow disabling or setting the cache break number -* Fixed `Window` to not dispatch `onClose` on HTML5 (due to some mobile browsers) -* Fixed ability to cancel context menus on HTML5 when they occur on mouse down -* Fixed font support for some video game console targets +- Updated howler.js to 2.1.0 +- Improved the internal HTTP request limit for better transfer speed on HTML5 +- Improved the performance for native HTTP requests +- Improved the quality of embedded font meta-data on the HTML5 target +- Improved `lime.utils.Assets` to allow disabling or setting the cache break number +- Fixed `Window` to not dispatch `onClose` on HTML5 (due to some mobile browsers) +- Fixed ability to cancel context menus on HTML5 when they occur on mouse down +- Fixed font support for some video game console targets 7.2.0 (12/04/2018) ------------------ -* Improved support for Haxe 4 preview 5 -* Improved detection of HTML5 browser key codes to convert to Lime key values -* Improved support for Turkish lowercase values in `lime.text.UTF8String` -* Improved `HTTPRequest` with `-Dallow-status-0` to allow code 0 as success -* Improved project XML to allow `` or `"transparent"` -* Improved `fileDialog.save` support optional MIME types on HTML5 -* Improved munit support by enabling headless testing on the AIR target -* Improved the Electron target template with minor updates -* Improved the standard index.html template for cases when the window is transparent -* Improved performance when converting `lime.utils.DataPointer` on the C++ target -* Improved support for native `Clipboard` events -* Improved use of the `-rebuild` flag when targeting Neko on Windows -* Fixed a memory leak when certain kinds of bytes were loaded from disk -* Fixed a possible multi-thread crash in Lime native Bytes -* Fixed the failure case when loading corrupted PNG images -* Fixed an issue where `window.cursor = null` did not hide the cursor on HTML5 -* Fixed cases where the HTML5 backend attempted to cancel non-cancelable events -* Fixed support for `Font.renderGlyph` and `Font.renderGlyphs` -* Fixed an error in `haxe.Timer` if `System.getTimer` returned 0 -* Fixed native libraries to build with SSE3 support for better performance -* Fixed use of the `-Ddom` define to force HTML5 DOM render mode +- Improved support for Haxe 4 preview 5 +- Improved detection of HTML5 browser key codes to convert to Lime key values +- Improved support for Turkish lowercase values in `lime.text.UTF8String` +- Improved `HTTPRequest` with `-Dallow-status-0` to allow code 0 as success +- Improved project XML to allow `` or `"transparent"` +- Improved `fileDialog.save` support optional MIME types on HTML5 +- Improved munit support by enabling headless testing on the AIR target +- Improved the Electron target template with minor updates +- Improved the standard index.html template for cases when the window is transparent +- Improved performance when converting `lime.utils.DataPointer` on the C++ target +- Improved support for native `Clipboard` events +- Improved use of the `-rebuild` flag when targeting Neko on Windows +- Fixed a memory leak when certain kinds of bytes were loaded from disk +- Fixed a possible multi-thread crash in Lime native Bytes +- Fixed the failure case when loading corrupted PNG images +- Fixed an issue where `window.cursor = null` did not hide the cursor on HTML5 +- Fixed cases where the HTML5 backend attempted to cancel non-cancelable events +- Fixed support for `Font.renderGlyph` and `Font.renderGlyphs` +- Fixed an error in `haxe.Timer` if `System.getTimer` returned 0 +- Fixed native libraries to build with SSE3 support for better performance +- Fixed use of the `-Ddom` define to force HTML5 DOM render mode 7.1.1 (10/02/2018) ------------------ -* Improved the timing on native `HTTPRequest` to process more quickly -* Improved handling of `haxe.Timer` to pause and resume when the application suspends -* Fixed `lime rebuild mac` using Xcode 10 (disabled 32-bit rebuilds by default) -* Fixed an issue in the newer howler.js library regarding IE support -* Fixed a regression in older desktop CPU support -* Fixed an issue when using larger than 64-bit background color values on Flash -* Fixed `context.antialiasing` setting on HTML5 `Window` +- Improved the timing on native `HTTPRequest` to process more quickly +- Improved handling of `haxe.Timer` to pause and resume when the application suspends +- Fixed `lime rebuild mac` using Xcode 10 (disabled 32-bit rebuilds by default) +- Fixed an issue in the newer howler.js library regarding IE support +- Fixed a regression in older desktop CPU support +- Fixed an issue when using larger than 64-bit background color values on Flash +- Fixed `context.antialiasing` setting on HTML5 `Window` 7.1.0 (09/26/2018) ------------------ -* Updated Harfbuzz to 1.8.8 -* Updated OpenAL to 1.19.0 -* Updated howler.js to 2.0.15 -* Updated build configuration of pixman to better support each platform -* Added `application.meta.version` to the default application template -* Added support for `` for undefining values -* Added support for `` in project.xml -* Renamed `cairo.operator` to `cairo.setOperator`/`getOperator` on Haxe 4 builds -* Updated `lime.text.Font` to allow for changes to the font metric meta values -* Removed `-Ddisplay` on `lime display` output for better cached compilation -* Removed prefixes on `imageSmoothingEnabled` internally to remove HTML5 warnings -* Improved use of howler.js to enable sound position -* Improved HTML5 support for certain MP3 audio files -* Improved `Image.loadFromBase64`/`Image.fromBase64` to work on non-HTML5 platforms -* Fixed a possible error when processing directories ending in ".bundle" -* Fixed an issue where multiple `HTTPRequest` instances on native could hang -* Fixed support for `` as an alias for type "deflate" -* Fixed minor issues in `TextField` when working with non-UTF8 `String` values -* Fixed use of specific iOS target devices in the AIR project template -* Fixed an exception caused in garbage collection for cURL requests -* Fixed an issue when using `window.readPixels` on HTML5 -* Fixed possible exceptions when working with Harfbuzz languages -* Fixed a minor encoding issue in `image.encode (BMP)` -* Fixed setting of `window.parameters` using `WindowAttributes` on creation -* Fixed default use of Visual Studio Community when older versions are installed -* Fixed an exception when checking locale on certain iOS devices -* Fixed compiler errors when using `webgl2.texImage2D` with certain parameters -* Fixed use of WebGL 2, when available, as the default context on HTML5 -* Fixed support for `-static` native builds for Windows -* Fixed an issue where `Assets` cache breaking was not working properly -* Fixed compilation issues in Haxe 4 development builds +- Updated Harfbuzz to 1.8.8 +- Updated OpenAL to 1.19.0 +- Updated howler.js to 2.0.15 +- Updated build configuration of pixman to better support each platform +- Added `application.meta.version` to the default application template +- Added support for `` for undefining values +- Added support for `` in project.xml +- Renamed `cairo.operator` to `cairo.setOperator`/`getOperator` on Haxe 4 builds +- Updated `lime.text.Font` to allow for changes to the font metric meta values +- Removed `-Ddisplay` on `lime display` output for better cached compilation +- Removed prefixes on `imageSmoothingEnabled` internally to remove HTML5 warnings +- Improved use of howler.js to enable sound position +- Improved HTML5 support for certain MP3 audio files +- Improved `Image.loadFromBase64`/`Image.fromBase64` to work on non-HTML5 platforms +- Fixed a possible error when processing directories ending in ".bundle" +- Fixed an issue where multiple `HTTPRequest` instances on native could hang +- Fixed support for `` as an alias for type "deflate" +- Fixed minor issues in `TextField` when working with non-UTF8 `String` values +- Fixed use of specific iOS target devices in the AIR project template +- Fixed an exception caused in garbage collection for cURL requests +- Fixed an issue when using `window.readPixels` on HTML5 +- Fixed possible exceptions when working with Harfbuzz languages +- Fixed a minor encoding issue in `image.encode (BMP)` +- Fixed setting of `window.parameters` using `WindowAttributes` on creation +- Fixed default use of Visual Studio Community when older versions are installed +- Fixed an exception when checking locale on certain iOS devices +- Fixed compiler errors when using `webgl2.texImage2D` with certain parameters +- Fixed use of WebGL 2, when available, as the default context on HTML5 +- Fixed support for `-static` native builds for Windows +- Fixed an issue where `Assets` cache breaking was not working properly +- Fixed compilation issues in Haxe 4 development builds 7.0.0 (08/09/2018) ------------------ -* Major API re-design to improve workflow outside of command-line tools -* Migrated the core of the command-line tools into a new project called HXP -* Updated Freetype to 2.9.1 -* Updated Android minimum SDK to API 14 and the default target SDK to API 26 -* Updated window defaults to always enable depth and stencil buffers -* Updated window defaults to use a 32-bit (instead of 16-bit) backbuffer -* Removed `lime.graphics.Renderer`, functionality moved to `Window` -* Removed `lime.app.Config`, moved `app.frameRate` to `Window` -* Removed `lime.graphics.format.*`, functionality moved to `image.encode` -* Removed `lime.utils.compress.*`, functionality moved to `lime.utils.Bytes` -* Removed `lime.ui.Mouse`, functionality moved to `Window` -* Renamed `lime.app.Preloader` to `lime.utils.Preloader` -* Removed `lime.text.TextLayout`, replaced with native Harfbuzz bindings -* Moved `lime.project` types into `lime.tools` -* Moved `lime.utils.GLUtils` functionality to `GLProgram` and `GLShader` -* Added new `lime.graphics.RenderContext` with more lightweight API bindings -* Divided OpenGL support into separate `OPENGL`, `OPENGLES` and `WEBGL` types -* Compatibility APIs are provided in one direction (GL -> GLES -> WebGL) -* Added `lime.ui.WindowAttributes` with broader context creation control -* Sub-classing `Application` now requires no `window` argument for most methods -* Multi-window applications should listen to `app.onWindowCreate` instead -* Added support for Haxe Eval target, and beta support for HashLink (on dev) -* Added Windows 64-bit support, Android ARM64 support, progress on WinRT support -* Added bindings for the Harfbuzz native text layout library -* Added `lime.ui.MouseButton` and `lime.ui.MouseWheelMode` -* Added MojoAL support (as an alternative to OpenAL-Soft) in dev builds -* Added cURL Multi support -* Added support for `` -* Exposed `window.stage` and `window.element` on Flash/HTML5 targets -* Improved native build times by not relying on macros for CFFI -* Improved mouse event bindings, improved consistency of mouse wheel behavior -* Improved HTML5 fullscreen exit to dispatch a restore, not a resize event -* Improved `lime.math.*` classes to allow for less GC activity -* Improved support for Electron on Linux to allow for WebGL on more drivers -* Improved quality for HTML5 frame rate when set to lower than VSync -* Improved `HTTPRequest` to dispatch a progress event when loading locally -* Fixed some cases where allocation could occur during native GC -* Fixed use of future.then when the result is an error condition -* Fixed issues with some of the equations in `lime.math.*` -* Fixed warning in Chrome caused by default HTML5 template -* Fixed unnecessary AL cleanup message on exit -* Fixed replay of existing native AudioSource sounds -* Fixed Unicode paths on Windows when returning paths from the system -* Fixed pasting Clipboard data when application first launches -* Fixed webfont loading on mobile Safari -* Fixed issue with AL.source3i types -* Fixed support for iOS entitlements paths that include spaces +- Major API re-design to improve workflow outside of command-line tools +- Migrated the core of the command-line tools into a new project called HXP +- Updated Freetype to 2.9.1 +- Updated Android minimum SDK to API 14 and the default target SDK to API 26 +- Updated window defaults to always enable depth and stencil buffers +- Updated window defaults to use a 32-bit (instead of 16-bit) backbuffer +- Removed `lime.graphics.Renderer`, functionality moved to `Window` +- Removed `lime.app.Config`, moved `app.frameRate` to `Window` +- Removed `lime.graphics.format.*`, functionality moved to `image.encode` +- Removed `lime.utils.compress.*`, functionality moved to `lime.utils.Bytes` +- Removed `lime.ui.Mouse`, functionality moved to `Window` +- Renamed `lime.app.Preloader` to `lime.utils.Preloader` +- Removed `lime.text.TextLayout`, replaced with native Harfbuzz bindings +- Moved `lime.project` types into `lime.tools` +- Moved `lime.utils.GLUtils` functionality to `GLProgram` and `GLShader` +- Added new `lime.graphics.RenderContext` with more lightweight API bindings +- Divided OpenGL support into separate `OPENGL`, `OPENGLES` and `WEBGL` types +- Compatibility APIs are provided in one direction (GL -> GLES -> WebGL) +- Added `lime.ui.WindowAttributes` with broader context creation control +- Sub-classing `Application` now requires no `window` argument for most methods +- Multi-window applications should listen to `app.onWindowCreate` instead +- Added support for Haxe Eval target, and beta support for HashLink (on dev) +- Added Windows 64-bit support, Android ARM64 support, progress on WinRT support +- Added bindings for the Harfbuzz native text layout library +- Added `lime.ui.MouseButton` and `lime.ui.MouseWheelMode` +- Added MojoAL support (as an alternative to OpenAL-Soft) in dev builds +- Added cURL Multi support +- Added support for `` +- Exposed `window.stage` and `window.element` on Flash/HTML5 targets +- Improved native build times by not relying on macros for CFFI +- Improved mouse event bindings, improved consistency of mouse wheel behavior +- Improved HTML5 fullscreen exit to dispatch a restore, not a resize event +- Improved `lime.math.*` classes to allow for less GC activity +- Improved support for Electron on Linux to allow for WebGL on more drivers +- Improved quality for HTML5 frame rate when set to lower than VSync +- Improved `HTTPRequest` to dispatch a progress event when loading locally +- Fixed some cases where allocation could occur during native GC +- Fixed use of future.then when the result is an error condition +- Fixed issues with some of the equations in `lime.math.*` +- Fixed warning in Chrome caused by default HTML5 template +- Fixed unnecessary AL cleanup message on exit +- Fixed replay of existing native AudioSource sounds +- Fixed Unicode paths on Windows when returning paths from the system +- Fixed pasting Clipboard data when application first launches +- Fixed webfont loading on mobile Safari +- Fixed issue with AL.source3i types +- Fixed support for iOS entitlements paths that include spaces 6.4.0 (06/01/2018) ------------------ -* Updated NPM dependency to `file-saver` from `file-saverjs` -* Updated Android ARMv7 builds to use `armeabi-v7a` instead of `armeabi-v7` -* Added (Beta) support for `electron` (`html5 -electron`) target -* Added `window.onExpose` event (useful when not rendering every frame) -* Added `raspberrypi` or `rpi` as a target alias -* Improved `Locale` to better handle `en_US-en` style strings -* Improved handling of iOS locale values -* Improved support for current Xcode versions by using an `.entitlements` file -* Improved support for mouse "release outside" behavior on HTML5 -* Improved support for current Raspberry Pi OpenGL/EGL libraries -* Improved Android Gradle template to include Maven for native extensions -* Improved error handling when a library handler does not execute properly -* Fixed crash in `ObjectPool` when setting initial size -* Fixed setting `powerOfTwo = true` for an `ImageBuffer` with a canvas source -* Fixed SWF font generation to limit kerning values to the SWF spec maximum -* Fixed some cases where `HOME` environment variable might return `null` +- Updated NPM dependency to `file-saver` from `file-saverjs` +- Updated Android ARMv7 builds to use `armeabi-v7a` instead of `armeabi-v7` +- Added (Beta) support for `electron` (`html5 -electron`) target +- Added `window.onExpose` event (useful when not rendering every frame) +- Added `raspberrypi` or `rpi` as a target alias +- Improved `Locale` to better handle `en_US-en` style strings +- Improved handling of iOS locale values +- Improved support for current Xcode versions by using an `.entitlements` file +- Improved support for mouse "release outside" behavior on HTML5 +- Improved support for current Raspberry Pi OpenGL/EGL libraries +- Improved Android Gradle template to include Maven for native extensions +- Improved error handling when a library handler does not execute properly +- Fixed crash in `ObjectPool` when setting initial size +- Fixed setting `powerOfTwo = true` for an `ImageBuffer` with a canvas source +- Fixed SWF font generation to limit kerning values to the SWF spec maximum +- Fixed some cases where `HOME` environment variable might return `null` 6.3.1 (05/11/2018) ------------------ -* Improved support for \*.bundle libraries within an asset folder -* Improved the output of `lime help` -* Fixed the behavior of `` to behave like `` + `` +- Improved support for \*.bundle libraries within an asset folder +- Improved the output of `lime help` +- Fixed the behavior of `` to behave like `` + `` 6.3.0 (05/04/2018) ------------------ -* Updated SDL to 2.0.8 -* Updated howler.js to 2.0.9 -* Updated Android NDK platform to a minimum of API 14 -* Updated macOS minimum support version to 10.9 -* Added support for `-D foo` in addition to `-Dfoo` -* Added support for `--` in addition to `-args` for runtime arguments -* Added catching of key/value runtime arguments as `window.config.parameters` -* Added support for `--window-` flags at runtime on Lime applications -* Added a workaround to fix memory leaks in Apple's OpenAL implementation -* Added initial HTML5 accelerometer sensor support -* Added support for exporting multiple iOS IPA types when using `lime deploy` -* Added `ENHANCED` profile to AIR extern types -* Improved the behavior of `lime setup` -* Improved the output of `lime help` -* Improved failed sound loading on HTML5 to print a runtime warning -* Improved support for multiple threads in OpenAL, Cairo and cURL GC -* Improved the generation of webfonts to ignore non-essential formats -* Improved behavior when calling closure compiler to minify JS -* Improved `openfl.Vector` to typed array conversion to support OpenFL 8 -* Improved `Assets.getPath` to return the first path if using a path group -* Improved support for `KHR_debug` in OpenGL -* Improved handling of errors within OpenAL generation of sources and buffers -* Improved window focus mouse clicks to still fire an event -* Improvde handling of disposed native `AudioSource` objects -* Improved support for opening files with spaces in the path -* Improved the Gradle template to use jcenter instead of maven for dependencies -* Fixed detection of font family names on some Android 4.x devices -* Fixed support for `-dce full` with `embed=true` assets on native -* Fixed a small memory leak in Zlib compress -* Fixed a small memory leak when using cURL request headers -* Fixed a small memory leak in `gamepad.guid` -* Fixed support for a software fallback when GL support is too old -* Fixed a regression in support for static desktop builds -* Fixed a possible garbage collection issue in cURL support -* Fixed calling `UTF8String.substr()` internally without a length field -* Fixed request of keyboard input on WebKit when in fullscreen -* Fixed a possible issue when building on macOS with spaces in the Lime directory -* Fixed the behavior of `embed="false"` assets on HTML5 -* Fixed a possible race condition in `-Dsimulate-preloader` on Flash target -* Fixed support for additional iOS icon sizes -* Fixed fullscreen text input on WebKit browsers -* Fixed an issue using `Image.fromBase64` in ES6/NPM-based builds -* Fixed disabling of vsync on native targets when not desired +- Updated SDL to 2.0.8 +- Updated howler.js to 2.0.9 +- Updated Android NDK platform to a minimum of API 14 +- Updated macOS minimum support version to 10.9 +- Added support for `-D foo` in addition to `-Dfoo` +- Added support for `--` in addition to `-args` for runtime arguments +- Added catching of key/value runtime arguments as `window.config.parameters` +- Added support for `--window-` flags at runtime on Lime applications +- Added a workaround to fix memory leaks in Apple's OpenAL implementation +- Added initial HTML5 accelerometer sensor support +- Added support for exporting multiple iOS IPA types when using `lime deploy` +- Added `ENHANCED` profile to AIR extern types +- Improved the behavior of `lime setup` +- Improved the output of `lime help` +- Improved failed sound loading on HTML5 to print a runtime warning +- Improved support for multiple threads in OpenAL, Cairo and cURL GC +- Improved the generation of webfonts to ignore non-essential formats +- Improved behavior when calling closure compiler to minify JS +- Improved `openfl.Vector` to typed array conversion to support OpenFL 8 +- Improved `Assets.getPath` to return the first path if using a path group +- Improved support for `KHR_debug` in OpenGL +- Improved handling of errors within OpenAL generation of sources and buffers +- Improved window focus mouse clicks to still fire an event +- Improvde handling of disposed native `AudioSource` objects +- Improved support for opening files with spaces in the path +- Improved the Gradle template to use jcenter instead of maven for dependencies +- Fixed detection of font family names on some Android 4.x devices +- Fixed support for `-dce full` with `embed=true` assets on native +- Fixed a small memory leak in Zlib compress +- Fixed a small memory leak when using cURL request headers +- Fixed a small memory leak in `gamepad.guid` +- Fixed support for a software fallback when GL support is too old +- Fixed a regression in support for static desktop builds +- Fixed a possible garbage collection issue in cURL support +- Fixed calling `UTF8String.substr()` internally without a length field +- Fixed request of keyboard input on WebKit when in fullscreen +- Fixed a possible issue when building on macOS with spaces in the Lime directory +- Fixed the behavior of `embed="false"` assets on HTML5 +- Fixed a possible race condition in `-Dsimulate-preloader` on Flash target +- Fixed support for additional iOS icon sizes +- Fixed fullscreen text input on WebKit browsers +- Fixed an issue using `Image.fromBase64` in ES6/NPM-based builds +- Fixed disabling of vsync on native targets when not desired 6.2.0 (02/16/2018) ------------------ -* Added new implementation of `Font.renderGlyphs` for native platforms -* Added generation of font metrics for embedded HTML5 fonts -* Improved support for ANGLE builds on Windows -* Improved accuracy of file seeking in streaming OGG Vorbis sounds on native -* Fixed regression in `renderer.readPixels` when using an OpenGL renderer -* Fixed addition of an empty character when using arrow keys on HTML5 text input -* Fixed fallback for OpenGL ES 2.0 on older iOS devices when 3.0 is not available -* Fixed using environment variables to define the path to the Emscripten SDK -* Fixed letting the user focus outside a Lime embed when text input is enabled -* Fixed `FileDialog.save` to require FileSaver.js when using CommonJS +- Added new implementation of `Font.renderGlyphs` for native platforms +- Added generation of font metrics for embedded HTML5 fonts +- Improved support for ANGLE builds on Windows +- Improved accuracy of file seeking in streaming OGG Vorbis sounds on native +- Fixed regression in `renderer.readPixels` when using an OpenGL renderer +- Fixed addition of an empty character when using arrow keys on HTML5 text input +- Fixed fallback for OpenGL ES 2.0 on older iOS devices when 3.0 is not available +- Fixed using environment variables to define the path to the Emscripten SDK +- Fixed letting the user focus outside a Lime embed when text input is enabled +- Fixed `FileDialog.save` to require FileSaver.js when using CommonJS 6.1.0 (02/07/2018) ------------------ -* Added OpenGL ES 3.0 support on iOS -* Added `System.deviceVendor` and `System.deviceModel` -* Added `System.platformLabel`, `.platformName` and `.platformVersion` -* Added support for `` -* Added support for `` -* Improved garbage collection behavior in `lime.net.curl.CURL` -* Improved performance when requesting static `System` values repeatedly -* Improved Xcode template for iPhone X and Xcode 9.2 -* Renamed `-Dmodular` to `-Dlime-modular` (to allow for using lib modular) -* Fixed a possible crash in `ImageDataUtil.gaussianBlur` -* Fixed an iOS template path for "haxe/Build.hxml" -* Fixed an issue when setting volume in HTML5 before playback starts -* Fixed default framebuffer binding when using iOS simulator -* Fixed support for properly detecting MP3 format in some files -* Fixed support for builds on macOS/Linux when `$HOME` variable is not present -* Fixed crash in continuous-testing when no window can be initialized +- Added OpenGL ES 3.0 support on iOS +- Added `System.deviceVendor` and `System.deviceModel` +- Added `System.platformLabel`, `.platformName` and `.platformVersion` +- Added support for `` +- Added support for `` +- Improved garbage collection behavior in `lime.net.curl.CURL` +- Improved performance when requesting static `System` values repeatedly +- Improved Xcode template for iPhone X and Xcode 9.2 +- Renamed `-Dmodular` to `-Dlime-modular` (to allow for using lib modular) +- Fixed a possible crash in `ImageDataUtil.gaussianBlur` +- Fixed an iOS template path for "haxe/Build.hxml" +- Fixed an issue when setting volume in HTML5 before playback starts +- Fixed default framebuffer binding when using iOS simulator +- Fixed support for properly detecting MP3 format in some files +- Fixed support for builds on macOS/Linux when `$HOME` variable is not present +- Fixed crash in continuous-testing when no window can be initialized 6.0.1 (01/16/2018) ------------------ -* Minor fix for `haxelib run openfl setup` command-line alias installation +- Minor fix for `haxelib run openfl setup` command-line alias installation 6.0.0 (01/15/2018) ------------------ -* Added `-watch` for simple \*.hx file watching support on commands -* Added support for OpenAL effects extension where available -* Added support for forcing a WebGL 1 context at runtime -* Added support for defining an HTML5 DOM renderer at runtime -* Added support for automatic iOS device provisioning and registration -* Added improved support for CommonJS output -* Improved support for the `haxe-modular` library -* Improved support for haxelibs that define `classPath` in haxelib.json -* Improved performance of `image.copyPixels` on HTML5 when image is not a canvas -* Improved use of external libraries when using CommonJS -* Improved the quality of locale values returned on Windows -* Improved handling of null responses in `HTTPRequest` -* Improved `ObjectPool` to not use generics on HTML5 for better file size -* Fixed issues preventing compilation of tools for Node.js -* Fixed use of `rootPath` when loading packed asset libraries -* Fixed launch image sizes for iPhone X -* Fixed support for `-Dnocffi` when compiling CLI tools -* Fixed a possible range error in `DataPointer` -* Fixed a minor debug message when HXCPP "std" is statically linked +- Added `-watch` for simple \*.hx file watching support on commands +- Added support for OpenAL effects extension where available +- Added support for forcing a WebGL 1 context at runtime +- Added support for defining an HTML5 DOM renderer at runtime +- Added support for automatic iOS device provisioning and registration +- Added improved support for CommonJS output +- Improved support for the `haxe-modular` library +- Improved support for haxelibs that define `classPath` in haxelib.json +- Improved performance of `image.copyPixels` on HTML5 when image is not a canvas +- Improved use of external libraries when using CommonJS +- Improved the quality of locale values returned on Windows +- Improved handling of null responses in `HTTPRequest` +- Improved `ObjectPool` to not use generics on HTML5 for better file size +- Fixed issues preventing compilation of tools for Node.js +- Fixed use of `rootPath` when loading packed asset libraries +- Fixed launch image sizes for iPhone X +- Fixed support for `-Dnocffi` when compiling CLI tools +- Fixed a possible range error in `DataPointer` +- Fixed a minor debug message when HXCPP "std" is statically linked 5.9.1 (11/30/2017) ------------------ -* Updated howler.js with minor fixes for IE11 and Firefox browsers +- Updated howler.js with minor fixes for IE11 and Firefox browsers 5.9.0 (11/29/2017) ------------------ -* Added support for {{variable}} substitution in template file/folder names -* Added support for packed asset libraries, with optional compression -* Added initial support for Adobe native extensions (ANE) for AIR -* Added `-Dlime-default-timeout` to override the default HTTPRequest timeout -* Added a prompt for keystore password on Android if no password is provided -* Added a hint to request a discrete GPU on dual-GPU Windows systems -* Added a general "ios/template" template path for copying additional files -* Added ability to export iOS `-archive` on build -* Added ability to `lime deploy ios` and output IPA for store or ad-hoc -* Improved `-verbose` to be ignored by default on `lime display` for IDEs -* Improved iOS launch image list to support iPhone X fullscreen resolution -* Improved CSS font generation to skip formats that are not able to convert -* Improved the behavior of `` on HTML5 -* Fixed handling of HTTP status 0 as an error when not running on Tizen HTML5 -* Fixed an issue with `ContextMenuItem`/`NativeContextMenuItem` for Flash/AIR -* Fixed the AIR target install folder if `` is empty -* Fixed reference to the `EMSCRIPTEN_SDK` when targeting Emscripten/WebAssembly -* Fixed an issue with double playing of sound on Firefox using howler.js -* Fixed a possible error in some web browsers when reloading the current page -* Fixed handling of the newer iOS simulator and file extensions for AIR builds -* Fixed return to Android fullscreen when dismissing an on-screen keyboard -* Fixed a minor naming issue when using newer HXCPP and MSVC for static builds -* Fixed setting of "ios" and "android" project values when using AIR iOS/Android -* Fixed handling of Haxe version output with newer Haxe development build +- Added support for {{variable}} substitution in template file/folder names +- Added support for packed asset libraries, with optional compression +- Added initial support for Adobe native extensions (ANE) for AIR +- Added `-Dlime-default-timeout` to override the default HTTPRequest timeout +- Added a prompt for keystore password on Android if no password is provided +- Added a hint to request a discrete GPU on dual-GPU Windows systems +- Added a general "ios/template" template path for copying additional files +- Added ability to export iOS `-archive` on build +- Added ability to `lime deploy ios` and output IPA for store or ad-hoc +- Improved `-verbose` to be ignored by default on `lime display` for IDEs +- Improved iOS launch image list to support iPhone X fullscreen resolution +- Improved CSS font generation to skip formats that are not able to convert +- Improved the behavior of `` on HTML5 +- Fixed handling of HTTP status 0 as an error when not running on Tizen HTML5 +- Fixed an issue with `ContextMenuItem`/`NativeContextMenuItem` for Flash/AIR +- Fixed the AIR target install folder if `` is empty +- Fixed reference to the `EMSCRIPTEN_SDK` when targeting Emscripten/WebAssembly +- Fixed an issue with double playing of sound on Firefox using howler.js +- Fixed a possible error in some web browsers when reloading the current page +- Fixed handling of the newer iOS simulator and file extensions for AIR builds +- Fixed return to Android fullscreen when dismissing an on-screen keyboard +- Fixed a minor naming issue when using newer HXCPP and MSVC for static builds +- Fixed setting of "ios" and "android" project values when using AIR iOS/Android +- Fixed handling of Haxe version output with newer Haxe development build 5.8.2 (11/10/2017) ------------------ -* Updated cURL to 7.56.1 and changed SSL library from axTLS to mbedTLS -* Updated howler.js to 2.0.5, FileSaver.js to 1.3.3 -* Added `-Dcurl-verbose` for additional cURL debug info in native `HTTPRequest` -* Improved support for `` on HTML5 target -* Improved `renderer.readPixels` on native platforms to allow transparency -* Fixed the behavior of `` +- Updated cURL to 7.56.1 and changed SSL library from axTLS to mbedTLS +- Updated howler.js to 2.0.5, FileSaver.js to 1.3.3 +- Added `-Dcurl-verbose` for additional cURL debug info in native `HTTPRequest` +- Improved support for `` on HTML5 target +- Improved `renderer.readPixels` on native platforms to allow transparency +- Fixed the behavior of `` 5.8.1 (11/06/2017) ------------------ -* Added support for `AudioBuffer.fromBytes` on HTML5 -* Added initial support for `fileDialog.save` on HTML5 (using FileSaver.js) -* Added initial support for native extensions on the Adobe AIR target -* Improved the behavior of missing webfonts to no longer crash a web application -* Improved `window.onClose` to be cancelable on HTML5 -* Improved tools to print warning for unrecognized `` values -* Fixed support for Adobe AIR where `nativeWindow` is `null` +- Added support for `AudioBuffer.fromBytes` on HTML5 +- Added initial support for `fileDialog.save` on HTML5 (using FileSaver.js) +- Added initial support for native extensions on the Adobe AIR target +- Improved the behavior of missing webfonts to no longer crash a web application +- Improved `window.onClose` to be cancelable on HTML5 +- Improved tools to print warning for unrecognized `` values +- Fixed support for Adobe AIR where `nativeWindow` is `null` 5.8.0 (10/24/2017) ------------------ -* Added `httpRequest.withCredentials` for sending cookies with web requests -* Added initial support for `Touch.onCancel` events -* Restored `false` as the default `httpRequest.enableResponseHeaders` value -* Improved image loading to better support progress events on some browsers -* Improved support for `HTTPRequest` headers on native platforms -* Improved the handling of `lime.utils.Log` output on web browsers -* Improved `lime.utils.ObjectPool` to allow abstract types -* Improved AIR builds to support the `` tag for signing -* Improved the default window size for AIR output for mobile platforms -* Improved AIR template to respect `` for iOS -* Improved AIR template to support additional icon sizes for mobile -* Fixed the behavior of tailing the `trace` log on Windows/Flash target -* Fixed HTML5 "same origin" calculation for CORS requests -* Fixed return to Android fullscreen after losing window focus -* Fixed support for `ANDROID_GRADLE_TASK` with command-line arguments -* Fixed support for relative provisioning profile paths for AIR target +- Added `httpRequest.withCredentials` for sending cookies with web requests +- Added initial support for `Touch.onCancel` events +- Restored `false` as the default `httpRequest.enableResponseHeaders` value +- Improved image loading to better support progress events on some browsers +- Improved support for `HTTPRequest` headers on native platforms +- Improved the handling of `lime.utils.Log` output on web browsers +- Improved `lime.utils.ObjectPool` to allow abstract types +- Improved AIR builds to support the `` tag for signing +- Improved the default window size for AIR output for mobile platforms +- Improved AIR template to respect `` for iOS +- Improved AIR template to support additional icon sizes for mobile +- Fixed the behavior of tailing the `trace` log on Windows/Flash target +- Fixed HTML5 "same origin" calculation for CORS requests +- Fixed return to Android fullscreen after losing window focus +- Fixed support for `ANDROID_GRADLE_TASK` with command-line arguments +- Fixed support for relative provisioning profile paths for AIR target 5.7.1 (10/12/2017) ------------------ -* Updated default `MACOSX_DEPLOYMENT_TARGET` on macOS to 10.7 -* Improved native `HTTPRequest` to complete as error if response status is error -* Fixed `HTTPRequest` to treat HTTP status code 400 as an error +- Updated default `MACOSX_DEPLOYMENT_TARGET` on macOS to 10.7 +- Improved native `HTTPRequest` to complete as error if response status is error +- Fixed `HTTPRequest` to treat HTTP status code 400 as an error 5.7.0 (10/10/2017) ------------------ -* Updated Freetype to 2.7.1, compiled with Harfbuzz/PNG support enabled -* Added initial Adobe AIR backend support for multiple windows, alerts, etc -* Added `threadPool.onRun` to be notified when work is about to be run -* Added `ModuleHelper.addModuleSource` to improve JS modules from HXP projects -* Added initial Dockerfile script -* Added a polyfill for `performance.now()` to restore iPhone 4 HTML5 support -* Improved Raspberry Pi support by adding "Escape" as a default key to exit -* Improved support for non-premultiplied alpha in `imageDataUtil.gaussianBlur` -* Improved native `HTTPRequest` to size bytes initially based on Content-Length -* Improved support for Xcode 9.1 -* Improved support for combined characters in `TextLayout` -* Fixed setting of `MACOSX_DEPLOYMENT_TARGET` on macOS -* Fixed support for resolving iOS provisioning profiles for AIR/iOS on Windows -* Fixed the addition of the HTML5 default cache break string for assets -* Fixed default asset type assignment for files with upper-case file extensions -* Fixed support for Raspberry Pi -* Fixed `threadPool.onProgress` to dispatch in the proper foreground thread -* Fixed native `HTTPRequest` to calculate timeout from when requests run +- Updated Freetype to 2.7.1, compiled with Harfbuzz/PNG support enabled +- Added initial Adobe AIR backend support for multiple windows, alerts, etc +- Added `threadPool.onRun` to be notified when work is about to be run +- Added `ModuleHelper.addModuleSource` to improve JS modules from HXP projects +- Added initial Dockerfile script +- Added a polyfill for `performance.now()` to restore iPhone 4 HTML5 support +- Improved Raspberry Pi support by adding "Escape" as a default key to exit +- Improved support for non-premultiplied alpha in `imageDataUtil.gaussianBlur` +- Improved native `HTTPRequest` to size bytes initially based on Content-Length +- Improved support for Xcode 9.1 +- Improved support for combined characters in `TextLayout` +- Fixed setting of `MACOSX_DEPLOYMENT_TARGET` on macOS +- Fixed support for resolving iOS provisioning profiles for AIR/iOS on Windows +- Fixed the addition of the HTML5 default cache break string for assets +- Fixed default asset type assignment for files with upper-case file extensions +- Fixed support for Raspberry Pi +- Fixed `threadPool.onProgress` to dispatch in the proper foreground thread +- Fixed native `HTTPRequest` to calculate timeout from when requests run 5.6.0 (09/26/2017) ------------------ -* Added `lime.system.FileWatcher` for notifications of file events -* Added support for color output on the Windows 10 standard command prompt -* Added support for `lime config NAME VALUE` to add/set config values -* Added initial template support for `lime test winjs` for HTML5/UWP support -* Updated haxe.io.Bytes to match current official version -* Improved key events to always set the key modifier on alt/ctrl/shift key press -* Improved support for Adobe AIR iOS and Android builds -* Improved Android builds to minimize to background on back button and not exit -* Improved Linux target to build without HXCPP liblinuxcompat.a -* Improved support for setting `-dce` on the command-line -* Fixed support for setting `--window-minimized`, maximized and hidden using CLI -* Fixed escaping of spaces in Windows paths -* Fixed the behavior of `image.copyPixels` using an alpha image -* Fixed the class path order when embedding Flash assets in certain conditions -* Fixed support for Tizen HTML5 applications -* Fixed progress event update on HTML5 HTTPRequest uploads -* Fixed `ImageHelper.resizeImage` to properly handle null parameters +- Added `lime.system.FileWatcher` for notifications of file events +- Added support for color output on the Windows 10 standard command prompt +- Added support for `lime config NAME VALUE` to add/set config values +- Added initial template support for `lime test winjs` for HTML5/UWP support +- Updated haxe.io.Bytes to match current official version +- Improved key events to always set the key modifier on alt/ctrl/shift key press +- Improved support for Adobe AIR iOS and Android builds +- Improved Android builds to minimize to background on back button and not exit +- Improved Linux target to build without HXCPP liblinuxcompat.a +- Improved support for setting `-dce` on the command-line +- Fixed support for setting `--window-minimized`, maximized and hidden using CLI +- Fixed escaping of spaces in Windows paths +- Fixed the behavior of `image.copyPixels` using an alpha image +- Fixed the class path order when embedding Flash assets in certain conditions +- Fixed support for Tizen HTML5 applications +- Fixed progress event update on HTML5 HTTPRequest uploads +- Fixed `ImageHelper.resizeImage` to properly handle null parameters 5.5.0 (09/12/2017) ------------------ -* Added an instance-based API for cURL (such as `new CURL ()`) -* Added `` setting value -* Added generation of source map when minifying HTML5 on debug -* Deprecated `lime.net.curl.CURLEasy` in favor of `CURL` -* Updated tinyfiledialogs to 2.9.3 -* Updated bundled Google Closure Compiler to v20170806 -* Improved the functionality of `System.endianness` -* Improved Adobe AIR `deploy` command to generate a \*.bundle file -* Improved the behavior of native HTTPRequest for better memory management -* Fixed endianness issues in `image.setPixels` -* Fixed support for `image.copyPixels` using alpha image and offset point -* Fixed support for newer HXCPP, including dynamic libs only on Haxe 3.2.1 -* Fixed ability to exclude default architectures on builds -* Fixed support for `` on Android -* Fixed minor issues caused by detecting some AWD files as text +- Added an instance-based API for cURL (such as `new CURL ()`) +- Added `` setting value +- Added generation of source map when minifying HTML5 on debug +- Deprecated `lime.net.curl.CURLEasy` in favor of `CURL` +- Updated tinyfiledialogs to 2.9.3 +- Updated bundled Google Closure Compiler to v20170806 +- Improved the functionality of `System.endianness` +- Improved Adobe AIR `deploy` command to generate a \*.bundle file +- Improved the behavior of native HTTPRequest for better memory management +- Fixed endianness issues in `image.setPixels` +- Fixed support for `image.copyPixels` using alpha image and offset point +- Fixed support for newer HXCPP, including dynamic libs only on Haxe 3.2.1 +- Fixed ability to exclude default architectures on builds +- Fixed support for `` on Android +- Fixed minor issues caused by detecting some AWD files as text 5.4.0 (08/25/2017) ------------------ -* Added tooling for Adobe AIR (`lime test air`, `lime test windows -air`, etc) -* Added externs for Adobe AIR classes and types -* Added `` for choosing a custom haxelib repository path -* Added OpenGL ES 3 API support (currently enabled on Linux and Emscripten) -* Added support for setting `HAXELIB_PATH` environment variable in projects -* Changed the output directory to not include the build type by default -* Improved HTML5 to default images to canvas, not a typed array -* Improved HXP to handle `-nocolor`, `-verbose` and other compile flags -* Improved HXP to be able to update environment variables for build process -* Fixed tvOS target to use `` -* Fixed Android builds when using an Android SDK older than API 23 -* Fixed an issue when running command-line tools from a root directory -* Fixed UTF-8 `charCodeAt` when index is out of range -* Fixed the `strength` property of `ImageDataUtils.gaussianBlur` +- Added tooling for Adobe AIR (`lime test air`, `lime test windows -air`, etc) +- Added externs for Adobe AIR classes and types +- Added `` for choosing a custom haxelib repository path +- Added OpenGL ES 3 API support (currently enabled on Linux and Emscripten) +- Added support for setting `HAXELIB_PATH` environment variable in projects +- Changed the output directory to not include the build type by default +- Improved HTML5 to default images to canvas, not a typed array +- Improved HXP to handle `-nocolor`, `-verbose` and other compile flags +- Improved HXP to be able to update environment variables for build process +- Fixed tvOS target to use `` +- Fixed Android builds when using an Android SDK older than API 23 +- Fixed an issue when running command-line tools from a root directory +- Fixed UTF-8 `charCodeAt` when index is out of range +- Fixed the `strength` property of `ImageDataUtils.gaussianBlur` 5.3.0 (07/31/2017) ------------------ -* Added support for WebAssembly (`emscripten -webassembly` or `-wasm`) -* Added `lime -version` for simpler Lime version output -* Added `@:compiler` to add extra compiler arguments to HXP projects -* Updated howler.js to 2.0.4, plus an additional Firefox WebAudio patch -* Improved support for using Lime in local .haxelib directories -* Improved detection of default asset type in command-line tools -* Improved support for HTML5 -Dmodular builds -* Improved handling of error messages from howler.js -* Fixed support for asset libraries in Emscripten/WebAssembly target -* Fixed `lime create extension` to preserve `ANDROID_GRADLE_PLUGIN` variable -* Fixed support for preloading fonts on Safari +- Added support for WebAssembly (`emscripten -webassembly` or `-wasm`) +- Added `lime -version` for simpler Lime version output +- Added `@:compiler` to add extra compiler arguments to HXP projects +- Updated howler.js to 2.0.4, plus an additional Firefox WebAudio patch +- Improved support for using Lime in local .haxelib directories +- Improved detection of default asset type in command-line tools +- Improved support for HTML5 -Dmodular builds +- Improved handling of error messages from howler.js +- Fixed support for asset libraries in Emscripten/WebAssembly target +- Fixed `lime create extension` to preserve `ANDROID_GRADLE_PLUGIN` variable +- Fixed support for preloading fonts on Safari 5.2.1 (06/21/2017) ------------------ -* Improved HTTPRequest with default "Content-Type" headers when sending data -* Fixed case where HTML5 could preload sounds twice, unintentionally -* Fixed support for compiling HTML5 -Dmodular builds +- Improved HTTPRequest with default "Content-Type" headers when sending data +- Fixed case where HTML5 could preload sounds twice, unintentionally +- Fixed support for compiling HTML5 -Dmodular builds 5.2.0 (06/20/2017) ------------------ -* Added ability to override the target output directory -* Added `Assets.hasLibrary` to check if a given library is registered -* Improved webfonts to cache upon generation and not save in asset directory -* Updated JavaScript timers to use `performance.now()` instead of `new Date()` -* Fixed support for *.bundle directories which include "include.xml" -* Fixed `AssetLibrary` to preload non-embedded assets if set to preload -* Fixed an issue when converting non-String values to `UTF8String` -* Fixed an issue with Node http-server resolving properly to localhost -* Fixed support for `lime test linux -32` on 64-bit systems +- Added ability to override the target output directory +- Added `Assets.hasLibrary` to check if a given library is registered +- Improved webfonts to cache upon generation and not save in asset directory +- Updated JavaScript timers to use `performance.now()` instead of `new Date()` +- Fixed support for *.bundle directories which include "include.xml" +- Fixed `AssetLibrary` to preload non-embedded assets if set to preload +- Fixed an issue when converting non-String values to `UTF8String` +- Fixed an issue with Node http-server resolving properly to localhost +- Fixed support for `lime test linux -32` on 64-bit systems 5.1.0 (06/07/2017) ------------------ -* Added `lime.text.UTF8String` with unifill for handling UTF-8 text -* Added support for `Clipboard.onUpdate` on native and HTML5 -* Added initial support for HTML5 fullscreen -* Added initial support for `window.setIcon` and `window.title` on HTML5 -* Added support for 32-bit GL color depth on native platforms -* Added support for making 64-bit Windows builds -* Added support for automatically detecting latest Android build tools -* Added support for setting `` -* Added support for `` -* Added support for `` -* Updated Node http-server to version 0.10.0 -* Improved handling of crossOrigin requests on HTML5 for same-origin -* Improved the accuracy of `image.copyPixels` when using alpha image -* Improved performance of ObjectPool when constantly recycling objects -* Improved `image.setPixels` to accept bytes and offset -* Improved performance of creating a new Image with no fill color -* Fixed issue with OpenAL GC -* Fixed loading of some WAV files -* Fixed minor issues in using output of `lime display` for code completion -* Fixed semi-transparent fillRect on canvas-based Image -* Fixed minor issues with cURL +- Added `lime.text.UTF8String` with unifill for handling UTF-8 text +- Added support for `Clipboard.onUpdate` on native and HTML5 +- Added initial support for HTML5 fullscreen +- Added initial support for `window.setIcon` and `window.title` on HTML5 +- Added support for 32-bit GL color depth on native platforms +- Added support for making 64-bit Windows builds +- Added support for automatically detecting latest Android build tools +- Added support for setting `` +- Added support for `` +- Added support for `` +- Updated Node http-server to version 0.10.0 +- Improved handling of crossOrigin requests on HTML5 for same-origin +- Improved the accuracy of `image.copyPixels` when using alpha image +- Improved performance of ObjectPool when constantly recycling objects +- Improved `image.setPixels` to accept bytes and offset +- Improved performance of creating a new Image with no fill color +- Fixed issue with OpenAL GC +- Fixed loading of some WAV files +- Fixed minor issues in using output of `lime display` for code completion +- Fixed semi-transparent fillRect on canvas-based Image +- Fixed minor issues with cURL 5.0.3 (05/24/2017) ------------------ -* Reverted inclusion of custom haxelib build in Lime tools -* Support for wildcard versioning requires a compatible install of haxelib -* Added support for optional runtime overriding of haxelib script -* Improved handling of haxelib errors during HXML generation -* Fixed support for uploading larger byte objects using HTTPRequest -* Fixed support for config.rootPath +- Reverted inclusion of custom haxelib build in Lime tools +- Support for wildcard versioning requires a compatible install of haxelib +- Added support for optional runtime overriding of haxelib script +- Improved handling of haxelib errors during HXML generation +- Fixed support for uploading larger byte objects using HTTPRequest +- Fixed support for config.rootPath 5.0.2 (05/22/2017) ------------------ -* Improved support for finding versioned haxelib path when using haxelib git +- Improved support for finding versioned haxelib path when using haxelib git 5.0.1 (05/22/2017) ------------------ -* Fixed an issue with PathHelper.getHaxelib outside of Lime tools -* Fixed regressions in haxelib path resolution +- Fixed an issue with PathHelper.getHaxelib outside of Lime tools +- Fixed regressions in haxelib path resolution 5.0.0 (05/19/2017) ------------------ -* Updated the OpenGL bindings for better performance on HTML5 -* WebGL-specific signatures are now available using "WEBGL" suffix -* Added support for wildcard haxelib versions (such as "1.0.\*") -* Added a new joystick.onTrackballMove with both x and y values -* Added support for ThreadPool when there is no Application instance -* Added haxelib to Lime tools to support path resolution fixes -* Added ProjectXMLParser.fromFile for consistency -* Updated default SWF version to 17 to prevent common compile issues -* Removed deprecated config.assetsPrefix (use config.rootPath) -* Improved support for HXP projects on Windows -* Improved performance of image.copyPixels -* Improved the `lime create extension ` template -* Improved the behavior of Flash Player logging on Linux -* Improved memory use in Matrix4 and TextLayout -* Improved render event to allow canceling (avoids a screen flip) -* Improved `lime setup` to quiet the "no setup required" message -* Fixed dead-code-elimination with OpenGL extension classes -* Fixed support for >, <, >=, <= and == in XML "unless" attribute -* Fixed complete exit on Android when using the back button +- Updated the OpenGL bindings for better performance on HTML5 +- WebGL-specific signatures are now available using "WEBGL" suffix +- Added support for wildcard haxelib versions (such as "1.0.\*") +- Added a new joystick.onTrackballMove with both x and y values +- Added support for ThreadPool when there is no Application instance +- Added haxelib to Lime tools to support path resolution fixes +- Added ProjectXMLParser.fromFile for consistency +- Updated default SWF version to 17 to prevent common compile issues +- Removed deprecated config.assetsPrefix (use config.rootPath) +- Improved support for HXP projects on Windows +- Improved performance of image.copyPixels +- Improved the `lime create extension ` template +- Improved the behavior of Flash Player logging on Linux +- Improved memory use in Matrix4 and TextLayout +- Improved render event to allow canceling (avoids a screen flip) +- Improved `lime setup` to quiet the "no setup required" message +- Fixed dead-code-elimination with OpenGL extension classes +- Fixed support for >, <, >=, <= and == in XML "unless" attribute +- Fixed complete exit on Android when using the back button 4.1.0 (05/04/2017) ------------------ -* Updated SDL to latest development version -* Updated Freetype to 2.7.1 -* Updated Harfbuzz to 1.4.6 -* Updated Howler.js to 2.0.3 -* Added window.alwaysOnTop, with initial support on Windows and Linux -* Added WebP compatibility on HTML5, improved file format detection -* Added EXT_texture_compression_s3tc to GL extensions -* Added ability to specify architecture when performing iOS simulator builds -* Removed deprecated HTML meta for Google Chrome Frame -* Improved macro compile performance -* Improved asset manifests to embed when all of their assets are embedded -* Improved the web template for Flash for better relative URL resolution -* Improved support for OpenGL extensions when dead-code-elimination is enabled -* Improved the suspend/resume behavior on Android -* Improved System.endianness to return BIG_ENDIAN on Flash Player -* Improved file copying in tools to not copy templates that have not changed -* Improved Cairo bindings to return the same object reference when possible -* Improved OpenAL bindings to return the same object reference when possible -* Fixed an issue with exiting fullscreen on HTML5 -* Fixed an issue with escaped paths when generating Neko executables -* Fixed possible cases where paths could have been escaped twice in Haxe 3.3 -* Fixed support for GL.compressedTexImage on HTML5 -* Fixed CORS exception on HTML5 if there is no content-type header -* Fixed static initialization order of core lime.system.CFFI methods -* Fixed a dead-code-elimination issue in NativeHTTPRequest -* Fixed the Android Gradle Plugin setting in the Lime extension template +- Updated SDL to latest development version +- Updated Freetype to 2.7.1 +- Updated Harfbuzz to 1.4.6 +- Updated Howler.js to 2.0.3 +- Added window.alwaysOnTop, with initial support on Windows and Linux +- Added WebP compatibility on HTML5, improved file format detection +- Added EXT_texture_compression_s3tc to GL extensions +- Added ability to specify architecture when performing iOS simulator builds +- Removed deprecated HTML meta for Google Chrome Frame +- Improved macro compile performance +- Improved asset manifests to embed when all of their assets are embedded +- Improved the web template for Flash for better relative URL resolution +- Improved support for OpenGL extensions when dead-code-elimination is enabled +- Improved the suspend/resume behavior on Android +- Improved System.endianness to return BIG_ENDIAN on Flash Player +- Improved file copying in tools to not copy templates that have not changed +- Improved Cairo bindings to return the same object reference when possible +- Improved OpenAL bindings to return the same object reference when possible +- Fixed an issue with exiting fullscreen on HTML5 +- Fixed an issue with escaped paths when generating Neko executables +- Fixed possible cases where paths could have been escaped twice in Haxe 3.3 +- Fixed support for GL.compressedTexImage on HTML5 +- Fixed CORS exception on HTML5 if there is no content-type header +- Fixed static initialization order of core lime.system.CFFI methods +- Fixed a dead-code-elimination issue in NativeHTTPRequest +- Fixed the Android Gradle Plugin setting in the Lime extension template 4.0.3 (03/28/2017) ------------------ -* Added support for GL EXT_packed_depth_stencil -* Improved safety around DataPointer when performing arithmetic -* Improved Image.loadFromBytes when bytes are not a known image type -* Improved the performance of Image.fillRect in some cases +- Added support for GL EXT_packed_depth_stencil +- Improved safety around DataPointer when performing arithmetic +- Improved Image.loadFromBytes when bytes are not a known image type +- Improved the performance of Image.fillRect in some cases 4.0.2 (03/21/2017) ------------------ -* Added an internal transfer queue for limiting simultaneous HTML5 requests -* Added an internal thread pool for limiting simultaneous native HTTPRequests -* Fixed compilation support with newer Haxe releases on Raspberry Pi -* Fixed the default "end" argument value of ArrayBufferView subarray -* Fixed a performance regression in WebGL support -* Fixed native HTTPRequest so that it always returns on the correct thread -* Fixed path resolution to APK-based assets using HTTPRequest on Android -* Fixed "unused pattern" warning caused by duplicate constant in GL bindings -* Fixed a mismatch between intptr_t and uintptr_t (affecting Android) -* Fixed several Window properties when creating a new window without a config +- Added an internal transfer queue for limiting simultaneous HTML5 requests +- Added an internal thread pool for limiting simultaneous native HTTPRequests +- Fixed compilation support with newer Haxe releases on Raspberry Pi +- Fixed the default "end" argument value of ArrayBufferView subarray +- Fixed a performance regression in WebGL support +- Fixed native HTTPRequest so that it always returns on the correct thread +- Fixed path resolution to APK-based assets using HTTPRequest on Android +- Fixed "unused pattern" warning caused by duplicate constant in GL bindings +- Fixed a mismatch between intptr_t and uintptr_t (affecting Android) +- Fixed several Window properties when creating a new window without a config 4.0.1 (03/17/2017) ------------------ -* Improved error message when an asset library is not found -* Improved generated code performance when using ArrayBufferView -* Fixed some issues with incorrect OpenGL garbage collection -* Fixed AssetLibrary loadText to use text (not binary) loading on HTML5 -* Fixed support `` tag without using a "path" attribute -* Fixed premature loading of `embed="false"` assets on HTML5 -* Fixed missing bufferData API in WebGLContext -* Fixed OpenGL bindings to return null OpenGL objects if an ID is zero +- Improved error message when an asset library is not found +- Improved generated code performance when using ArrayBufferView +- Fixed some issues with incorrect OpenGL garbage collection +- Fixed AssetLibrary loadText to use text (not binary) loading on HTML5 +- Fixed support `` tag without using a "path" attribute +- Fixed premature loading of `embed="false"` assets on HTML5 +- Fixed missing bufferData API in WebGLContext +- Fixed OpenGL bindings to return null OpenGL objects if an ID is zero 4.0.0 (03/15/2017) ------------------ -* Added support for WebGL 2 APIs on HTML5 -* Recreated GL bindings in preparation for GLES3 support -* Added support for running different Lime tools to match project version -* Added WebGL, WebGL 2, GLES 2 and GLES 3 abstracts -* Added initial support for WebGL/GLES2 extension constants -* Added GL context, type and version properties -* Added window.displayMode for full-screen display mode switching -* Added lime.utils.DataPointer for managing native pointers -* Added lime.utils.BytePointer for Bytes + offset without a new typed array -* Added lime.utils.ObjectPool as a convenience API for object pooling -* Added support for `` for library packing -* Added support for loading \*.bundle directories as asset libraries -* Added support for `${meta.title}` and other project data in project.xml -* Added support for Cairo textPath -* Added support for multiple Lime embeds, rewrote HTML5 embed code -* Added asset type to verbose Preloader messages -* Added `-Dwebgl1` to use a WebGL 1 context instead of WebGL 2 on HTML5 -* Removed deprecated behaviors from Lime 3 -* Updated Gamepad mappings to support additional models -* Updated HTML5 window to dispatch resize event if parent element is resized -* Improved support for deferred loading of asset libraries -* Improved Asset error events, updated to throw errors when assets not found -* Improved handling of GL context loss on WebGL -* Improved behavior of asset manifests included as assets of another library -* Improved behavior of path groups for audioBuffer assets -* Improved error message if ANDROID_SDK or ANDROID_NDK_ROOT is not defined -* Fixed caching for HTML5 cache groups -* Fixed native HTTPRequest if file is not found or uses ~/ for home directory -* Fixed copying of files when a directory exists of the same name -* Fixed dispatch of Renderer.onRender when there is no context -* Fixed dispatch of Renderer.onContextLost on native platforms -* Fixed use of image.threshold when source is canvas or HTML5 image -* Fixed missing warning if `` is null -* Fixed `` to be relative to include.xml path -* Fixed `` to be relative to include.xml path -* Fixed case where assets could be processed as templates -* Fixed support for ATF textures on Flash target -* Fixed ID value for Joystick/Gamepad guid property -* Fixed double dispatch of preloader complete verbose message -* Fixed path of `-options` parameter when calling HXCPP +- Added support for WebGL 2 APIs on HTML5 +- Recreated GL bindings in preparation for GLES3 support +- Added support for running different Lime tools to match project version +- Added WebGL, WebGL 2, GLES 2 and GLES 3 abstracts +- Added initial support for WebGL/GLES2 extension constants +- Added GL context, type and version properties +- Added window.displayMode for full-screen display mode switching +- Added lime.utils.DataPointer for managing native pointers +- Added lime.utils.BytePointer for Bytes + offset without a new typed array +- Added lime.utils.ObjectPool as a convenience API for object pooling +- Added support for `` for library packing +- Added support for loading \*.bundle directories as asset libraries +- Added support for `${meta.title}` and other project data in project.xml +- Added support for Cairo textPath +- Added support for multiple Lime embeds, rewrote HTML5 embed code +- Added asset type to verbose Preloader messages +- Added `-Dwebgl1` to use a WebGL 1 context instead of WebGL 2 on HTML5 +- Removed deprecated behaviors from Lime 3 +- Updated Gamepad mappings to support additional models +- Updated HTML5 window to dispatch resize event if parent element is resized +- Improved support for deferred loading of asset libraries +- Improved Asset error events, updated to throw errors when assets not found +- Improved handling of GL context loss on WebGL +- Improved behavior of asset manifests included as assets of another library +- Improved behavior of path groups for audioBuffer assets +- Improved error message if ANDROID_SDK or ANDROID_NDK_ROOT is not defined +- Fixed caching for HTML5 cache groups +- Fixed native HTTPRequest if file is not found or uses ~/ for home directory +- Fixed copying of files when a directory exists of the same name +- Fixed dispatch of Renderer.onRender when there is no context +- Fixed dispatch of Renderer.onContextLost on native platforms +- Fixed use of image.threshold when source is canvas or HTML5 image +- Fixed missing warning if `` is null +- Fixed `` to be relative to include.xml path +- Fixed `` to be relative to include.xml path +- Fixed case where assets could be processed as templates +- Fixed support for ATF textures on Flash target +- Fixed ID value for Joystick/Gamepad guid property +- Fixed double dispatch of preloader complete verbose message +- Fixed path of `-options` parameter when calling HXCPP 3.7.4 (02/15/2017) ------------------ -* Improved AudioBuffer/Font/Image/Sound.loadFromFile to support URLs -* Deprecated AudioBuffer.fromURL and onload/onerror callbacks -* Added verbose log messages during asset library preload -* Fixed crash on iOS when rewinding or looping sounds +- Improved AudioBuffer/Font/Image/Sound.loadFromFile to support URLs +- Deprecated AudioBuffer.fromURL and onload/onerror callbacks +- Added verbose log messages during asset library preload +- Fixed crash on iOS when rewinding or looping sounds 3.7.3 (02/13/2017) ------------------ -* Improved support for Raspberry Pi -* Improved configuration for Gradle version on Android builds -* Fixed a crash in VorbisFile.fromBytes -* Fixed httpRequest.timeout to timeout only on opening a connection -* Fixed setting of system clipboard when using Clipboard.text on HTML5 -* Fixed Assets.getBytes for cached text assets -* Fixed the final progress value when using -Dsimulate-preloader -* Fixed valid image check when returning cached image assets -* Fixed a minor memory leak in System application directories -* Fixed filters and default file name in FileDialog -* Fixed AudioBuffer.loadFromFile on native for remote assets +- Improved support for Raspberry Pi +- Improved configuration for Gradle version on Android builds +- Fixed a crash in VorbisFile.fromBytes +- Fixed httpRequest.timeout to timeout only on opening a connection +- Fixed setting of system clipboard when using Clipboard.text on HTML5 +- Fixed Assets.getBytes for cached text assets +- Fixed the final progress value when using -Dsimulate-preloader +- Fixed valid image check when returning cached image assets +- Fixed a minor memory leak in System application directories +- Fixed filters and default file name in FileDialog +- Fixed AudioBuffer.loadFromFile on native for remote assets 3.7.2 (01/26/2017) ------------------ -* Reverted high-DPI HTML5 mouse scale change -* Improved the DPI values returned from display.dpi -* Fixed "Update to Recommended Settings" message on Xcode 8.2 +- Reverted high-DPI HTML5 mouse scale change +- Improved the DPI values returned from display.dpi +- Fixed "Update to Recommended Settings" message on Xcode 8.2 3.7.1 (01/25/2017) ------------------ -* Improved output of Flash Player log output -* Fixed minor issues with Flash Player preload logic -* Fixed use of AudioBuffer in multiple native AudioSource instances +- Improved output of Flash Player log output +- Fixed minor issues with Flash Player preload logic +- Fixed use of AudioBuffer in multiple native AudioSource instances 3.7.0 (01/24/2017) ------------------ -* Added `` (implies `` and ``) -* Added `` (will default to false in Lime 4) -* Added `-Dsimulate-preloader=3000` for simulating preload progress -* Improved Image.loadFromBase64/loadFromBytes/loadFromFile on HTML5 -* Improved Image.loadFromBytes/loadFromFile support on Flash target -* Improved support for "library.json" files that are not embedded -* Improved support for browsers that do not have context.isPointInPath -* Improved `lime setup linux` command for some newer environments -* Improved caching behavior of text assets in AssetLibrary -* Improved seeking behavior for AudioSource on native targets -* Improved preload behavior on Flash target -* Fixed metadata-based font embedding for Flash Player -* Fixed issues with Windows paths when building tools with Haxe 3.4 -* Fixed preloading of fonts similar to default sans-serif on HTML5 -* Fixed base path for assets loaded from non-default asset libraries -* Fixed scale of mouse events dispatched for high-DPI HTML5 windows +- Added `` (implies `` and ``) +- Added `` (will default to false in Lime 4) +- Added `-Dsimulate-preloader=3000` for simulating preload progress +- Improved Image.loadFromBase64/loadFromBytes/loadFromFile on HTML5 +- Improved Image.loadFromBytes/loadFromFile support on Flash target +- Improved support for "library.json" files that are not embedded +- Improved support for browsers that do not have context.isPointInPath +- Improved `lime setup linux` command for some newer environments +- Improved caching behavior of text assets in AssetLibrary +- Improved seeking behavior for AudioSource on native targets +- Improved preload behavior on Flash target +- Fixed metadata-based font embedding for Flash Player +- Fixed issues with Windows paths when building tools with Haxe 3.4 +- Fixed preloading of fonts similar to default sans-serif on HTML5 +- Fixed base path for assets loaded from non-default asset libraries +- Fixed scale of mouse events dispatched for high-DPI HTML5 windows 3.6.2 (01/20/2017) ------------------ -* Improved error when making a directory on an unavailable drive letter -* Fixed regression in support for HTML5 font preloading -* Fixed possible font overflow when embedding fonts on Flash target -* Fixed crash on Neko when using AudioSource with no AudioBuffer +- Improved error when making a directory on an unavailable drive letter +- Fixed regression in support for HTML5 font preloading +- Fixed possible font overflow when embedding fonts on Flash target +- Fixed crash on Neko when using AudioSource with no AudioBuffer 3.6.1 (01/18/2017) ------------------ -* Added streaming audio support to AudioSource -* Fixed issues in bytesLoaded/bytesTotal calculation -* Fixed a regression in support for static-linking -* Fixed a regression in support for lime.utils.JNI +- Added streaming audio support to AudioSource +- Fixed issues in bytesLoaded/bytesTotal calculation +- Fixed a regression in support for static-linking +- Fixed a regression in support for lime.utils.JNI 3.6.0 (01/16/2017) ------------------ -* Moved "lime.audio" to "lime.media" -* Added Vorbis bindings under "lime.media.codecs.vorbis" -* Added lime.ui.ScanCode, with conversion support to/from KeyCode on native -* Added tool support for the "--no-output" argument -* Migrated from NFD to tinyfiledialogs for better dialog support -* Made window.close cancelable on desktop platforms -* Updated libjpeg to 9b -* Updated howler.js to 2.0.2 -* Improved support for Haxe 3.4 -* Improved support for progress events while preloading -* Fixed force install when deploying to Android (API 16+ devices) -* Fixed an invalid state when returning from background on Android -* Fixed playback of a single audio buffer multiple times on HTML5 -* Fixed initial volume level in AudioSource on HTML5 -* Fixed a regression in the default architecture list for iOS -* Fixed merging of multiple `` tags in project files -* Fixed a possible crash when retrieving OpenGL strings -* Fixed the default template for HTML5 when multiple projects are embedded -* Fixed support for non-preloaded assets on HTML5 -* Fixed support for image.copyChannel on HTML5 when using WebGL -* Fixed support for command-line arguments with "lime rebuild" +- Moved "lime.audio" to "lime.media" +- Added Vorbis bindings under "lime.media.codecs.vorbis" +- Added lime.ui.ScanCode, with conversion support to/from KeyCode on native +- Added tool support for the "--no-output" argument +- Migrated from NFD to tinyfiledialogs for better dialog support +- Made window.close cancelable on desktop platforms +- Updated libjpeg to 9b +- Updated howler.js to 2.0.2 +- Improved support for Haxe 3.4 +- Improved support for progress events while preloading +- Fixed force install when deploying to Android (API 16+ devices) +- Fixed an invalid state when returning from background on Android +- Fixed playback of a single audio buffer multiple times on HTML5 +- Fixed initial volume level in AudioSource on HTML5 +- Fixed a regression in the default architecture list for iOS +- Fixed merging of multiple `` tags in project files +- Fixed a possible crash when retrieving OpenGL strings +- Fixed the default template for HTML5 when multiple projects are embedded +- Fixed support for non-preloaded assets on HTML5 +- Fixed support for image.copyChannel on HTML5 when using WebGL +- Fixed support for command-line arguments with "lime rebuild" 3.5.2 (12/19/2016) ------------------ -* Fixed issues related to @:bitmap, @:file and @:sound -* Fixed support for HTML5 font preloading -* Fixed issue with HTTPRequest and IE 11 -* Fixed an issue when merging multiple project.config values -* Reverted bytes changes to resolve C++ GC issues +- Fixed issues related to @:bitmap, @:file and @:sound +- Fixed support for HTML5 font preloading +- Fixed issue with HTTPRequest and IE 11 +- Fixed an issue when merging multiple project.config values +- Reverted bytes changes to resolve C++ GC issues 3.5.1 (12/16/2016) ------------------ -* Made major changes to Assets and the behavior of asset libraries -* Made progress on a better asset manifest system -* Made significant improvements to the iOS project templates -* Moved lime.Assets to lime.utils.Assets -* Added lime.utils.AssetLibrary, lime.utils.AssetType, lime.utils.AssetManifest -* Added static "loadFrom" constructors for core types -* Improved C++ performance on debug builds, added -Dlime-debug -* Updated CFFI bytes to better support C# target -* Fixed the 'cannot find build target "by"' error with current Haxe releases -* Fixed support for *.hxp projects -* Fixed some compile errors when core types were used in macros -* Fixed a minor issue with HTTPRequest on HTML5 -* Fixed Android template so READ\_PHONE\_STATE is not a required permission -* Fixed support for `` -* Fixed a regression with the quality of generated SVG icons +- Made major changes to Assets and the behavior of asset libraries +- Made progress on a better asset manifest system +- Made significant improvements to the iOS project templates +- Moved lime.Assets to lime.utils.Assets +- Added lime.utils.AssetLibrary, lime.utils.AssetType, lime.utils.AssetManifest +- Added static "loadFrom" constructors for core types +- Improved C++ performance on debug builds, added -Dlime-debug +- Updated CFFI bytes to better support C# target +- Fixed the 'cannot find build target "by"' error with current Haxe releases +- Fixed support for *.hxp projects +- Fixed some compile errors when core types were used in macros +- Fixed a minor issue with HTTPRequest on HTML5 +- Fixed Android template so READ\_PHONE\_STATE is not a required permission +- Fixed support for `` +- Fixed a regression with the quality of generated SVG icons 3.5.0 (12/07/2016) ------------------ -* Significantly improved lime.net.HTTPRequest -* Added support for lime.system.Clipboard on HTML5 -* Added System.openURL to launch a website externally -* Added System.openFile to open a file using a system default application -* Added -nolaunch option for HTML5 "test" command -* Added support for `` for iOS -* Updated SDL to dev version to fix Linux keyboard events -* Updated lime.app.Future with better progress events -* Updated to initialize WebGL2 on HTML5, when available -* Refactored certificate storage in HXProject -* Improved the parsing and merge support for default Lime config -* Improved the GL context in anticipation for GLES3/WebGL2 support -* Improved HTML5 mouse events to allow canceling -* Improved auto-build number detection to support SVN -* Improved support for toggling window.resizable on native -* Fixed audioBuffer.dispose for Howler.js buffers -* Fixed use of deprecated APIs in lime.ui.Haptic implementation on iOS -* Fixed use of deprecated APIs in accelerometer implementation on iOS -* Fixed crash when resuming iOS applications from the background -* Fixed crash if an asset manifest is not found and live reloading is enabled -* Fixed handling of the default framebuffer on iOS -* Fixed handling of \*.jpeg file extension when making Flash builds -* Fixed an issue in bytes handling for C# -* Fixed the behavior of window onEnter/onLeave on DOM -* Fixed the behavior of image.scroll -* Fixed garbage collection for lime.audio.openal.ALSource -* Fixed incorrect window scale calculation on the iPhone Plus -* Fixed some standard APIs when making modular HTML5 builds -* Fixed crash when setting window.title -* Fixed the return value of gl.shaderInfoLog on some platforms -* Fixed the behavior of Event.ACTIVATE when resuming on iOS -* Fixed missing input event initially on HTML5 +- Significantly improved lime.net.HTTPRequest +- Added support for lime.system.Clipboard on HTML5 +- Added System.openURL to launch a website externally +- Added System.openFile to open a file using a system default application +- Added -nolaunch option for HTML5 "test" command +- Added support for `` for iOS +- Updated SDL to dev version to fix Linux keyboard events +- Updated lime.app.Future with better progress events +- Updated to initialize WebGL2 on HTML5, when available +- Refactored certificate storage in HXProject +- Improved the parsing and merge support for default Lime config +- Improved the GL context in anticipation for GLES3/WebGL2 support +- Improved HTML5 mouse events to allow canceling +- Improved auto-build number detection to support SVN +- Improved support for toggling window.resizable on native +- Fixed audioBuffer.dispose for Howler.js buffers +- Fixed use of deprecated APIs in lime.ui.Haptic implementation on iOS +- Fixed use of deprecated APIs in accelerometer implementation on iOS +- Fixed crash when resuming iOS applications from the background +- Fixed crash if an asset manifest is not found and live reloading is enabled +- Fixed handling of the default framebuffer on iOS +- Fixed handling of \*.jpeg file extension when making Flash builds +- Fixed an issue in bytes handling for C# +- Fixed the behavior of window onEnter/onLeave on DOM +- Fixed the behavior of image.scroll +- Fixed garbage collection for lime.audio.openal.ALSource +- Fixed incorrect window scale calculation on the iPhone Plus +- Fixed some standard APIs when making modular HTML5 builds +- Fixed crash when setting window.title +- Fixed the return value of gl.shaderInfoLog on some platforms +- Fixed the behavior of Event.ACTIVATE when resuming on iOS +- Fixed missing input event initially on HTML5 3.4.1 (11/01/2016) ------------------ -* Fixed order of Assets.registerLibrary and app.onPreloaderComplete -* Added a workaround for HAXE_STD_PATH error on -Dmodular +- Fixed order of Assets.registerLibrary and app.onPreloaderComplete +- Added a workaround for HAXE_STD_PATH error on -Dmodular 3.4.0 (10/31/2016) ------------------ -* Moved Lime config from ~/.hxcpp_config.xml to ~/.lime/config.xml -* Added a new "lime config" command to print the current config -* Added "lime config VARNAME" command to print a value from the current config -* Added initial support for modular HTML5 builds (generates separate lime.js) -* Added support for comparisons in project XML (like ${haxe >= 3.2.1}) -* Added lime.ui.Haptic for initial support of vibrate on iOS/Android -* Added `` to project XML for info/warning/error/verbose messages -* Added a build-time error if Haxe is less than 3.2.0 -* Added support for GIT-based meta build number value -* Added initial high-DPI support for HTML5 -* Updated SDL to version 2.0.5 -* Improved support for Android immersive mode -* Improved idle performance on macOS -* Improved Gradle template to output APK filenames based on build type -* Improved verbose messages for embedded fonts -* Removed Neko template binaries, updated tools to use host version -* Fixed IPHONE_VER issues with certain versions of HXCPP -* Fixed iOS device deployment on macOS Sierra -* Fixed iOS simulator deployment on macOS Sierra -* Fixed node.js HTTP server support on macOS Sierra -* Fixed duplicate symbol error on iOS -* Fixed support for older CPUs without SSE4 instruction support -* Fixed crash on negative seek position for HTML5 AudioSource -* Fixed initial gain and position when playing HTML5 AudioSource sound -* Fixed compatibility issues with current Haxe development versions +- Moved Lime config from ~/.hxcpp_config.xml to ~/.lime/config.xml +- Added a new "lime config" command to print the current config +- Added "lime config VARNAME" command to print a value from the current config +- Added initial support for modular HTML5 builds (generates separate lime.js) +- Added support for comparisons in project XML (like ${haxe >= 3.2.1}) +- Added lime.ui.Haptic for initial support of vibrate on iOS/Android +- Added `` to project XML for info/warning/error/verbose messages +- Added a build-time error if Haxe is less than 3.2.0 +- Added support for GIT-based meta build number value +- Added initial high-DPI support for HTML5 +- Updated SDL to version 2.0.5 +- Improved support for Android immersive mode +- Improved idle performance on macOS +- Improved Gradle template to output APK filenames based on build type +- Improved verbose messages for embedded fonts +- Removed Neko template binaries, updated tools to use host version +- Fixed IPHONE_VER issues with certain versions of HXCPP +- Fixed iOS device deployment on macOS Sierra +- Fixed iOS simulator deployment on macOS Sierra +- Fixed node.js HTTP server support on macOS Sierra +- Fixed duplicate symbol error on iOS +- Fixed support for older CPUs without SSE4 instruction support +- Fixed crash on negative seek position for HTML5 AudioSource +- Fixed initial gain and position when playing HTML5 AudioSource sound +- Fixed compatibility issues with current Haxe development versions 3.3.0 (10/10/2016) ----------------- -* Added Future.ready and Future.result -* Added AudioBuffer.loadFromFile and AudioBuffer.loadFromFiles -* Added favicon support to HTML5 builds -* Added automatic garbage collection to OpenAL bindings -* Improved the behavior of AudioSource, added Howler.js for HTML5 -* Improved CFFI bindings to prevent early GC of bytes -* Improved the behavior of \*.hxp project files -* Improved support for the C# target -* Improved `` to allow a value of 0 -* Improved support for "-lib lime" from plain HXML -* Implemented relative mouse movement events for Flash and HTML5 -* Implemented Locale support for Android -* Updated the behavior of "lime run" to imply "trace" (unless "-notrace") -* Updated Android template to allow submission to non-touchscreen devices -* Fixed support for `` on Android -* Fixed the value of Assets.isLocal for certain non-embedded assets -* Fixed an issue affecting touch events after an HTML5 build was rotated -* Fixed use of a custom HAXELIB_PATH for iOS builds (in Xcode) -* Fixed numpad key values in HTML5 -* Fixed C++ casting when converting openfl.Vector to Float32Array -* Fixed support for `` -* Fixed Android compilation using debug +- Added Future.ready and Future.result +- Added AudioBuffer.loadFromFile and AudioBuffer.loadFromFiles +- Added favicon support to HTML5 builds +- Added automatic garbage collection to OpenAL bindings +- Improved the behavior of AudioSource, added Howler.js for HTML5 +- Improved CFFI bindings to prevent early GC of bytes +- Improved the behavior of \*.hxp project files +- Improved support for the C# target +- Improved `` to allow a value of 0 +- Improved support for "-lib lime" from plain HXML +- Implemented relative mouse movement events for Flash and HTML5 +- Implemented Locale support for Android +- Updated the behavior of "lime run" to imply "trace" (unless "-notrace") +- Updated Android template to allow submission to non-touchscreen devices +- Fixed support for `` on Android +- Fixed the value of Assets.isLocal for certain non-embedded assets +- Fixed an issue affecting touch events after an HTML5 build was rotated +- Fixed use of a custom HAXELIB_PATH for iOS builds (in Xcode) +- Fixed numpad key values in HTML5 +- Fixed C++ casting when converting openfl.Vector to Float32Array +- Fixed support for `` +- Fixed Android compilation using debug 3.2.1 (09/20/2016) ------------------ -* Fixed an issue when GC was executed from another thread +- Fixed an issue when GC was executed from another thread 3.2.0 (09/19/2016) ------------------ -* Updated to support Xcode 8 and iOS 10 -* Added lime.system.Locale -* Added initial changes to support the C# target -* Updated to OpenAL-Soft 1.17.2 -* Cleaned up some API paths with GC optimizations -* Changed macOS to use OpenAL.framework, not OpenAL-Soft -* Changed Android to use the standard OpenAL-Soft release -* Improved suspend/resume support for Android audio -* Improved support for `lime setup` on Linux -* Improved CADisplayLink support for iOS -* Improved the behavior of ColorMatrix -* Fixed some crash issues in lime.system.System -* Fixed setting of window.title -* Fixed an issue with the Android NDK and debuggable=false -* Fixed a possible crash when using multiple windows -* Fixed the Android template for `lime create extension` -* Corrected support for high DPI windows +- Updated to support Xcode 8 and iOS 10 +- Added lime.system.Locale +- Added initial changes to support the C# target +- Updated to OpenAL-Soft 1.17.2 +- Cleaned up some API paths with GC optimizations +- Changed macOS to use OpenAL.framework, not OpenAL-Soft +- Changed Android to use the standard OpenAL-Soft release +- Improved suspend/resume support for Android audio +- Improved support for `lime setup` on Linux +- Improved CADisplayLink support for iOS +- Improved the behavior of ColorMatrix +- Fixed some crash issues in lime.system.System +- Fixed setting of window.title +- Fixed an issue with the Android NDK and debuggable=false +- Fixed a possible crash when using multiple windows +- Fixed the Android template for `lime create extension` +- Corrected support for high DPI windows 3.1.0 (08/29/2016) ------------------ -* Switched from Ant to Gradle for Android builds -* Added workarounds for some Haxe 3.3.0-rc1 issues -* Added support for hidden windows on the desktop -* Improved HTML5 mouse move by ignoring repeat events -* Fixed issues in ArrayBuffer when values were null -* Fixed a cross-origin issue that affected some browsers -* Fixed support for System directories on Android -* Fixed null fromBytes/fromImage conversion +- Switched from Ant to Gradle for Android builds +- Added workarounds for some Haxe 3.3.0-rc1 issues +- Added support for hidden windows on the desktop +- Improved HTML5 mouse move by ignoring repeat events +- Fixed issues in ArrayBuffer when values were null +- Fixed a cross-origin issue that affected some browsers +- Fixed support for System directories on Android +- Fixed null fromBytes/fromImage conversion 3.0.3 (07/27/2016) ------------------ -* Improved "lime test flash -web" behavior to use HTTP server -* Fixed an issue with Neko native byte resizing +- Improved "lime test flash -web" behavior to use HTTP server +- Fixed an issue with Neko native byte resizing 3.0.2 (07/22/2016) ------------------ -* Added lime.utils.compress.* Deflate, GZip, LZMA and Zlib -* Added -Dcairo to force use of Cairo software rendering on native -* Deprecated lime.utils.LZMA -* Fixed issue where assets were not found on Linux +- Added lime.utils.compress.* Deflate, GZip, LZMA and Zlib +- Added -Dcairo to force use of Cairo software rendering on native +- Deprecated lime.utils.LZMA +- Fixed issue where assets were not found on Linux 3.0.1 (07/20/2016) ------------------ -* Improved the exclude/include filter behavior on `` tags -* Fixed an issue that caused Window to duplicate event dispatches -* Fixed the name of generated folder for HTML5 output -* Fixed support for OpenAL getSource3f +- Improved the exclude/include filter behavior on `` tags +- Fixed an issue that caused Window to duplicate event dispatches +- Fixed the name of generated folder for HTML5 output +- Fixed support for OpenAL getSource3f 3.0.0 (07/08/2016) ------------------ -* Changed to different build directories for release/debug/final -* Added support for transparent HTML5 windows -* Added support for cairo.showGlyphs -* Added garbage collection to the OpenGL bindings -* Added audioSource.position for panning -* Improved the behavior of Image when using WebGL -* Improved the behavior of the HTML5 cache string -* Improved the Flash target to embed unsupported audio assets -* Improved support for integer positioning of unscaled HTML5 content -* Updated the SVG tool using the latest SVG/OpenFL versions -* Updated the module system to be more resilient to API changes -* Updated the iOS plist for newer app store submission guidelines -* Updated the HTML5 canvas to allow for premultiplied alpha -* Integrated changes to improve tvOS support -* Fixed issues in the Cairo bindings for improved Neko support -* Fixed image.copyPixels when using a negative destination -* Fixed the fillRect behavior when using alpha on native -* Fixed an issue with PNG encoding on HTML5 -* Fixed an issue in typed arrays where offset/length were ignored -* Fixed a crash in ExternalInterface -* Fixed a case where displayInfo.currentMode is not active yet +- Changed to different build directories for release/debug/final +- Added support for transparent HTML5 windows +- Added support for cairo.showGlyphs +- Added garbage collection to the OpenGL bindings +- Added audioSource.position for panning +- Improved the behavior of Image when using WebGL +- Improved the behavior of the HTML5 cache string +- Improved the Flash target to embed unsupported audio assets +- Improved support for integer positioning of unscaled HTML5 content +- Updated the SVG tool using the latest SVG/OpenFL versions +- Updated the module system to be more resilient to API changes +- Updated the iOS plist for newer app store submission guidelines +- Updated the HTML5 canvas to allow for premultiplied alpha +- Integrated changes to improve tvOS support +- Fixed issues in the Cairo bindings for improved Neko support +- Fixed image.copyPixels when using a negative destination +- Fixed the fillRect behavior when using alpha on native +- Fixed an issue with PNG encoding on HTML5 +- Fixed an issue in typed arrays where offset/length were ignored +- Fixed a crash in ExternalInterface +- Fixed a case where displayInfo.currentMode is not active yet 2.9.1 (03/28/2016) ------------------ -* Added automatic support for mouse capture when dragging -* Added initial support for `` -* Added window.onDropFile, window.maximized -* Added a missing dependency in the iOS project template -* Added a polyfill for context.isPointInStroke (for IE support) -* Added a flag to disable "allow-high-dpi" support -* Improved support for Assets.loadBytes on Flash -* Fixed some minor memory leaks when allocating CFFI strings -* Fixed a rare crash in the tools when `haxelib path` does not work -* Fixed the name suffix for Windows builds on newer HXCPP versions -* Fixed an issue where Cairo could render text at the wrong size -* Fixed the default company meta to be blank instead of a dummy value -* Fixed the window position and size to update after fullscreen +- Added automatic support for mouse capture when dragging +- Added initial support for `` +- Added window.onDropFile, window.maximized +- Added a missing dependency in the iOS project template +- Added a polyfill for context.isPointInStroke (for IE support) +- Added a flag to disable "allow-high-dpi" support +- Improved support for Assets.loadBytes on Flash +- Fixed some minor memory leaks when allocating CFFI strings +- Fixed a rare crash in the tools when `haxelib path` does not work +- Fixed the name suffix for Windows builds on newer HXCPP versions +- Fixed an issue where Cairo could render text at the wrong size +- Fixed the default company meta to be blank instead of a dummy value +- Fixed the window position and size to update after fullscreen 2.9.0 (01/22/2016) ------------------ -* Updated to SDL 2.0.4 -* Updated to Cairo 1.14.6 and pixman 0.32.8 -* Changed default Android SDK version to 19 (enables immersive mode) -* Added initial support for display.dpi -* Added initial support for window.borderless and window.resizable -* Added initial support for renderer.readPixels -* Added support for image.threshold -* Added open directory support to file dialog -* Added support for stopping propagation of browser keyboard events -* Added support for environment variables in if/unless conditionals -* Added support for variable substitution in if/unless conditionals -* Added MIPS and MIPSEL to architectures in tools -* Improved guards against using lime.* classes with legacy -* Improved support for the newer Android NDK -* Improved handling of reference leaks in JNI access -* Removed @:finalizer support, due to issues it caused -* Fixed compatibility with HXCPP changes regarding Visual Studio 2015 -* Fixed support for window.display on scaled windows -* Fixed a tool crash when using an unrecognized -armvX flag +- Updated to SDL 2.0.4 +- Updated to Cairo 1.14.6 and pixman 0.32.8 +- Changed default Android SDK version to 19 (enables immersive mode) +- Added initial support for display.dpi +- Added initial support for window.borderless and window.resizable +- Added initial support for renderer.readPixels +- Added support for image.threshold +- Added open directory support to file dialog +- Added support for stopping propagation of browser keyboard events +- Added support for environment variables in if/unless conditionals +- Added support for variable substitution in if/unless conditionals +- Added MIPS and MIPSEL to architectures in tools +- Improved guards against using lime.* classes with legacy +- Improved support for the newer Android NDK +- Improved handling of reference leaks in JNI access +- Removed @:finalizer support, due to issues it caused +- Fixed compatibility with HXCPP changes regarding Visual Studio 2015 +- Fixed support for window.display on scaled windows +- Fixed a tool crash when using an unrecognized -armvX flag 2.8.3 (01/02/2016) ------------------ -* Improved support for the latest Android NDK -* Improved cross-domain image loading on HTML5 -* Improved support for rebuilding and using tools without haxelib -* Ensured that OpenAL is disabled in static builds by default -* Fixed support for the current Haxe development build -* Fixed the setup command to ensure all requested dependencies -* Fixed a compile error when using `` and an empty path -* Fixed the -notrace flag (to disable "trace" on "test" commands) +- Improved support for the latest Android NDK +- Improved cross-domain image loading on HTML5 +- Improved support for rebuilding and using tools without haxelib +- Ensured that OpenAL is disabled in static builds by default +- Fixed support for the current Haxe development build +- Fixed the setup command to ensure all requested dependencies +- Fixed a compile error when using `` and an empty path +- Fixed the -notrace flag (to disable "trace" on "test" commands) 2.8.2 (12/16/2015) ------------------ -* Enabled WebGL by default on HTML5 -* Added support for Lime event canceling -* Added default keyboard shortcuts for toggling fullscreen -* Added default Android back button behavior to quit -* Added support for `` on HTML5 template -* Changed iOS default system font path to be more generic -* Fixed issues with OGG decoding on newer Android NDK -* Fixed AudioSource complete event when setting currentTime or length -* Fixed minor issue compiling Neko Windows binaries from Linux -* Minor updates to the default Android ADB output filter -* Updated ANGLE binaries to resolve ALT + Enter fullscreen issue -* Fixed font paths on iOS (legacy) +- Enabled WebGL by default on HTML5 +- Added support for Lime event canceling +- Added default keyboard shortcuts for toggling fullscreen +- Added default Android back button behavior to quit +- Added support for `` on HTML5 template +- Changed iOS default system font path to be more generic +- Fixed issues with OGG decoding on newer Android NDK +- Fixed AudioSource complete event when setting currentTime or length +- Fixed minor issue compiling Neko Windows binaries from Linux +- Minor updates to the default Android ADB output filter +- Updated ANGLE binaries to resolve ALT + Enter fullscreen issue +- Fixed font paths on iOS (legacy) 2.8.1 (12/09/2015) ------------------ -* Disable ANGLE by default on Windows, need to do additional testing -* Added support for optional haxelib references in XML -* Fixed an issue with incorrect joystick IDs on connect +- Disable ANGLE by default on Windows, need to do additional testing +- Added support for optional haxelib references in XML +- Fixed an issue with incorrect joystick IDs on connect 2.8.0 (12/07/2015) ------------------ -* Removed lime.utils.ByteArray in favor of Haxe (3.2+) Bytes -* Enabled ANGLE on Windows builds by default -* Restored compatibility with Windows XP -* Added support for HTML5 gamepad/joystick events -* Removed lime.net.URLLoader, added HTTPRequest as a temporary patch -* Added cache-break support to HTML5 based on each build -* Fixed use of 32-bit Windows builds on recent HXCPP versions -* Fixed support for correct touch event coordinates in HTML5 fullscreen -* Fixed importing of lime.system.JNI on platforms other than Android -* Fixed an issue that could cause native crashes on null Vector2 values -* Fixed embed of runtime-generate asset files -* Fixed default font paths on new versions of iOS (legacy) +- Removed lime.utils.ByteArray in favor of Haxe (3.2+) Bytes +- Enabled ANGLE on Windows builds by default +- Restored compatibility with Windows XP +- Added support for HTML5 gamepad/joystick events +- Removed lime.net.URLLoader, added HTTPRequest as a temporary patch +- Added cache-break support to HTML5 based on each build +- Fixed use of 32-bit Windows builds on recent HXCPP versions +- Fixed support for correct touch event coordinates in HTML5 fullscreen +- Fixed importing of lime.system.JNI on platforms other than Android +- Fixed an issue that could cause native crashes on null Vector2 values +- Fixed embed of runtime-generate asset files +- Fixed default font paths on new versions of iOS (legacy) 2.7.0 (10/28/2015) ------------------ -* Added a minimum version check for OpenGL (software fallback otherwise) -* Improved the consistency of frame time on native platforms -* Fixed an issue where Android applications would crash on unfound files -* Updated the Neko template for Lime legacy builds +- Added a minimum version check for OpenGL (software fallback otherwise) +- Improved the consistency of frame time on native platforms +- Fixed an issue where Android applications would crash on unfound files +- Updated the Neko template for Lime legacy builds 2.6.9 (10/15/2015) ------------------ -* Fixed an issue with certain predictive text keyboards on Android -* Fixed an issue where ImageBuffer did not update after certain changes -* Fixed a red tint that occurred on some mobile graphics -* Fixed a crash on closing applications on OS X 10.11 due to OpenAL -* Fixed an issue with VERIFY_HOST in the cURL bindings -* Additional fixes for tvOS compatibility -* Made minor template updates -* Fixed the default virtual keyboard type on BlackBerry (legacy) +- Fixed an issue with certain predictive text keyboards on Android +- Fixed an issue where ImageBuffer did not update after certain changes +- Fixed a red tint that occurred on some mobile graphics +- Fixed a crash on closing applications on OS X 10.11 due to OpenAL +- Fixed an issue with VERIFY_HOST in the cURL bindings +- Additional fixes for tvOS compatibility +- Made minor template updates +- Fixed the default virtual keyboard type on BlackBerry (legacy) 2.6.8 (10/05/2015) ------------------ -* Updated to a new SDL development version -* Added window.scale, window size and mouse events are in points -* Added Lime Joystick events (alongside Gamepad events) -* Added JPEG and PNG encode support for HTML5 -* Improved tooling support for tvOS builds +- Updated to a new SDL development version +- Added window.scale, window size and mouse events are in points +- Added Lime Joystick events (alongside Gamepad events) +- Added JPEG and PNG encode support for HTML5 +- Improved tooling support for tvOS builds 2.6.7 (10/02/2015) ------------------ -* Added initial changes to support Apple tvOS -* Added System.allowScreenTimeout to allow screensaver/sleep -* Updated CFFI to fix "hx_register_prim" issue on Android -* Improved "lime setup linux" -* Fixed preload when the same asset is listed twice -* Fixed an issue with importing lime.Assets in legacy builds +- Added initial changes to support Apple tvOS +- Added System.allowScreenTimeout to allow screensaver/sleep +- Updated CFFI to fix "hx_register_prim" issue on Android +- Improved "lime setup linux" +- Fixed preload when the same asset is listed twice +- Fixed an issue with importing lime.Assets in legacy builds 2.6.6 (09/24/2015) ------------------ -* Patch support for static C++ builds without use of HXCPP dev -* Fixed a crash that could occur in Flixel 3.x +- Patch support for static C++ builds without use of HXCPP dev +- Fixed a crash that could occur in Flixel 3.x 2.6.5 (09/23/2015) ------------------ -* Improved automatic garbage collection for native references -* Removed Cairo reference/destroy (handled internally now) -* Added lime.system.CFFIPointer -* Added *.fla to default exclude asset filter -* Disabled ENABLE_BITCODE on iOS by default -* Fixed an issue with Image.fromBitmapData when using OpenFL -* Fixed a minor issue with copyPixels on Firefox +- Improved automatic garbage collection for native references +- Removed Cairo reference/destroy (handled internally now) +- Added lime.system.CFFIPointer +- Added *.fla to default exclude asset filter +- Disabled ENABLE_BITCODE on iOS by default +- Fixed an issue with Image.fromBitmapData when using OpenFL +- Fixed a minor issue with copyPixels on Firefox 2.6.4 (09/21/2015) ------------------ -* Changed cURL bindings to use Bytes instead of String for callbacks -* Fixed iOS support for CFFI prime (requires HXCPP update) -* Reverted SDL2 version to fix regression in iOS window size -* Disabled Cairo finalizer (for now) to resolve some crash problems -* Reduced "unreachable code" warnings in Firefox -* Fixed iOS multitouch behavior (legacy) +- Changed cURL bindings to use Bytes instead of String for callbacks +- Fixed iOS support for CFFI prime (requires HXCPP update) +- Reverted SDL2 version to fix regression in iOS window size +- Disabled Cairo finalizer (for now) to resolve some crash problems +- Reduced "unreachable code" warnings in Firefox +- Fixed iOS multitouch behavior (legacy) 2.6.3 (09/19/2015) ------------------ -* Added initial support for CFFI-based finalizer callbacks -* Added initial accelerometer support -* Fixed an issue with erratic mouse values on Mac -* Fixed a minor issue with touch events -* Updated to a newer SDL development version -* Improved the handling of alpha when using image.setPixel -* Updated System.exit to go to background on Android if not an error -* Improved dirty logic with Image pixel operations -* Added an optimization for repeated Font path lookups -* Improved support for non-US keyboard layouts (legacy) +- Added initial support for CFFI-based finalizer callbacks +- Added initial accelerometer support +- Fixed an issue with erratic mouse values on Mac +- Fixed a minor issue with touch events +- Updated to a newer SDL development version +- Improved the handling of alpha when using image.setPixel +- Updated System.exit to go to background on Android if not an error +- Improved dirty logic with Image pixel operations +- Added an optimization for repeated Font path lookups +- Improved support for non-US keyboard layouts (legacy) 2.6.2 (09/08/2015) ------------------ -* Added support for Raspberry Pi 2 -* Added lime.app.Future/lime.app.Promise -* Migrated asynchronous lime.Assets calls to use futures -* Added lime.system.CFFI and a new @:cffi macro to use prime -* Migrated Lime CFFI bindings to use new (faster) prime bindings -* Added window.alert (taskbar flash, optional message popup) -* Set the "lime" shortcut on Mac and Linux to use "/usr/local/bin" -* Set the Lime tools to use optional CFFI (can run without NDLL) -* Added -Ddisplay when running "lime display" to help code completion -* Added some minor Windows XP fixes -* Improved lime.app.Event to be more resilient to other macros -* Fixed lime.ui.FileDialog on Mac -* Fixed dispatch of mouse events from touch on HTML5 -* Added "onBackPressed" to Android extensions +- Added support for Raspberry Pi 2 +- Added lime.app.Future/lime.app.Promise +- Migrated asynchronous lime.Assets calls to use futures +- Added lime.system.CFFI and a new @:cffi macro to use prime +- Migrated Lime CFFI bindings to use new (faster) prime bindings +- Added window.alert (taskbar flash, optional message popup) +- Set the "lime" shortcut on Mac and Linux to use "/usr/local/bin" +- Set the Lime tools to use optional CFFI (can run without NDLL) +- Added -Ddisplay when running "lime display" to help code completion +- Added some minor Windows XP fixes +- Improved lime.app.Event to be more resilient to other macros +- Fixed lime.ui.FileDialog on Mac +- Fixed dispatch of mouse events from touch on HTML5 +- Added "onBackPressed" to Android extensions 2.6.1 (08/26/2015) ------------------ -* Added window.focus for raising and focusing windows -* Added lime.ui.FileDialog for save/open dialogs -* Made application renderer and window return the first of each array -* Added renderer.type for simpler comparisons -* Implemented AudioBuffer.fromURL for OpenFL Sound support -* Switched to current Lime architecture when processing SVG files -* Fixed color order in image.getColorBoundsRect -* Fixed font embedding for HTML5 -* Fixed Cairo inFill, inStroke, inClip -* Fixed some issues in image.copyPixels -* Fixed missing callback in Assets.loadLibrary -* Fixed multi-touch on iOS (legacy) +- Added window.focus for raising and focusing windows +- Added lime.ui.FileDialog for save/open dialogs +- Made application renderer and window return the first of each array +- Added renderer.type for simpler comparisons +- Implemented AudioBuffer.fromURL for OpenFL Sound support +- Switched to current Lime architecture when processing SVG files +- Fixed color order in image.getColorBoundsRect +- Fixed font embedding for HTML5 +- Fixed Cairo inFill, inStroke, inClip +- Fixed some issues in image.copyPixels +- Fixed missing callback in Assets.loadLibrary +- Fixed multi-touch on iOS (legacy) 2.6.0 (08/20/2015) ------------------ -* Added support for multiple windows -* Improved Lime application config for multiple windows -* Renamed application.init to application.onWindowCreate -* Changed many application events to include a window reference -* Expanded touch input support, added lime.ui.Touch -* Moved game input events from Window to Gamepad -* Added application onPreloadProgress/onPreloadComplete events -* Added onModuleExit events (for a clean shutdown) -* Added additional key mappings for Flash and HTML5 -* Fixed HTML5 text input with spaces -* Fixed event.remove -* Fixed an issue with software-based windows -* Fixed an unused reference in the Android template -* Fixed "std@module_read" errors on Neko +- Added support for multiple windows +- Improved Lime application config for multiple windows +- Renamed application.init to application.onWindowCreate +- Changed many application events to include a window reference +- Expanded touch input support, added lime.ui.Touch +- Moved game input events from Window to Gamepad +- Added application onPreloadProgress/onPreloadComplete events +- Added onModuleExit events (for a clean shutdown) +- Added additional key mappings for Flash and HTML5 +- Fixed HTML5 text input with spaces +- Fixed event.remove +- Fixed an issue with software-based windows +- Fixed an unused reference in the Android template +- Fixed "std@module_read" errors on Neko 2.5.3 (08/13/2015) ------------------ -* Ported the JNI class for Android extension support without legacy -* Added a new Display API for information on connected screens -* Added lime.system.Clipboard and support for System.endianness -* Added window.display and window.setTitle -* Merged updates to the game console render context -* Standardized touch events to use normalized x/y coordinates -* Standardized touch events to dispatch mouse events as well -* Added support for unicode text input on HTML5 -* Added support for specifying the iOS simulator device type -* Added conversion to/from UInt for Int abstracts -* Fixed the output color order when image encoding -* Reduced allocations when using gl.vertexAttribPointer -* Improved font hinting when using Cairo -* Fixed decoding support for some JPEG images -* Fixed support for embedded assets on iOS and Android -* Fixed a possible issue in the Flash preloader -* Fixed passing of Haxe defines in the iOS build template -* Fixed support for lime.utils.Log -* Fixed support for event.has +- Ported the JNI class for Android extension support without legacy +- Added a new Display API for information on connected screens +- Added lime.system.Clipboard and support for System.endianness +- Added window.display and window.setTitle +- Merged updates to the game console render context +- Standardized touch events to use normalized x/y coordinates +- Standardized touch events to dispatch mouse events as well +- Added support for unicode text input on HTML5 +- Added support for specifying the iOS simulator device type +- Added conversion to/from UInt for Int abstracts +- Fixed the output color order when image encoding +- Reduced allocations when using gl.vertexAttribPointer +- Improved font hinting when using Cairo +- Fixed decoding support for some JPEG images +- Fixed support for embedded assets on iOS and Android +- Fixed a possible issue in the Flash preloader +- Fixed passing of Haxe defines in the iOS build template +- Fixed support for lime.utils.Log +- Fixed support for event.has 2.5.2 (07/23/2015) ------------------ -* Added support for automatic software fallback on native platforms -* Improved the behavior of image getPixel/setPixel -* Fixed native fillRect/floodFill when using certain color values -* Improved color conversion support for Flash -* Fixed issue preventing Neko from reading 32-bit integers correctly +- Added support for automatic software fallback on native platforms +- Improved the behavior of image getPixel/setPixel +- Fixed native fillRect/floodFill when using certain color values +- Improved color conversion support for Flash +- Fixed issue preventing Neko from reading 32-bit integers correctly 2.5.1 (07/21/2015) ------------------ -* Made Image properly support all PixelFormat/premultiplied types -* Updated PixelFormat names to be more descriptive -* Added prefix support for generated library class names -* Fixed an issue with Assets.loadImage on HTML5 -* Fixed support for OpenAL playback using a starting offset +- Made Image properly support all PixelFormat/premultiplied types +- Updated PixelFormat names to be more descriptive +- Added prefix support for generated library class names +- Fixed an issue with Assets.loadImage on HTML5 +- Fixed support for OpenAL playback using a starting offset 2.5.0 (07/17/2015) ------------------ -* Added guards against duplicate gamepad connect events -* Added guards against gamepad events after a disconnect -* Added dead zone and repeat value filtering for gamepad axis -* Added CairoImageSurface, properly separate from CairoSurface -* Improved HTML5 to use the project FPS setting -* Improved asset libraries to have an "unload" method -* Fixed repeated calls to Assets.load* with the same ID -* Fixed "lime build" to not progress without sources -* Fixed a regression in ByteArray.fromFile on Android -* Fixed a bug in arrayBufferView.set -* Quieted libpng "known incorrect profile" messages -* Added a patch to allow Wii Remote detection (legacy) +- Added guards against duplicate gamepad connect events +- Added guards against gamepad events after a disconnect +- Added dead zone and repeat value filtering for gamepad axis +- Added CairoImageSurface, properly separate from CairoSurface +- Improved HTML5 to use the project FPS setting +- Improved asset libraries to have an "unload" method +- Fixed repeated calls to Assets.load* with the same ID +- Fixed "lime build" to not progress without sources +- Fixed a regression in ByteArray.fromFile on Android +- Fixed a bug in arrayBufferView.set +- Quieted libpng "known incorrect profile" messages +- Added a patch to allow Wii Remote detection (legacy) 2.4.9 (07/13/2015) ------------------ -* Added lime.system.ThreadPool -* Added lime.utils.Log -* Added image.scroll -* Added event.has -* Improved performance of Flash target logging -* Improved "lime upgrade" when Git is not in the PATH -* Improved image.clone when using canvas -* Updated for compatibility with newer lime-samples -* Updated to use a default icon when none is available -* Updated Assets to use a ThreadPool for asynchronous loads -* Updated to pass -verbose during "run" when in verbose mode -* Fixed an issue when tracing null typed arrays -* Fixed image.copyChannel when clipping is necessary -* Fixed use of cURL basic types as Int -* Improved support for asynchronous SSL requests (legacy) +- Added lime.system.ThreadPool +- Added lime.utils.Log +- Added image.scroll +- Added event.has +- Improved performance of Flash target logging +- Improved "lime upgrade" when Git is not in the PATH +- Improved image.clone when using canvas +- Updated for compatibility with newer lime-samples +- Updated to use a default icon when none is available +- Updated Assets to use a ThreadPool for asynchronous loads +- Updated to pass -verbose during "run" when in verbose mode +- Fixed an issue when tracing null typed arrays +- Fixed image.copyChannel when clipping is necessary +- Fixed use of cURL basic types as Int +- Improved support for asynchronous SSL requests (legacy) 2.4.8 (07/09/2015) ------------------ -* Improved lime.system.BackgroundWorker onComplete -* Improved native bytes to guard against premature GC -* Fixed ENABLE_BITCODE when targeting older iOS versions -* Fixed possible double mouse events on iOS -* Fixed embedded font support on iOS -* Fixed "lime rebuild ios" with some versions of HXCPP -* Fixed mouse middle/right/wheel events on desktop (legacy) +- Improved lime.system.BackgroundWorker onComplete +- Improved native bytes to guard against premature GC +- Fixed ENABLE_BITCODE when targeting older iOS versions +- Fixed possible double mouse events on iOS +- Fixed embedded font support on iOS +- Fixed "lime rebuild ios" with some versions of HXCPP +- Fixed mouse middle/right/wheel events on desktop (legacy) 2.4.7 (07/06/2015) ------------------ -* Fixed regression in HTML5 typed array support +- Fixed regression in HTML5 typed array support 2.4.6 (07/06/2015) ------------------ -* Added lime.system.BackgroundWorker for easy threads -* Made Assets loadImage/loadBytes asynchronous on native -* Removed the ByteArray \__init__ and matching CFFI functions -* Improved the help documentation when using "lime create" -* Fixed a crash that could occur when using Bytes -* Fixed audioSource.play on native when there is no data -* Fixed event.remove when using during an event dispatch -* Fixed the cleanup of OpenAL when closing applications -* Fixed a crash that could occur using cURL on Mac -* Fixed static builds for the Mac target +- Added lime.system.BackgroundWorker for easy threads +- Made Assets loadImage/loadBytes asynchronous on native +- Removed the ByteArray \__init__ and matching CFFI functions +- Improved the help documentation when using "lime create" +- Fixed a crash that could occur when using Bytes +- Fixed audioSource.play on native when there is no data +- Fixed event.remove when using during an event dispatch +- Fixed the cleanup of OpenAL when closing applications +- Fixed a crash that could occur using cURL on Mac +- Fixed static builds for the Mac target 2.4.5 (07/02/2015) ------------------ -* Changed to a new, better Haxe typed array implementation -* Added an improved Bytes (internal) for native targets -* Added lime.utils.LZMA for LZMA compression/decompression -* Expanded support for gamepad devices -* Improved desktop multitouch support -* Exposed decodeBytes/decodeFile for PNG and JPG formats -* Added support for header-only decoding of PNG or JPG -* Improved support for Flash log output -* Improved the "update" command to support GIT submodules -* Restored previous rendering behavior on high-DPI Apple devices -* Fixed support for non-embedded assets on HTML5 -* Fixed other cases in the Assets loading code on HTML5 -* Fixed imageBuffer.bitsPerPixel to default 32, not 4 (bytes) -* Updated webgl-debug.js for use with HTML5 -Dwebgl -debug -* Fixed a regression in middle and right click events (legacy) -* Fixed possible file handle leaks in the audio code (legacy) -* Added DPI-aware keyboard height for iOS (legacy) -* Added a hack to identify the type of connected gamepads (legacy) -* Fixed the sourceRect coordinates for blitChannel (legacy) -* Added screen resolution width/height for BlackBerry (legacy) -* Fixed a possible overflow in the LZMA buffer (legacy) +- Changed to a new, better Haxe typed array implementation +- Added an improved Bytes (internal) for native targets +- Added lime.utils.LZMA for LZMA compression/decompression +- Expanded support for gamepad devices +- Improved desktop multitouch support +- Exposed decodeBytes/decodeFile for PNG and JPG formats +- Added support for header-only decoding of PNG or JPG +- Improved support for Flash log output +- Improved the "update" command to support GIT submodules +- Restored previous rendering behavior on high-DPI Apple devices +- Fixed support for non-embedded assets on HTML5 +- Fixed other cases in the Assets loading code on HTML5 +- Fixed imageBuffer.bitsPerPixel to default 32, not 4 (bytes) +- Updated webgl-debug.js for use with HTML5 -Dwebgl -debug +- Fixed a regression in middle and right click events (legacy) +- Fixed possible file handle leaks in the audio code (legacy) +- Added DPI-aware keyboard height for iOS (legacy) +- Added a hack to identify the type of connected gamepads (legacy) +- Fixed the sourceRect coordinates for blitChannel (legacy) +- Added screen resolution width/height for BlackBerry (legacy) +- Fixed a possible overflow in the LZMA buffer (legacy) 2.4.4 (06/08/2015) ------------------ -* Handle Flash traces, similar to native logging -* Improved performance of TextLayout -* Improved the behavior of the Android Activity class -* Added window activate/deactivate events on mobile -* Added retina support on Mac desktop -* Allow --meta overrides when using `lime create project` -* Added sleep after Android touch events for better performance -* Improved build support for Raspberry Pi 2 -* Fixed -force_load flag on iOS builds -* Fixed GL.clearDepth and GL.depthRange bindings -* Fixed negative System.getTimer value on HTML5 -* Added multi-touch desktop support (legacy) -* Improved WAV format loading (legacy) -* Fixed iswalpha crash on BlackBerry (legacy) +- Handle Flash traces, similar to native logging +- Improved performance of TextLayout +- Improved the behavior of the Android Activity class +- Added window activate/deactivate events on mobile +- Added retina support on Mac desktop +- Allow --meta overrides when using `lime create project` +- Added sleep after Android touch events for better performance +- Improved build support for Raspberry Pi 2 +- Fixed -force_load flag on iOS builds +- Fixed GL.clearDepth and GL.depthRange bindings +- Fixed negative System.getTimer value on HTML5 +- Added multi-touch desktop support (legacy) +- Improved WAV format loading (legacy) +- Fixed iswalpha crash on BlackBerry (legacy) 2.4.3 (06/01/2015) ------------------ -* Improved support for embedded fonts -* Fixed regression when embedding certain OTF fonts +- Improved support for embedded fonts +- Fixed regression when embedding certain OTF fonts 2.4.2 (05/30/2015) ------------------ -* Improved iOS and Android build support -* Add support for application.frameRate -* Reduce cURL connection timeout to 30 seconds -* Improved handling of non-transparent image buffers -* Add cubic support to font decomposition -* Added Cairo window resize handling -* Added Cairo Freetype support -* Added check to remove duplicated `` references -* Minor fix to image premultiply alpha -* Minor fix to "lime create" command -* Minor fix to rectangle.transform -* Fixed Windows Neko builds when not running on Windows +- Improved iOS and Android build support +- Add support for application.frameRate +- Reduce cURL connection timeout to 30 seconds +- Improved handling of non-transparent image buffers +- Add cubic support to font decomposition +- Added Cairo window resize handling +- Added Cairo Freetype support +- Added check to remove duplicated `` references +- Minor fix to image premultiply alpha +- Minor fix to "lime create" command +- Minor fix to rectangle.transform +- Fixed Windows Neko builds when not running on Windows 2.4.1 (05/13/2015) ------------------ -* Improve handling of custom error types in HTML5 target -* Guard icon helpers if PNG encoding fails -* Fixed Emscripten rebuild -* Fixed issue on the build server +- Improve handling of custom error types in HTML5 target +- Guard icon helpers if PNG encoding fails +- Fixed Emscripten rebuild +- Fixed issue on the build server 2.4.0 (05/12/2015) ------------------ -* Added Cairo render context and bindings -* Added support for software windows, using Cairo not OpenGL -* Added text input/edit events -* Added onEnter/onLeave events for Window mouse focus -* Added Image getColorBoundsRect -* Added build support for ANGLE -* Removed prevent default for HTML5 arrow and space keys -* Improved Image copyPixels with merge alpha -* Fixed static build support -* Fixed a case where fonts might not be embedded -* Fixed occasional crash with OpenAL on Neko +- Added Cairo render context and bindings +- Added support for software windows, using Cairo not OpenGL +- Added text input/edit events +- Added onEnter/onLeave events for Window mouse focus +- Added Image getColorBoundsRect +- Added build support for ANGLE +- Removed prevent default for HTML5 arrow and space keys +- Improved Image copyPixels with merge alpha +- Fixed static build support +- Fixed a case where fonts might not be embedded +- Fixed occasional crash with OpenAL on Neko 2.3.3 (04/21/2015) ------------------ -* Added audioSource.loops, audioSource.offset, audioSource.length -* Renamed audioSource.timeOffset to audioSource.currentTime -* Fixed onComplete for AudioSource instances -* Fixed support for embedded bytes on HTML5 -* Fixed support for hardware anti-aliasing on SDL2 targets -* Fixed some loose file handles in the format decoders -* Fixed a possible crash in copyPixels -* Improved accuracy of URLLoader progress +- Added audioSource.loops, audioSource.offset, audioSource.length +- Renamed audioSource.timeOffset to audioSource.currentTime +- Fixed onComplete for AudioSource instances +- Fixed support for embedded bytes on HTML5 +- Fixed support for hardware anti-aliasing on SDL2 targets +- Fixed some loose file handles in the format decoders +- Fixed a possible crash in copyPixels +- Improved accuracy of URLLoader progress 2.3.2 (04/15/2015) ------------------ -* Improved performance of pixel-based operations in Image -* Added support for RGBA (default) and ARGB color order -* Added --port=123 to change the webserver port on HTML5 builds -* Added support for Unicode Windows system paths -* Added larger icon sizes requested by Windows 10 -* Improved functionality of BMP.encode -* Fixed compilation on Android without Sound.java -* Fixed support for -Doptional-cffi -* Fixed haxe.Timer (legacy) +- Improved performance of pixel-based operations in Image +- Added support for RGBA (default) and ARGB color order +- Added --port=123 to change the webserver port on HTML5 builds +- Added support for Unicode Windows system paths +- Added larger icon sizes requested by Windows 10 +- Improved functionality of BMP.encode +- Fixed compilation on Android without Sound.java +- Fixed support for -Doptional-cffi +- Fixed haxe.Timer (legacy) 2.3.1 (04/08/2015) ------------------ -* Renamed Lime legacy to "lime-legacy" to support hybrid builds -* Added -Dhybrid for using Lime 2 and Lime legacy in the same project -* Improved support for standalone Neko builds on Linux -* Fixed loading of OGG sounds on Android -* Fixed Emscripten support for newer HXCPP -* Fixed a crash using gl.texSubImage2D on Neko -* Fixed missing System.fontsDirectory on Linux -* Fixed crash on NULL system directories -* Fixed crash when font or JPEG file paths are not found -* Added softKeyboardRect support for iOS (legacy) +- Renamed Lime legacy to "lime-legacy" to support hybrid builds +- Added -Dhybrid for using Lime 2 and Lime legacy in the same project +- Improved support for standalone Neko builds on Linux +- Fixed loading of OGG sounds on Android +- Fixed Emscripten support for newer HXCPP +- Fixed a crash using gl.texSubImage2D on Neko +- Fixed missing System.fontsDirectory on Linux +- Fixed crash on NULL system directories +- Fixed crash when font or JPEG file paths are not found +- Added softKeyboardRect support for iOS (legacy) 2.3.0 (03/26/2015) ------------------ -* Added initial Lime 2 support for iOS -* Added Mouse.lock and Mouse.warp on native platforms -* Added window.onMouseMoveRelative for use with mouse locking -* Added System.exit -* Added Lime 2 support for haxe.Timer -* Changed window.onMouseMove to dispatch only (x, y) -* Improved window width/height reporting after creation -* Updated ios-deploy, fixed the run command for iOS -* Fixed the ByteArray size returned from Image.getPixels -* Fixed Flash builds for Mac and Haxe 3.2 -* Fixed js.Boot for new changes in Haxe 3.2 -* Fixed an issue in the Gamepad API -* Fixed the ZipHelper for Haxe 3.2 -* Fixed the -Dstats define for HTML5 builds +- Added initial Lime 2 support for iOS +- Added Mouse.lock and Mouse.warp on native platforms +- Added window.onMouseMoveRelative for use with mouse locking +- Added System.exit +- Added Lime 2 support for haxe.Timer +- Changed window.onMouseMove to dispatch only (x, y) +- Improved window width/height reporting after creation +- Updated ios-deploy, fixed the run command for iOS +- Fixed the ByteArray size returned from Image.getPixels +- Fixed Flash builds for Mac and Haxe 3.2 +- Fixed js.Boot for new changes in Haxe 3.2 +- Fixed an issue in the Gamepad API +- Fixed the ZipHelper for Haxe 3.2 +- Fixed the -Dstats define for HTML5 builds 2.2.2 (03/25/2015) ------------------ -* Restored support for OpenFL 2.2 -* Added System.fontsDirectory -* Improved Font.fromFile when the file is not available -* Improved HTTP server to allow access from other devices -* Improved System.getTimer to work without haxe.Timer -* Fixed a crash when using GL.bufferData with zero-length data +- Restored support for OpenFL 2.2 +- Added System.fontsDirectory +- Improved Font.fromFile when the file is not available +- Improved HTTP server to allow access from other devices +- Improved System.getTimer to work without haxe.Timer +- Fixed a crash when using GL.bufferData with zero-length data 2.2.1 (03/21/2015) ------------------ -* Fixed -rebuild for 32-bit Mac/Linux with newer HXCPP -* Fixed ImageBuffer with newer HXCPP -* Compile fix +- Fixed -rebuild for 32-bit Mac/Linux with newer HXCPP +- Fixed ImageBuffer with newer HXCPP +- Compile fix 2.2.0 (03/20/2015) ------------------ -* Added formal support for fonts -* Added formal support for complex text layout -* Added Gamepad input support -* Added Haxe 3.2 support -* Added support for Window fullscreen -* Added support for Window minimized -* Added System directories (user, documents, etc) -* Added the foundation for iOS support -* Improved support for node.js -* Improved support for Lime modules -* Added support for embedded images and sounds -* Changed Module init() to occur sooner -* Implemented Assets.getBytes for Flash BitmapData -* Fixed Assets.isLocal for Flash sound assets -* Fixed Image and ImageBuffer clone() -* Fixed support for HXCPP 3.2.x -* Fixed -rebuild when using the Lime 2 desktop NDLL -* Fixed "lime rebuild" when in the Lime directory +- Added formal support for fonts +- Added formal support for complex text layout +- Added Gamepad input support +- Added Haxe 3.2 support +- Added support for Window fullscreen +- Added support for Window minimized +- Added System directories (user, documents, etc) +- Added the foundation for iOS support +- Improved support for node.js +- Improved support for Lime modules +- Added support for embedded images and sounds +- Changed Module init() to occur sooner +- Implemented Assets.getBytes for Flash BitmapData +- Fixed Assets.isLocal for Flash sound assets +- Fixed Image and ImageBuffer clone() +- Fixed support for HXCPP 3.2.x +- Fixed -rebuild when using the Lime 2 desktop NDLL +- Fixed "lime rebuild" when in the Lime directory 2.1.3 (03/02/2015) ------------------ -* Added lime.ui.KeyModifier -* Added key modifier support to Flash and HTML5 keyboard events -* Added support for iOS builds using HXCPP 3.2 -* Now "create project" creates unique package IDs instead of a common one -* Now "-clean" is ignored where it does not make sense (such as "run -clean") -* Changed default fullscreen for native targets to SDL_WINDOW_FULLSCREEN_DESKTOP -* Fixed escaping for quotes and spaces in macro calls on Flash target -* Removed Lime native dependency defines from Flash and HTML5 builds -* Improved the behavior of shader isValid/isInvalid -* Added a request for focus after resuming on Android -* Fixed an IME issue that affected some Android keyboards -* Fixed Linux setup on Arch 32-bit systems -* Fixed an issue when building iOS projects to an absolute build path -* Fixed issue where iOS builds may lack some defines (such as HXCPP_API_LEVEL) -* Patched support for Assets.loadSound on Flash target -* Fixed a null check in lime_alc_open_device +- Added lime.ui.KeyModifier +- Added key modifier support to Flash and HTML5 keyboard events +- Added support for iOS builds using HXCPP 3.2 +- Now "create project" creates unique package IDs instead of a common one +- Now "-clean" is ignored where it does not make sense (such as "run -clean") +- Changed default fullscreen for native targets to SDL_WINDOW_FULLSCREEN_DESKTOP +- Fixed escaping for quotes and spaces in macro calls on Flash target +- Removed Lime native dependency defines from Flash and HTML5 builds +- Improved the behavior of shader isValid/isInvalid +- Added a request for focus after resuming on Android +- Fixed an IME issue that affected some Android keyboards +- Fixed Linux setup on Arch 32-bit systems +- Fixed an issue when building iOS projects to an absolute build path +- Fixed issue where iOS builds may lack some defines (such as HXCPP_API_LEVEL) +- Patched support for Assets.loadSound on Flash target +- Fixed a null check in lime_alc_open_device 2.1.2 (02/20/2015) ------------------ -* Minor fixes for upcoming Haxe 3.2 release -* Added "lime deploy" to zip and support upload targets -* Added initial support for Google Drive using "lime deploy" -* Added "Options.txt" reading for iOS builds to include -Dhxcpp_api_level -* Changed "lime update ios" to only update, and not open Xcode -* Added "-xcode" flag to open Xcode on iOS "build" or "run" command -* Fixed the use of "lime" from Windows batch/command files -* Improved "haxelib path" error message when a dependency haxelib is missing -* Improved PathHelper.relocatePath to resolve issues with absolute paths -* Fixed issue preventing projects from changing Flash scaleMode/align -* Improved web font loading on HTML5 target -* Fixed JavaScript minification that was failing on some systems -* Fix issue with disappearing keyboards on certain Android devices -* Fix "isValid" check in GLShader to check for zero -* Set `` by default -* Request focus in resume on Android, in case an extension has focus (legacy) -* Added TILE_BLEND_SUBTRACT (legacy) +- Minor fixes for upcoming Haxe 3.2 release +- Added "lime deploy" to zip and support upload targets +- Added initial support for Google Drive using "lime deploy" +- Added "Options.txt" reading for iOS builds to include -Dhxcpp_api_level +- Changed "lime update ios" to only update, and not open Xcode +- Added "-xcode" flag to open Xcode on iOS "build" or "run" command +- Fixed the use of "lime" from Windows batch/command files +- Improved "haxelib path" error message when a dependency haxelib is missing +- Improved PathHelper.relocatePath to resolve issues with absolute paths +- Fixed issue preventing projects from changing Flash scaleMode/align +- Improved web font loading on HTML5 target +- Fixed JavaScript minification that was failing on some systems +- Fix issue with disappearing keyboards on certain Android devices +- Fix "isValid" check in GLShader to check for zero +- Set `` by default +- Request focus in resume on Android, in case an extension has focus (legacy) +- Added TILE_BLEND_SUBTRACT (legacy) 2.1.1 (02/13/2015) ------------------ -* Added initial Emscripten target support -* Fixed regression in HTML5 font asset embedding -* Minor improvement to SWF embedding for Flash target +- Added initial Emscripten target support +- Fixed regression in HTML5 font asset embedding +- Minor improvement to SWF embedding for Flash target 2.1.0 (02/11/2015) ------------------ -* Refactored, made many events instance-based, not static -* Removed event managers, moved input events to Window class instances -* Moved many Lime tool classes into the public lime.* API -* Added initial Lime 2 support for Android -* Added official Android X86 emulator support -* Added support for munit unit testing suite -* Added System.getTimer for faster delta time calculations -* Added application.removeWindow and window.close -* Added support for a custom asset root URL on HTML5 -* Added forced OpenAL cleanup, in case of an unclean exit -* Fixed support for Haxe 3.2 haxelib behavior -* Fixed createImageData issue on HTML5 for WebGL -* Improvements to in-progress Lime text layout API -* Improved handling of Android Debug Bridge on Linux -* Improved handling of ANT_HOME for use with ADB -* Fixed the output of textField.htmlText on Android (legacy) -* Updated TextField implementation (legacy) -* Fixed behavior of ColorMatrixFilter (legacy) -* Fixed textField.setTextFormat with different font (legacy) -* Fixed crash in Capabilities.language on iOS (legacy) +- Refactored, made many events instance-based, not static +- Removed event managers, moved input events to Window class instances +- Moved many Lime tool classes into the public lime.* API +- Added initial Lime 2 support for Android +- Added official Android X86 emulator support +- Added support for munit unit testing suite +- Added System.getTimer for faster delta time calculations +- Added application.removeWindow and window.close +- Added support for a custom asset root URL on HTML5 +- Added forced OpenAL cleanup, in case of an unclean exit +- Fixed support for Haxe 3.2 haxelib behavior +- Fixed createImageData issue on HTML5 for WebGL +- Improvements to in-progress Lime text layout API +- Improved handling of Android Debug Bridge on Linux +- Improved handling of ANT_HOME for use with ADB +- Fixed the output of textField.htmlText on Android (legacy) +- Updated TextField implementation (legacy) +- Fixed behavior of ColorMatrixFilter (legacy) +- Fixed textField.setTextFormat with different font (legacy) +- Fixed crash in Capabilities.language on iOS (legacy) 2.0.6 (01/22/2015) ------------------ -* Resolved asset embedding for Lime resources -* Added "js-flatten" and "dce full" to HTML5 -final builds -* Made "-minify" occur by default on HTML5 -final builds -* Improved the copy behavior for assets on Android and BlackBerry -* Improved the getDeviceSDKVersion call for Android -* Fixed support for making typed arrays from OpenFL Vector data -* Removed unneeded iOS CFBundleIcon references -* Updated the default iOS deployment to version 5.1.1 for arm64 -* Updated to the latest Google Closure compiler version -* Added a ConsoleRenderContext, to continue to grow with console efforts -* Refactored Application, Window, Renderer and other "backend" classes -* Fixed crash in BitmapData rendering (legacy) -* Fixed rotation of TextField instances (legacy) +- Resolved asset embedding for Lime resources +- Added "js-flatten" and "dce full" to HTML5 -final builds +- Made "-minify" occur by default on HTML5 -final builds +- Improved the copy behavior for assets on Android and BlackBerry +- Improved the getDeviceSDKVersion call for Android +- Fixed support for making typed arrays from OpenFL Vector data +- Removed unneeded iOS CFBundleIcon references +- Updated the default iOS deployment to version 5.1.1 for arm64 +- Updated to the latest Google Closure compiler version +- Added a ConsoleRenderContext, to continue to grow with console efforts +- Refactored Application, Window, Renderer and other "backend" classes +- Fixed crash in BitmapData rendering (legacy) +- Fixed rotation of TextField instances (legacy) 2.0.5 (01/13/2015) ------------------ -* Improved the Windows ICO generation support -* Added support for embedded ICO resources in Windows applications -* Added caching to improve performance when icons exist -* Added lime.graphics.format.JPEG/PNG/BMP classes for encoding -* Improved KeyCode so it automatically casts to/from Int -* Improved the behavior of Android ADB management -* Migrated to an "Asset Catalog" for iOS icons and launch images -* Added missing iOS icon and launch image sizes -* Added image.merge support for software image blending -* Fixed the color order for Windows icon generation -* Fixed a possible crash issue in empty Image instances -* Fixed support for forwarding HXCPP defines on iOS builds -* Fixed support for dead-code elimination full -* Guarded Android API calls that require newer device versions -* Improved lime.embed to support either a DOM object or ID string -* Improved the behavior of BitmapData getPixels (legacy) -* Exposed support for shifting pitch on OpenAL (legacy) -* Fixed a crash in iOS Capabilities.language (legacy) -* Added bitmapData.merge support (legacy) +- Improved the Windows ICO generation support +- Added support for embedded ICO resources in Windows applications +- Added caching to improve performance when icons exist +- Added lime.graphics.format.JPEG/PNG/BMP classes for encoding +- Improved KeyCode so it automatically casts to/from Int +- Improved the behavior of Android ADB management +- Migrated to an "Asset Catalog" for iOS icons and launch images +- Added missing iOS icon and launch image sizes +- Added image.merge support for software image blending +- Fixed the color order for Windows icon generation +- Fixed a possible crash issue in empty Image instances +- Fixed support for forwarding HXCPP defines on iOS builds +- Fixed support for dead-code elimination full +- Guarded Android API calls that require newer device versions +- Improved lime.embed to support either a DOM object or ID string +- Improved the behavior of BitmapData getPixels (legacy) +- Exposed support for shifting pitch on OpenAL (legacy) +- Fixed a crash in iOS Capabilities.language (legacy) +- Added bitmapData.merge support (legacy) 2.0.4 (12/31/2014) ------------------ -* Added system mouse cursor support in lime.ui.Mouse -* Added hide/show cursor support in lime.ui.Mouse -* Improved the behavior of the embedded web server -* Fixed the behavior of Image.getPixels -* Fixed embedded font support for OpenFL HTML5 -* Fixed the Windows application icon -* Fixed handling of dummy ANT_HOME or JAVA_HOME HXCPP values -* Improved default context menu behavior on Flash/OpenFL -* Improved fixed orientation support on iOS (legacy) +- Added system mouse cursor support in lime.ui.Mouse +- Added hide/show cursor support in lime.ui.Mouse +- Improved the behavior of the embedded web server +- Fixed the behavior of Image.getPixels +- Fixed embedded font support for OpenFL HTML5 +- Fixed the Windows application icon +- Fixed handling of dummy ANT_HOME or JAVA_HOME HXCPP values +- Improved default context menu behavior on Flash/OpenFL +- Improved fixed orientation support on iOS (legacy) 2.0.3 (12/27/2014) ------------------ -* Improved linking of OpenAL for Android -* Added support for cached `` processing -* Fixed exit code behavior when calling HXCPP -* Fixed minor issues with "lime rebuild tools" +- Improved linking of OpenAL for Android +- Added support for cached `` processing +- Fixed exit code behavior when calling HXCPP +- Fixed minor issues with "lime rebuild tools" 2.0.2 (12/21/2014) ------------------ -* Added ARMV7S, ARM64 and X86_64 support for iOS -* Added unofficial Java support -* Added xxhdpi and xxxhdpi icons for Android -* Added initial support for Android (without legacy) -* Upgraded to a newer SDL2 release for desktop -* Improved the behavior of Image.setPixels -* Improved Image.fromBytes for HTML5 -* Improved Image.fillRect for HTML5 -* Fixed issue causing "bin" directories to appear on rebuild -* Fixed issues with Android ADB -* Fixed an issue with HTML5 copyPixels -* Fixed an infinite loop when loading WAV audio -* Fixed an infinite loop when loading WAV audio (legacy) -* Fixed GL.getShaderPrecisionFormat (legacy) -* Removed unnecessary iOS libraries (legacy) -* Fixed Android x86 builds (legacy) -* Fixed TextField leading (legacy) +- Added ARMV7S, ARM64 and X86_64 support for iOS +- Added unofficial Java support +- Added xxhdpi and xxxhdpi icons for Android +- Added initial support for Android (without legacy) +- Upgraded to a newer SDL2 release for desktop +- Improved the behavior of Image.setPixels +- Improved Image.fromBytes for HTML5 +- Improved Image.fillRect for HTML5 +- Fixed issue causing "bin" directories to appear on rebuild +- Fixed issues with Android ADB +- Fixed an issue with HTML5 copyPixels +- Fixed an infinite loop when loading WAV audio +- Fixed an infinite loop when loading WAV audio (legacy) +- Fixed GL.getShaderPrecisionFormat (legacy) +- Removed unnecessary iOS libraries (legacy) +- Fixed Android x86 builds (legacy) +- Fixed TextField leading (legacy) 2.0.1 (12/04/2014) ------------------ -* Added GL.isContextLost -* Added Renderer onRenderContextLost/onRenderContextRestored -* Improved Android device version check -* Changed Firefox to type WEB instead of MOBILE -* Fixed HTML5 touch event coordinates +- Added GL.isContextLost +- Added Renderer onRenderContextLost/onRenderContextRestored +- Improved Android device version check +- Changed Firefox to type WEB instead of MOBILE +- Fixed HTML5 touch event coordinates 2.0.0 (11/20/2014) ------------------ -* Improved the "lime rebuild" command -* Added a "-dryrun" flag to help test the tools -* Fixed zero width/height in lime.graphics.Image -* Populate environment with HXCPP config defines -* Fixed double dispatch of HTML5 mouse events -* Improved the "lime.embed" JS command -* Fixed "lime create openfl" -* Made fixes to support the newer Blackberry SDK -* Fixed GraphicsPath on Neko (legacy) +- Improved the "lime rebuild" command +- Added a "-dryrun" flag to help test the tools +- Fixed zero width/height in lime.graphics.Image +- Populate environment with HXCPP config defines +- Fixed double dispatch of HTML5 mouse events +- Improved the "lime.embed" JS command +- Fixed "lime create openfl" +- Made fixes to support the newer Blackberry SDK +- Fixed GraphicsPath on Neko (legacy) 2.0.0-beta (11/13/2014) ----------------------- -* Merged the Lime "legacy" codebase -* Initial steps towards Lime node.js support -* Sped up rasterization of SVG icon images -* Sped up splash image generation -* Improved lime.graphics.Image for some browsers -* Added native PNG/JPG encoding -* Improved $variable handling in project parsing -* Other minor fixes +- Merged the Lime "legacy" codebase +- Initial steps towards Lime node.js support +- Sped up rasterization of SVG icon images +- Sped up splash image generation +- Improved lime.graphics.Image for some browsers +- Added native PNG/JPG encoding +- Improved $variable handling in project parsing +- Other minor fixes 2.0.0-alpha.8 (11/08/2014) -------------------------- -* Guarded certain CFFI calls -* Fixed discovery of Java install on OS X -* Omitting Android force downgrade on old devices +- Guarded certain CFFI calls +- Fixed discovery of Java install on OS X +- Omitting Android force downgrade on old devices 2.0.0-alpha.7 (11/01/2014) -------------------------- -* Improved handling of haxelib library versions -* Add patched haxe.CallStack to fix C++ stack order -* Fix fonts to use the true font name -* Automatically register fonts embedded in the project -* Fixed and documented the "-args" tool flag -* Added the force downgrade argument when installing on Android +- Improved handling of haxelib library versions +- Add patched haxe.CallStack to fix C++ stack order +- Fix fonts to use the true font name +- Automatically register fonts embedded in the project +- Fixed and documented the "-args" tool flag +- Added the force downgrade argument when installing on Android 2.0.0-alpha.6 (10/28/2014) -------------------------- -* Added initial support for cubic bezier font outlines -* Added better OpenFL ASCII color on Mac -* Maybe Java optional during build process for SVG rasterizer -* Improved "isText" file detection -* Fixed loading of type BINARY files as TEXT +- Added initial support for cubic bezier font outlines +- Added better OpenFL ASCII color on Mac +- Maybe Java optional during build process for SVG rasterizer +- Improved "isText" file detection +- Fixed loading of type BINARY files as TEXT 2.0.0-alpha.5 (10/23/2014) -------------------------- -* Added patched Haxe Boot class, to fix Std.is on Safari -* Added support for the "openfl" command -* Using the proper font name when embedding in Flash -* Improved the handling of font family name detection -* Minor fixes +- Added patched Haxe Boot class, to fix Std.is on Safari +- Added support for the "openfl" command +- Using the proper font name when embedding in Flash +- Improved the handling of font family name detection +- Minor fixes 2.0.0-alpha.4 (10/21/2014) -------------------------- -* Improved parsing of HXML when compiling for the Flash target -* Improved the `` data system -* Enabled splash screen generation for iOS again +- Improved parsing of HXML when compiling for the Flash target +- Improved the `` data system +- Enabled splash screen generation for iOS again 2.0.0-alpha.3 (10/20/2014) -------------------------- -* Fixed handling of HXML with comments when targeting Flash -* Added initial support for ".bundle" asset folders -* Added initial support for `` -* Passing "-verbose" when appropriate to library handlers -* Improved code completion for FlashDevelop -* Improved population of defines in project file handling -* Fixed "lime create extension" -* Improvements to `` tag merging -* Added Tilesheet TILE_RECT support (legacy) +- Fixed handling of HXML with comments when targeting Flash +- Added initial support for ".bundle" asset folders +- Added initial support for `` +- Passing "-verbose" when appropriate to library handlers +- Improved code completion for FlashDevelop +- Improved population of defines in project file handling +- Fixed "lime create extension" +- Improvements to `` tag merging +- Added Tilesheet TILE_RECT support (legacy) 2.0.0-alpha.2 (10/16/2014) -------------------------- -* Added Lime "legacy" binaries for OpenFL v2 native support -* Merged the Aether tools into Lime -* Improved the "lime rebuild" command -* Added onSaveInstanceState/onRestoreInstanceState on Android -* Added TouchEvent handling on HTML5 -* Fixed handling of GL depth and stencil buffers -* Fixed ImageDataUtil fillRect, copyPixels, colorTransform -* Fixed iOS framework paths which include spaces -* Fixed ByteArray.writeBytes when the length is zero -* Fixed the iOS linker flags project option -* Moved to JSON asset libraries instead of serialized ones -* Improved handling of SWF asset embedding -* Improved handling of HTML5 key events -* Disabled HTML5 page scrolling using the arrow keys -* Improved ByteArray support on HTML5 -* Fixed HTML5 mouse coordinates when letterboxing -* Fixed "bin" tool paths when Lime is not included in the project -* Many other small fixes -* Fixed sound.length when using streaming OGG audio (legacy) -* Added a proper shutdown for OpenAL audio (legacy) -* Fixed null data in URLLoader on Neko (legacy) -* Added a dead zone filter for joystick events (legacy) +- Added Lime "legacy" binaries for OpenFL v2 native support +- Merged the Aether tools into Lime +- Improved the "lime rebuild" command +- Added onSaveInstanceState/onRestoreInstanceState on Android +- Added TouchEvent handling on HTML5 +- Fixed handling of GL depth and stencil buffers +- Fixed ImageDataUtil fillRect, copyPixels, colorTransform +- Fixed iOS framework paths which include spaces +- Fixed ByteArray.writeBytes when the length is zero +- Fixed the iOS linker flags project option +- Moved to JSON asset libraries instead of serialized ones +- Improved handling of SWF asset embedding +- Improved handling of HTML5 key events +- Disabled HTML5 page scrolling using the arrow keys +- Improved ByteArray support on HTML5 +- Fixed HTML5 mouse coordinates when letterboxing +- Fixed "bin" tool paths when Lime is not included in the project +- Many other small fixes +- Fixed sound.length when using streaming OGG audio (legacy) +- Added a proper shutdown for OpenAL audio (legacy) +- Fixed null data in URLLoader on Neko (legacy) +- Added a dead zone filter for joystick events (legacy) 2.0.0-alpha (10/14/2014) ------------------------ -* Created an all-new Lime API -* The core architecture is built around Application, Window and Renderer -* Events are similar to C# or signals/slots, and strongly-typed -* Add support for Flash, DOM, Canvas or GL render contexts -* Added bindings to OpenAL, as well a simple unified audio API -* Added networking support, with bindings to cURL on native platforms -* Added cross-target pixel image manipulation features -* Fixed support for Xcode 6 publishing for iOS 8 -* Fixed support for BlackBerry 10.3 -* Restored support for old Android devices -* Added support for static linking on Windows, Mac and Linux -* Added support for externally defined platform targets -* Improved Flash asset embedding, to handle larger projects -* Added Firefox OS publishing using "lime publish firefox" -* Made the asset library system more flexible -* Many other tool improvements +- Created an all-new Lime API +- The core architecture is built around Application, Window and Renderer +- Events are similar to C# or signals/slots, and strongly-typed +- Add support for Flash, DOM, Canvas or GL render contexts +- Added bindings to OpenAL, as well a simple unified audio API +- Added networking support, with bindings to cURL on native platforms +- Added cross-target pixel image manipulation features +- Fixed support for Xcode 6 publishing for iOS 8 +- Fixed support for BlackBerry 10.3 +- Restored support for old Android devices +- Added support for static linking on Windows, Mac and Linux +- Added support for externally defined platform targets +- Improved Flash asset embedding, to handle larger projects +- Added Firefox OS publishing using "lime publish firefox" +- Made the asset library system more flexible +- Many other tool improvements 1.0.1 (06/24/2014) ------------------ -* Fixed BlackBerry support -* Fixed a memory leak when using LZMA decoding +- Fixed BlackBerry support +- Fixed a memory leak when using LZMA decoding 1.0.0 (05/29/2014) ----------------- @@ -2258,108 +2282,108 @@ _releases are still supported when building Lime from the source._ 0.9.9 (05/28/2014) ----------------- -* Fixed ACTIVATE/DEACTIVATE for Windows on minimize/restore -* Fixed Mac fullscreen handling -* Silenced "missing NDLL" warning when not in -verbose mode -* Added "-nocolor" option +- Fixed ACTIVATE/DEACTIVATE for Windows on minimize/restore +- Fixed Mac fullscreen handling +- Silenced "missing NDLL" warning when not in -verbose mode +- Added "-nocolor" option 0.9.8 (05/27/2014) ------------------ -* Fixed issues with Android JNI -* Fixed a GPU texture issue on iOS -* Fixed keyboard to only show if a TextField is type INPUT -* Fixed support for OpenGL on Nvidia drivers for Linux -* Fixed a bug where OpenGL textures were freed improperly -* Improved support for reading audio file length -* Added support for custom user agents in URL requests -* Other minor fixes +- Fixed issues with Android JNI +- Fixed a GPU texture issue on iOS +- Fixed keyboard to only show if a TextField is type INPUT +- Fixed support for OpenGL on Nvidia drivers for Linux +- Fixed a bug where OpenGL textures were freed improperly +- Improved support for reading audio file length +- Added support for custom user agents in URL requests +- Other minor fixes 0.9.7 (04/22/2014) ------------------ -* Merged Lime with NME for code collaboration -* Fixed software rendering path -* Fixed compile for older Android devices -* Added OpenAL support for BlackBerry -* Moved to C++11 by default for iOS builds -* Added additional Android extension callbacks -* Improved handling of Android keyboard/gamepad input -* Confirmed support for the Amazon FireTV -* Improved cursor visibility when switching to/from fullscreen -* Improved support for iOS virtual text input -* Fixed support for BWF wave files -* Fixed color order for PNG encoding +- Merged Lime with NME for code collaboration +- Fixed software rendering path +- Fixed compile for older Android devices +- Added OpenAL support for BlackBerry +- Moved to C++11 by default for iOS builds +- Added additional Android extension callbacks +- Improved handling of Android keyboard/gamepad input +- Confirmed support for the Amazon FireTV +- Improved cursor visibility when switching to/from fullscreen +- Improved support for iOS virtual text input +- Fixed support for BWF wave files +- Fixed color order for PNG encoding 0.9.6 (03/18/2014) ------------------ -* Fixed Android library instantiation order -* Fixed Android onKeyUp event -* Fixed volume and back keys on Android -* Added stereoscopic 3D support on Android -* Fixed TextField.textColor rendering -* Improved support for key codes -* Improved support for looping audio -* Minor fixes +- Fixed Android library instantiation order +- Fixed Android onKeyUp event +- Fixed volume and back keys on Android +- Added stereoscopic 3D support on Android +- Fixed TextField.textColor rendering +- Improved support for key codes +- Improved support for looping audio +- Minor fixes 0.9.5 (03/04/2014) ------------------ -* Improvements to Lime wrapper -* Fixed cURL to support larger header sizes -* Updated the SDL2 backend to support initialization without AA if not supported -* Added support for Android "immersive mode" -* Improved default \_sans, \_serif and \_typewriter font matching for Mac and iOS -* Multiple improvements to Android JNI support -* Added "count" support for drawTiles rendering -* Optimized renderer to perform more with a single draw array -* Improvements for anti-aliased hardware lines -* Optimizations to tessellation algorithm -* Added better support for pre-multiplied alpha, currently per surface -* Memory fixes for Freetype fonts -* Fix listing of Lime samples when running "lime create openfl" -* Added proper charCode and keyCode support for Android keyboard input -* Minor improvement to OpenAL sound -* Multi-threading fix for Android -* Fixed OpenGL ES 2 context support for Tizen -* Keyboard event support on Tizen -* Resolved rare issue when loading BitmapData from bytes -* Minor fixes for Emscripten -* Updated for automated builds: +- Improvements to Lime wrapper +- Fixed cURL to support larger header sizes +- Updated the SDL2 backend to support initialization without AA if not supported +- Added support for Android "immersive mode" +- Improved default \_sans, \_serif and \_typewriter font matching for Mac and iOS +- Multiple improvements to Android JNI support +- Added "count" support for drawTiles rendering +- Optimized renderer to perform more with a single draw array +- Improvements for anti-aliased hardware lines +- Optimizations to tessellation algorithm +- Added better support for pre-multiplied alpha, currently per surface +- Memory fixes for Freetype fonts +- Fix listing of Lime samples when running "lime create openfl" +- Added proper charCode and keyCode support for Android keyboard input +- Minor improvement to OpenAL sound +- Multi-threading fix for Android +- Fixed OpenGL ES 2 context support for Tizen +- Keyboard event support on Tizen +- Resolved rare issue when loading BitmapData from bytes +- Minor fixes for Emscripten +- Updated for automated builds: 0.9.4 (01/27/2014) ------------------ -* Fixed support for 8-bit PNG images with alpha -* Fixed software fallback for certain older cards +- Fixed support for 8-bit PNG images with alpha +- Fixed software fallback for certain older cards 0.9.3 (01/22/2014) ------------------ -* Improved the Android extension API -* Improved OpenAL audio panning behavior -* Fixed crash in ColorMatrixFilter -* Fixed GL drawArrays issue on desktop +- Improved the Android extension API +- Improved OpenAL audio panning behavior +- Fixed crash in ColorMatrixFilter +- Fixed GL drawArrays issue on desktop 0.9.2 (12/31/2013) ------------------ -* Fixed Tizen storage directory -* Fixed support for Emscripten +- Fixed Tizen storage directory +- Fixed support for Emscripten 0.9.1 (12/18/2013) ------------------ -* Lime wrapper improvements -* Improved performance when loading OGG samples in memory -* Added support for the Tizen emulator +- Lime wrapper improvements +- Improved performance when loading OGG samples in memory +- Added support for the Tizen emulator 0.9.0 (12/10/2013) ------------------ -* Added Tizen support -* Initial wrapper implementation -* Android JNI improvements -* Add OpenGL context lost/restored events -* Fixed support for Android OpenAL audio +- Added Tizen support +- Initial wrapper implementation +- Android JNI improvements +- Add OpenGL context lost/restored events +- Fixed support for Android OpenAL audio diff --git a/project/BuildHashlink.xml b/project/BuildHashlink.xml index 7c4aa27c65..7123640ee1 100644 --- a/project/BuildHashlink.xml +++ b/project/BuildHashlink.xml @@ -112,6 +112,7 @@ + diff --git a/project/README.md b/project/README.md index f0ddf921f0..ca1a594183 100644 --- a/project/README.md +++ b/project/README.md @@ -15,15 +15,21 @@ This directory contains two categories of code. - Windows requires [Visual Studio C++ components](https://visualstudio.microsoft.com/vs/features/cplusplus/). - Mac requires [Xcode](https://developer.apple.com/xcode/). - Linux requires several packages (names may vary per distro). + - Ubunutu requires the following packages. - ```bash - sudo apt install libgl1-mesa-dev libglu1-mesa-dev g++ g++-multilib gcc-multilib libasound2-dev libx11-dev libxext-dev libxi-dev libxrandr-dev libxinerama-dev libpulse-dev - ``` -- Raspberry Pi OS requires a slightly different set of packages. + ```bash + sudo apt install libgl1-mesa-dev libglu1-mesa-dev g++ g++-multilib gcc-multilib libasound2-dev libx11-dev libxext-dev libxi-dev libxrandr-dev libxinerama-dev libpulse-dev + ``` + - While Raspberry Pi OS also uses `apt`, it requires a slightly different set of packages. - ```bash - sudo apt install libgl1-mesa-dev libglu1-mesa-dev g++ libasound2-dev libx11-dev libxext-dev libxi-dev libxrandr-dev libxinerama-dev libpulse-dev libxcursor-dev libdbus-1-dev libdrm-dev libgbm-dev libudev-dev - ``` + ```bash + sudo apt install libgl1-mesa-dev libglu1-mesa-dev g++ libasound2-dev libx11-dev libxext-dev libxi-dev libxrandr-dev libxinerama-dev libpulse-dev libxcursor-dev libdbus-1-dev libdrm-dev libgbm-dev libudev-dev + ``` + - Fedora requires the following packages. + + ```bash + sudo dnf install g++ glibc-devel.x86_64 libstdc++-devel.x86_64 glibc-devel.i686 libstdc++-devel.i686 alsa-lib-devel pulseaudio-libs-devel libX11-devel libXi-devel libXrandr-devel libglvnd-devel + ``` - Building HashLink requires [additional packages](https://github.com/HaxeFoundation/hashlink#readme). ### Rebuilding diff --git a/project/include/app/Application.h b/project/include/app/Application.h index 863aa79bca..e7e5e7114a 100644 --- a/project/include/app/Application.h +++ b/project/include/app/Application.h @@ -20,7 +20,9 @@ namespace lime { virtual int Exec () = 0; virtual void Init () = 0; virtual int Quit () = 0; + virtual void SetMainLoop (int profile, double frameRate, int timePrecision, int busyWait, int uncapMode) { SetFrameRate (frameRate); } virtual void SetFrameRate (double frameRate) = 0; + virtual void SetVSyncMode (int vsyncMode) {} virtual bool Update () = 0; @@ -33,4 +35,4 @@ namespace lime { } -#endif \ No newline at end of file +#endif diff --git a/project/include/ui/Window.h b/project/include/ui/Window.h index 8dbf662c88..c8538aae0c 100644 --- a/project/include/ui/Window.h +++ b/project/include/ui/Window.h @@ -63,9 +63,12 @@ namespace lime { virtual void SetTextInputEnabled (bool enable) = 0; virtual void SetTextInputRect (Rectangle *rect) = 0; virtual const char* SetTitle (const char* title) = 0; + virtual void SetVSyncMode (int vsyncMode) {} virtual bool SetVisible (bool visible) = 0; virtual bool SetAlwaysOnTop (bool alwaysOnTop) = 0; virtual void WarpMouse (int x, int y) = 0; + virtual int GetVSyncInterval () const { return 0; } + virtual double GetRefreshRate () const { return 60.0; } Application* currentApplication; int flags; @@ -95,8 +98,11 @@ namespace lime { WINDOW_FLAG_MINIMIZED = 0x00002000, WINDOW_FLAG_MAXIMIZED = 0x00004000, WINDOW_FLAG_ALWAYS_ON_TOP = 0x00008000, - WINDOW_FLAG_COLOR_DEPTH_32_BIT = 0x00010000 - + WINDOW_FLAG_COLOR_DEPTH_32_BIT = 0x00010000, + WINDOW_FLAG_SKIP_TASKBAR = 0x00020000, + WINDOW_FLAG_UTILITY = 0x00040000, + WINDOW_FLAG_POPUP_MENU = 0x00080000, + WINDOW_FLAG_TOOLTIP = 0x00100000 }; } diff --git a/project/lib/mojoal b/project/lib/mojoal index aeaeff2132..e08dbf3982 160000 --- a/project/lib/mojoal +++ b/project/lib/mojoal @@ -1 +1 @@ -Subproject commit aeaeff21321d1d8ffb7a05811c80f9d4cc95a1be +Subproject commit e08dbf39828afbdaf0bf0b6e2a8bb861b7b86b10 diff --git a/project/src/ExternalInterface.cpp b/project/src/ExternalInterface.cpp index 91955558f3..b79615e78f 100644 --- a/project/src/ExternalInterface.cpp +++ b/project/src/ExternalInterface.cpp @@ -365,6 +365,38 @@ namespace lime { } + void lime_application_set_main_loop (value application, int profile, double frameRate, int timePrecision, int busyWait, int uncapMode) { + + Application* app = (Application*)val_data (application); + app->SetMainLoop (profile, frameRate, timePrecision, busyWait, uncapMode); + + } + + + HL_PRIM void HL_NAME(hl_application_set_main_loop) (HL_CFFIPointer* application, int profile, double frameRate, int timePrecision, int busyWait, int uncapMode) { + + Application* app = (Application*)application->ptr; + app->SetMainLoop (profile, frameRate, timePrecision, busyWait, uncapMode); + + } + + + void lime_application_set_vsync_mode (value application, int vsyncMode) { + + Application* app = (Application*)val_data (application); + app->SetVSyncMode (vsyncMode); + + } + + + HL_PRIM void HL_NAME(hl_application_set_vsync_mode) (HL_CFFIPointer* application, int vsyncMode) { + + Application* app = (Application*)application->ptr; + app->SetVSyncMode (vsyncMode); + + } + + bool lime_application_update (value application) { Application* app = (Application*)val_data (application); @@ -4079,7 +4111,9 @@ namespace lime { DEFINE_PRIME1 (lime_application_exec); DEFINE_PRIME1v (lime_application_init); DEFINE_PRIME1 (lime_application_quit); + DEFINE_PRIME6v (lime_application_set_main_loop); DEFINE_PRIME2v (lime_application_set_frame_rate); + DEFINE_PRIME2v (lime_application_set_vsync_mode); DEFINE_PRIME1 (lime_application_update); DEFINE_PRIME2 (lime_audio_load); DEFINE_PRIME2 (lime_audio_load_bytes); @@ -4276,6 +4310,8 @@ namespace lime { DEFINE_HL_PRIM (_VOID, hl_application_init, _TCFFIPOINTER); DEFINE_HL_PRIM (_I32, hl_application_quit, _TCFFIPOINTER); DEFINE_HL_PRIM (_VOID, hl_application_set_frame_rate, _TCFFIPOINTER _F64); + DEFINE_HL_PRIM (_VOID, hl_application_set_main_loop, _TCFFIPOINTER _I32 _F64 _I32 _I32 _I32); + DEFINE_HL_PRIM (_VOID, hl_application_set_vsync_mode, _TCFFIPOINTER _I32); DEFINE_HL_PRIM (_BOOL, hl_application_update, _TCFFIPOINTER); DEFINE_HL_PRIM (_TAUDIOBUFFER, hl_audio_load_bytes, _TBYTES _TAUDIOBUFFER); DEFINE_HL_PRIM (_TAUDIOBUFFER, hl_audio_load_file, _STRING _TAUDIOBUFFER); diff --git a/project/src/backend/sdl/SDLApplication.cpp b/project/src/backend/sdl/SDLApplication.cpp index 6627f827c9..a46345fe0b 100644 --- a/project/src/backend/sdl/SDLApplication.cpp +++ b/project/src/backend/sdl/SDLApplication.cpp @@ -1,6 +1,7 @@ #include "SDLApplication.h" #include "SDLGamepad.h" #include "SDLJoystick.h" +#include #include #ifdef HX_MACOS @@ -11,6 +12,8 @@ #include "emscripten.h" #endif +namespace lime +{ #ifdef LIME_SDL_SOUND #include "media/SDLSound.h" #include "SDL_sound.h" @@ -18,28 +21,36 @@ -namespace lime { - - - AutoGCRoot* Application::callback = 0; - SDLApplication* SDLApplication::currentApplication = 0; + AutoGCRoot *Application::callback = 0; + SDLApplication *SDLApplication::currentApplication = 0; const int analogAxisDeadZone = 1000; - std::map > gamepadsAxisMap; + std::map> gamepadsAxisMap; bool inBackground = false; + static SDL_atomic_t s_waitEventBlocking; +#if defined(HX_WINDOWS) && !defined(HX_WINRT) + static SDL_atomic_t s_nativeModalLoopDepth; + static SDL_atomic_t s_inModalEventWatch; +#endif - SDLApplication::SDLApplication () { + SDLApplication::SDLApplication() + { + allowBusyWait = true; + busyWaitOnly = false; + currentUpdate = 0.0; + displayRefreshRate = 60.0; initFlags = SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER | SDL_INIT_TIMER | SDL_INIT_JOYSTICK; - #if defined(LIME_MOJOAL) || defined(LIME_OPENALSOFT) + firstTime = true; +#if defined(LIME_MOJOAL) || defined(LIME_OPENALSOFT) initFlags |= SDL_INIT_AUDIO; - #endif - - if (SDL_Init (initFlags) != 0) { +#endif - printf ("Could not initialize SDL: %s.\n", SDL_GetError ()); + if (SDL_Init(initFlags) != 0) + { + printf("Could not initialize SDL: %s.\n", SDL_GetError()); } #ifdef LIME_SDL_SOUND @@ -53,12 +64,29 @@ namespace lime { SDL_LogSetPriority (SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_WARN); currentApplication = this; +#if defined(HX_WINDOWS) && !defined(HX_WINRT) + modalWatchInstalled = false; + mainThreadID = SDL_ThreadID(); + pendingResizeDispatchSkips = 0; + pendingWatchRenderSkips = 0; +#endif framePeriod = 1000.0 / 60.0; - - currentUpdate = 0; - lastUpdate = 0; - nextUpdate = 0; + lastUpdate = 0.0; + lastSleepCalibration = 0; + nextUpdate = 0.0; + performanceFrequency = SDL_GetPerformanceFrequency(); + realVSyncActive = false; + requestedBusyWaitMode = MAIN_LOOP_BUSY_WAIT_AUTO; + requestedFrameRate = 60.0; + requestedProfile = MAIN_LOOP_PROFILE_BALANCED; + requestedTimePrecisionMode = MAIN_LOOP_TIME_PRECISION_AUTO; + requestedUncapMode = MAIN_LOOP_UNCAP_OFF; + requestedVSyncMode = MAIN_LOOP_VSYNC_OFF; + schedulerUnthrottled = false; + sleepGuardMs = 2.0; + useDisplayDrivenFallback = false; + useHighResolutionTimer = false; ApplicationEvent applicationEvent; ClipboardEvent clipboardEvent; @@ -74,695 +102,1091 @@ namespace lime { TouchEvent touchEvent; WindowEvent windowEvent; - SDL_EventState (SDL_DROPFILE, SDL_ENABLE); - SDLJoystick::Init (); + SDL_EventState(SDL_DROPFILE, SDL_ENABLE); + SDLJoystick::Init(); +#if defined(HX_WINDOWS) && !defined(HX_WINRT) + SDL_AtomicSet(&s_nativeModalLoopDepth, 0); + SDL_AtomicSet(&s_inModalEventWatch, 0); + SDL_AtomicSet(&s_waitEventBlocking, 0); + SDL_AddEventWatch(ModalEventWatch, this); + modalWatchInstalled = true; +#endif - #ifdef HX_MACOS - CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL (CFBundleGetMainBundle ()); +#ifdef HX_MACOS + CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle()); char path[PATH_MAX]; - if (CFURLGetFileSystemRepresentation (resourcesURL, TRUE, (UInt8 *)path, PATH_MAX)) { - - chdir (path); + if (CFURLGetFileSystemRepresentation(resourcesURL, TRUE, (UInt8 *)path, PATH_MAX)) + { + chdir(path); } - CFRelease (resourcesURL); - #endif - + CFRelease(resourcesURL); +#endif } + void SDLApplication::AdvanceNextUpdate() + { - SDLApplication::~SDLApplication () { - - + if (schedulerUnthrottled || framePeriod <= 0.0) + { + nextUpdate = currentUpdate; + return; + } + nextUpdate += framePeriod; + while (nextUpdate <= currentUpdate) + { + nextUpdate += framePeriod; + } } + void SDLApplication::ApplyMainLoopSettings() + { - int SDLApplication::Exec () { + double clampedFrameRate = requestedFrameRate; + if (clampedFrameRate > 0.0 && clampedFrameRate > 10000.0) + clampedFrameRate = 10000.0; - Init (); + displayRefreshRate = GetDisplayRefreshRate(); + if (displayRefreshRate <= 0.0) + displayRefreshRate = 60.0; - #ifdef EMSCRIPTEN - emscripten_cancel_main_loop (); - emscripten_set_main_loop (UpdateFrame, 0, 0); - emscripten_set_main_loop_timing (EM_TIMING_RAF, 1); - #endif + realVSyncActive = false; + for (std::vector::const_iterator iter = windows.begin (); iter != windows.end (); ++iter) + { + if (*iter && (*iter)->GetVSyncInterval () != 0) + { + realVSyncActive = true; + break; + } + } - #if defined(IPHONE) || defined(EMSCRIPTEN) + useDisplayDrivenFallback = false; + schedulerUnthrottled = false; - return 0; + bool hasExplicitFrameRate = (clampedFrameRate > 0.0); + double effectiveFrameRate = hasExplicitFrameRate ? clampedFrameRate : 1.0; - #else + if (requestedUncapMode == MAIN_LOOP_UNCAP_SOFT || requestedUncapMode == MAIN_LOOP_UNCAP_HARD) + { + schedulerUnthrottled = true; + } + else if (realVSyncActive && hasExplicitFrameRate && clampedFrameRate >= displayRefreshRate) + { + schedulerUnthrottled = true; + } + else if (requestedVSyncMode == MAIN_LOOP_VSYNC_AUTO && !realVSyncActive && hasExplicitFrameRate && clampedFrameRate >= displayRefreshRate) + { + useDisplayDrivenFallback = true; + effectiveFrameRate = displayRefreshRate; + } - while (active) { + framePeriod = 1000.0 / effectiveFrameRate; - Update (); + switch (requestedTimePrecisionMode) + { + case MAIN_LOOP_TIME_PRECISION_MILLISECOND: + useHighResolutionTimer = false; + break; + + case MAIN_LOOP_TIME_PRECISION_HIGH_RESOLUTION: + useHighResolutionTimer = true; + break; + default: + useHighResolutionTimer = (requestedProfile == MAIN_LOOP_PROFILE_PRECISION || requestedProfile == MAIN_LOOP_PROFILE_UNCAPPED || + requestedUncapMode != MAIN_LOOP_UNCAP_OFF || clampedFrameRate > 1000.0); + break; } - return Quit (); + switch (requestedBusyWaitMode) + { + case MAIN_LOOP_BUSY_WAIT_OFF: + allowBusyWait = false; + break; - #endif + case MAIN_LOOP_BUSY_WAIT_ON: + allowBusyWait = true; + break; + + default: + allowBusyWait = (requestedProfile != MAIN_LOOP_PROFILE_LOW_ENERGY); + break; + } + busyWaitOnly = allowBusyWait && (requestedUncapMode == MAIN_LOOP_UNCAP_HARD || (framePeriod > 0.0 && framePeriod <= 2.0)); + currentUpdate = GetCurrentTimeMs(); + nextUpdate = currentUpdate; } + void SDLApplication::CalibrateSleepGuard(bool force) + { - void SDLApplication::HandleEvent (SDL_Event* event) { + Uint32 now = SDL_GetTicks(); + if (!force && lastSleepCalibration != 0 && (now - lastSleepCalibration) < 5000) + return; - #if defined(IPHONE) || defined(EMSCRIPTEN) + Uint32 t0 = SDL_GetTicks(); + SDL_Delay(1); + Uint32 t1 = SDL_GetTicks(); - int top = 0; - gc_set_top_of_stack(&top,false); + Uint32 observed = t1 - t0; + if (observed < 1) + observed = 1; - #endif + double observedD = (double)observed; - switch (event->type) { + if (lastSleepCalibration == 0 || force) + { - case SDL_USEREVENT: + sleepGuardMs = observedD; + } + else + { - if (!inBackground) { + // bend in scheduler changes passively so pacing stays stable + sleepGuardMs = (sleepGuardMs * 0.8) + (observedD * 0.2); + } - currentUpdate = SDL_GetTicks (); - applicationEvent.type = UPDATE; - applicationEvent.deltaTime = currentUpdate - lastUpdate; - lastUpdate = currentUpdate; + if (sleepGuardMs < 1.0) + sleepGuardMs = 1.0; + if (sleepGuardMs > 16.0) + sleepGuardMs = 16.0; - nextUpdate += framePeriod; + lastSleepCalibration = now; + } - while (nextUpdate <= currentUpdate) { + Uint32 SDLApplication::GetSleepGuardMs() const + { - nextUpdate += framePeriod; + Uint32 guardMs = (Uint32)(sleepGuardMs + 0.5); + if (guardMs < 1) + guardMs = 1; + return guardMs; + } - } + double SDLApplication::GetCurrentTimeMs() const + { - ApplicationEvent::Dispatch (&applicationEvent); - RenderEvent::Dispatch (&renderEvent); + if (useHighResolutionTimer && performanceFrequency != 0) + { + return ((double)SDL_GetPerformanceCounter() * 1000.0) / (double)performanceFrequency; + } - } + return (double)SDL_GetTicks(); + } - break; + double SDLApplication::GetDisplayRefreshRate() const + { - case SDL_APP_WILLENTERBACKGROUND: + for (std::vector::const_iterator iter = windows.begin (); iter != windows.end (); ++iter) + { + if (*iter) + { + double refreshRate = (*iter)->GetRefreshRate (); + if (refreshRate > 0.0) + return refreshRate; + } + } - inBackground = true; + return 60.0; + } - windowEvent.type = WINDOW_DEACTIVATE; - WindowEvent::Dispatch (&windowEvent); - break; + void SDLApplication::DispatchFrame(double now, bool renderFrame) + { - case SDL_APP_WILLENTERFOREGROUND: + currentUpdate = now; + applicationEvent.type = UPDATE; - break; + double delta = currentUpdate - lastUpdate; + if (delta < 0.0) + delta = 0.0; - case SDL_APP_DIDENTERFOREGROUND: + applicationEvent.deltaTime = (int)(delta + 0.5); + lastUpdate = currentUpdate; - windowEvent.type = WINDOW_ACTIVATE; - WindowEvent::Dispatch (&windowEvent); + AdvanceNextUpdate(); - inBackground = false; - break; + ApplicationEvent::Dispatch(&applicationEvent); - case SDL_CLIPBOARDUPDATE: + if (renderFrame) + { + RenderEvent::Dispatch(&renderEvent); + } + } - ProcessClipboardEvent (event); - break; + bool SDLApplication::IsFrameDue(double now) const + { - case SDL_CONTROLLERAXISMOTION: - case SDL_CONTROLLERBUTTONDOWN: - case SDL_CONTROLLERBUTTONUP: - case SDL_CONTROLLERDEVICEADDED: - case SDL_CONTROLLERDEVICEREMOVED: + if (schedulerUnthrottled) + return true; - ProcessGamepadEvent (event); - break; + return (now >= nextUpdate); + } - case SDL_DISPLAYEVENT: + bool SDLApplication::IsSchedulerUnthrottled() const + { - switch (event->display.event) { + return schedulerUnthrottled; + } - case SDL_DISPLAYEVENT_ORIENTATION: + void SDLApplication::RefreshVSyncState() + { - // this is the orientation of what is rendered, which - // may not exactly match the orientation of the device, - // if the app was locked to portrait or landscape. - orientationEvent.type = DISPLAY_ORIENTATION_CHANGE; - orientationEvent.orientation = event->display.data1; - orientationEvent.display = event->display.display; - OrientationEvent::Dispatch (&orientationEvent); + ApplyMainLoopSettings(); + } - break; + void SDLApplication::UpdateSleepGuard(Uint32 requestedMs, Uint32 elapsedMs) + { - } - break; + if (requestedMs == 0 || elapsedMs < requestedMs) + return; - case SDL_DROPFILE: + double overshoot = (double)elapsedMs - (double)requestedMs; + double targetGuard = overshoot + 1.0; - ProcessDropEvent (event); - break; + if (targetGuard < 1.0) + targetGuard = 1.0; + if (targetGuard > 16.0) + targetGuard = 16.0; - case SDL_FINGERMOTION: - case SDL_FINGERDOWN: - case SDL_FINGERUP: + sleepGuardMs = (sleepGuardMs * 0.9) + (targetGuard * 0.1); + } - ProcessTouchEvent (event); - break; + SDLApplication::~SDLApplication() + { +#if defined(HX_WINDOWS) && !defined(HX_WINRT) + if (modalWatchInstalled && SDL_WasInit(0)) + { + SDL_DelEventWatch(ModalEventWatch, this); + modalWatchInstalled = false; + } +#endif + } - case SDL_JOYAXISMOTION: +#if defined(HX_WINDOWS) && !defined(HX_WINRT) + void SDLApplication::EnterNativeModalLoop() + { - if (SDLJoystick::IsAccelerometer (event->jaxis.which)) { + SDL_AtomicAdd(&s_nativeModalLoopDepth, 1); + } - ProcessSensorEvent (event); + void SDLApplication::ExitNativeModalLoop() + { - } else { + int previousDepth = SDL_AtomicAdd(&s_nativeModalLoopDepth, -1); + if (previousDepth <= 1) + { + SDL_AtomicSet(&s_nativeModalLoopDepth, 0); + } + } - ProcessJoystickEvent (event); + int SDLApplication::ModalEventWatch(void *userdata, SDL_Event *event) + { - } + if (!event || event->type != SDL_WINDOWEVENT) + return 0; - break; + const Uint8 windowEvent = event->window.event; + if (windowEvent != SDL_WINDOWEVENT_EXPOSED && windowEvent != SDL_WINDOWEVENT_SIZE_CHANGED && windowEvent != SDL_WINDOWEVENT_RESIZED && windowEvent != SDL_WINDOWEVENT_MOVED) + return 0; - case SDL_JOYBALLMOTION: - case SDL_JOYBUTTONDOWN: - case SDL_JOYBUTTONUP: - case SDL_JOYHATMOTION: - case SDL_JOYDEVICEADDED: - case SDL_JOYDEVICEREMOVED: + SDLApplication *application = (SDLApplication *)userdata; + if (!application || !application->active || inBackground) + return 0; + if (SDL_AtomicGet(&s_waitEventBlocking) == 0 && SDL_AtomicGet(&s_nativeModalLoopDepth) == 0) + return 0; - ProcessJoystickEvent (event); - break; + if (SDL_ThreadID() != application->mainThreadID) + return 0; - case SDL_KEYDOWN: - case SDL_KEYUP: + // Prevent re-entry if rendering queues another window event. + if (!SDL_AtomicCAS(&s_inModalEventWatch, 0, 1)) + return 0; - ProcessKeyEvent (event); - break; + application->PumpOneFrameFromWatch(event); + SDL_AtomicSet(&s_inModalEventWatch, 0); + return 0; + } - case SDL_MOUSEMOTION: - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: - case SDL_MOUSEWHEEL: + void SDLApplication::PumpOneFrameFromWatch(SDL_Event *watchEvent) + { - ProcessMouseEvent (event); - break; + if (!active || inBackground) + return; - #ifndef EMSCRIPTEN - case SDL_RENDER_DEVICE_RESET: + bool isResizeEvent = false; + bool isExposeEvent = false; + if (watchEvent && watchEvent->type == SDL_WINDOWEVENT) + { + isResizeEvent = (watchEvent->window.event == SDL_WINDOWEVENT_SIZE_CHANGED || watchEvent->window.event == SDL_WINDOWEVENT_RESIZED); + isExposeEvent = (watchEvent->window.event == SDL_WINDOWEVENT_EXPOSED); + } - renderEvent.type = RENDER_CONTEXT_LOST; - RenderEvent::Dispatch (&renderEvent); + double now = GetCurrentTimeMs(); + bool frameDue = IsFrameDue(now); + bool isResizeOrExposeEvent = (isResizeEvent || isExposeEvent); + if (!frameDue && !isResizeEvent) + return; + + bool exitedBlocking = false; + if (SDL_AtomicGet(&s_waitEventBlocking)) + { + System::GCExitBlocking(); + SDL_AtomicSet(&s_waitEventBlocking, 0); + exitedBlocking = true; + } - renderEvent.type = RENDER_CONTEXT_RESTORED; - RenderEvent::Dispatch (&renderEvent); + if (isResizeEvent) + { + ProcessWindowEvent(watchEvent); + pendingResizeDispatchSkips++; + } - renderEvent.type = RENDER; - break; - #endif + if (frameDue) + { + DispatchFrame(now); - case SDL_TEXTINPUT: - case SDL_TEXTEDITING: + if (watchEvent && isResizeOrExposeEvent) + { + pendingWatchRenderSkips++; + } + } - ProcessTextEvent (event); - break; + if (exitedBlocking) + { + System::GCEnterBlocking(); + SDL_AtomicSet(&s_waitEventBlocking, 1); + } + } +#endif - case SDL_WINDOWEVENT: + int SDLApplication::Exec() + { - switch (event->window.event) { + Init(); - case SDL_WINDOWEVENT_ENTER: - case SDL_WINDOWEVENT_LEAVE: - case SDL_WINDOWEVENT_SHOWN: - case SDL_WINDOWEVENT_HIDDEN: - case SDL_WINDOWEVENT_FOCUS_GAINED: - case SDL_WINDOWEVENT_FOCUS_LOST: - case SDL_WINDOWEVENT_MAXIMIZED: - case SDL_WINDOWEVENT_MINIMIZED: - case SDL_WINDOWEVENT_MOVED: - case SDL_WINDOWEVENT_RESTORED: +#ifdef EMSCRIPTEN + emscripten_cancel_main_loop(); + emscripten_set_main_loop(UpdateFrame, 0, 0); + emscripten_set_main_loop_timing(EM_TIMING_RAF, 1); +#endif - ProcessWindowEvent (event); - break; +#if defined(IPHONE) || defined(EMSCRIPTEN) - case SDL_WINDOWEVENT_EXPOSED: + return 0; - ProcessWindowEvent (event); +#else - if (!inBackground) { + while (active) + { - RenderEvent::Dispatch (&renderEvent); + Update(); + } - } + return Quit(); - break; +#endif + } - case SDL_WINDOWEVENT_SIZE_CHANGED: + void SDLApplication::HandleEvent(SDL_Event *event) + { - ProcessWindowEvent (event); +#if defined(IPHONE) || defined(EMSCRIPTEN) - if (!inBackground) { + int top = 0; + gc_set_top_of_stack(&top, false); - RenderEvent::Dispatch (&renderEvent); +#endif - } + switch (event->type) + { - break; + case SDL_USEREVENT: - case SDL_WINDOWEVENT_CLOSE: + if (!inBackground) + { - ProcessWindowEvent (event); + DispatchFrame(GetCurrentTimeMs()); + } - // Avoid handling SDL_QUIT if in response to window.close - SDL_Event event; + break; - if (SDL_PollEvent (&event)) { + case SDL_APP_WILLENTERBACKGROUND: - if (event.type != SDL_QUIT) { + inBackground = true; - HandleEvent (&event); + windowEvent.type = WINDOW_DEACTIVATE; + WindowEvent::Dispatch(&windowEvent); + break; - } + case SDL_APP_WILLENTERFOREGROUND: - } - break; + break; - } + case SDL_APP_DIDENTERFOREGROUND: - break; + windowEvent.type = WINDOW_ACTIVATE; + WindowEvent::Dispatch(&windowEvent); - case SDL_QUIT: + inBackground = false; + break; - active = false; - break; + case SDL_CLIPBOARDUPDATE: - } + ProcessClipboardEvent(event); + break; - } + case SDL_CONTROLLERAXISMOTION: + case SDL_CONTROLLERBUTTONDOWN: + case SDL_CONTROLLERBUTTONUP: + case SDL_CONTROLLERDEVICEADDED: + case SDL_CONTROLLERDEVICEREMOVED: + ProcessGamepadEvent(event); + break; - void SDLApplication::Init () { + case SDL_DISPLAYEVENT: - active = true; - lastUpdate = SDL_GetTicks (); - nextUpdate = lastUpdate; + switch (event->display.event) + { - } + case SDL_DISPLAYEVENT_ORIENTATION: + // this is the orientation of what is rendered, which + // may not exactly match the orientation of the device, + // if the app was locked to portrait or landscape. + orientationEvent.type = DISPLAY_ORIENTATION_CHANGE; + orientationEvent.orientation = event->display.data1; + orientationEvent.display = event->display.display; + OrientationEvent::Dispatch(&orientationEvent); - void SDLApplication::ProcessClipboardEvent (SDL_Event* event) { + break; + } + break; - if (ClipboardEvent::callback) { + case SDL_DROPFILE: - clipboardEvent.type = CLIPBOARD_UPDATE; + ProcessDropEvent(event); + break; - ClipboardEvent::Dispatch (&clipboardEvent); + case SDL_FINGERMOTION: + case SDL_FINGERDOWN: + case SDL_FINGERUP: - } + ProcessTouchEvent(event); + break; - } + case SDL_JOYAXISMOTION: + if (SDLJoystick::IsAccelerometer(event->jaxis.which)) + { - void SDLApplication::ProcessDropEvent (SDL_Event* event) { + ProcessSensorEvent(event); + } + else + { - if (DropEvent::callback) { + ProcessJoystickEvent(event); + } - dropEvent.type = DROP_FILE; - dropEvent.file = (vbyte*)event->drop.file; + break; - DropEvent::Dispatch (&dropEvent); - SDL_free (dropEvent.file); + case SDL_JOYBALLMOTION: + case SDL_JOYBUTTONDOWN: + case SDL_JOYBUTTONUP: + case SDL_JOYHATMOTION: + case SDL_JOYDEVICEADDED: + case SDL_JOYDEVICEREMOVED: - } + ProcessJoystickEvent(event); + break; - } + case SDL_KEYDOWN: + case SDL_KEYUP: + ProcessKeyEvent(event); + break; - void SDLApplication::ProcessGamepadEvent (SDL_Event* event) { + case SDL_MOUSEMOTION: + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + case SDL_MOUSEWHEEL: - if (GamepadEvent::callback) { + ProcessMouseEvent(event); + break; - switch (event->type) { +#ifndef EMSCRIPTEN + case SDL_RENDER_DEVICE_RESET: - case SDL_CONTROLLERAXISMOTION: + renderEvent.type = RENDER_CONTEXT_LOST; + RenderEvent::Dispatch(&renderEvent); - if (gamepadsAxisMap[event->caxis.which].empty ()) { + renderEvent.type = RENDER_CONTEXT_RESTORED; + RenderEvent::Dispatch(&renderEvent); - gamepadsAxisMap[event->caxis.which][event->caxis.axis] = event->caxis.value; + renderEvent.type = RENDER; + break; +#endif - } else if (gamepadsAxisMap[event->caxis.which][event->caxis.axis] == event->caxis.value) { + case SDL_TEXTINPUT: + case SDL_TEXTEDITING: - break; + ProcessTextEvent(event); + break; - } + case SDL_WINDOWEVENT: + + switch (event->window.event) + { - gamepadEvent.type = GAMEPAD_AXIS_MOVE; - gamepadEvent.axis = event->caxis.axis; - gamepadEvent.id = event->caxis.which; + case SDL_WINDOWEVENT_ENTER: + case SDL_WINDOWEVENT_LEAVE: + case SDL_WINDOWEVENT_SHOWN: + case SDL_WINDOWEVENT_HIDDEN: + case SDL_WINDOWEVENT_FOCUS_GAINED: + case SDL_WINDOWEVENT_FOCUS_LOST: + case SDL_WINDOWEVENT_MAXIMIZED: + case SDL_WINDOWEVENT_MINIMIZED: + case SDL_WINDOWEVENT_MOVED: + case SDL_WINDOWEVENT_RESTORED: - if (event->caxis.value > -analogAxisDeadZone && event->caxis.value < analogAxisDeadZone) { + ProcessWindowEvent(event); + break; + + case SDL_WINDOWEVENT_EXPOSED: - if (gamepadsAxisMap[event->caxis.which][event->caxis.axis] != 0) { + ProcessWindowEvent(event); - gamepadsAxisMap[event->caxis.which][event->caxis.axis] = 0; - gamepadEvent.axisValue = 0; - GamepadEvent::Dispatch (&gamepadEvent); + if (!inBackground) + { + bool skipImmediateRender = false; +#if defined(HX_WINDOWS) && !defined(HX_WINRT) + if (pendingWatchRenderSkips > 0) + { + pendingWatchRenderSkips--; + skipImmediateRender = true; + } + if (SDL_AtomicGet(&s_waitEventBlocking)) + { + PumpOneFrameFromWatch(); + } + else +#endif + { + double now = GetCurrentTimeMs(); + bool frameDue = IsFrameDue(now); + if (frameDue) + { + DispatchFrame(now, !skipImmediateRender); } + } + } - break; + break; + + case SDL_WINDOWEVENT_SIZE_CHANGED: + case SDL_WINDOWEVENT_RESIZED: + { + + bool skipResizeDispatch = false; + bool skipImmediateRender = false; +#if defined(HX_WINDOWS) && !defined(HX_WINRT) + if (pendingResizeDispatchSkips > 0) + { + pendingResizeDispatchSkips--; + skipResizeDispatch = true; + } + if (pendingWatchRenderSkips > 0) + { + pendingWatchRenderSkips--; + skipImmediateRender = true; + } +#endif + if (!skipResizeDispatch) + { + ProcessWindowEvent(event); + } + if (!inBackground) + { +#if defined(HX_WINDOWS) && !defined(HX_WINRT) + if (SDL_AtomicGet(&s_waitEventBlocking)) + { + PumpOneFrameFromWatch(); } + else +#endif + { + double now = GetCurrentTimeMs(); + bool frameDue = IsFrameDue(now); + if (frameDue) + { + DispatchFrame(now, !skipImmediateRender); + } + } + } - gamepadsAxisMap[event->caxis.which][event->caxis.axis] = event->caxis.value; - gamepadEvent.axisValue = event->caxis.value / (event->caxis.value > 0 ? 32767.0 : 32768.0); + break; + } - GamepadEvent::Dispatch (&gamepadEvent); - break; + case SDL_WINDOWEVENT_CLOSE: - case SDL_CONTROLLERBUTTONDOWN: + ProcessWindowEvent(event); - gamepadEvent.type = GAMEPAD_BUTTON_DOWN; - gamepadEvent.button = event->cbutton.button; - gamepadEvent.id = event->cbutton.which; + // Avoid handling SDL_QUIT if in response to window.close + SDL_Event event; - GamepadEvent::Dispatch (&gamepadEvent); - break; + if (SDL_PollEvent(&event)) + { - case SDL_CONTROLLERBUTTONUP: + if (event.type != SDL_QUIT) + { - gamepadEvent.type = GAMEPAD_BUTTON_UP; - gamepadEvent.button = event->cbutton.button; - gamepadEvent.id = event->cbutton.which; + HandleEvent(&event); + } + } + break; + } - GamepadEvent::Dispatch (&gamepadEvent); - break; + break; - case SDL_CONTROLLERDEVICEADDED: + case SDL_QUIT: - if (SDLGamepad::Connect (event->cdevice.which)) { + active = false; + break; + } + } - gamepadEvent.type = GAMEPAD_CONNECT; - gamepadEvent.id = SDLGamepad::GetInstanceID (event->cdevice.which); + void SDLApplication::Init() + { - GamepadEvent::Dispatch (&gamepadEvent); + active = true; + lastUpdate = GetCurrentTimeMs(); + nextUpdate = lastUpdate; + firstTime = true; +#if defined(HX_WINDOWS) && !defined(HX_WINRT) + pendingResizeDispatchSkips = 0; + pendingWatchRenderSkips = 0; + SDL_AtomicSet(&s_nativeModalLoopDepth, 0); +#endif + CalibrateSleepGuard(true); + } - } + void SDLApplication::ProcessClipboardEvent(SDL_Event *event) + { - break; + if (ClipboardEvent::callback) + { - case SDL_CONTROLLERDEVICEREMOVED: { + clipboardEvent.type = CLIPBOARD_UPDATE; - gamepadEvent.type = GAMEPAD_DISCONNECT; - gamepadEvent.id = event->cdevice.which; + ClipboardEvent::Dispatch(&clipboardEvent); + } + } - GamepadEvent::Dispatch (&gamepadEvent); - SDLGamepad::Disconnect (event->cdevice.which); - break; + void SDLApplication::ProcessDropEvent(SDL_Event *event) + { - } + if (DropEvent::callback) + { - } + dropEvent.type = DROP_FILE; + dropEvent.file = (vbyte *)event->drop.file; + DropEvent::Dispatch(&dropEvent); + SDL_free(dropEvent.file); } - } + void SDLApplication::ProcessGamepadEvent(SDL_Event *event) + { - void SDLApplication::ProcessJoystickEvent (SDL_Event* event) { + if (GamepadEvent::callback) + { - if (JoystickEvent::callback) { + switch (event->type) + { - switch (event->type) { + case SDL_CONTROLLERAXISMOTION: - case SDL_JOYAXISMOTION: + if (gamepadsAxisMap[event->caxis.which].empty()) + { - if (!SDLJoystick::IsAccelerometer (event->jaxis.which)) { + gamepadsAxisMap[event->caxis.which][event->caxis.axis] = event->caxis.value; + } + else if (gamepadsAxisMap[event->caxis.which][event->caxis.axis] == event->caxis.value) + { + + break; + } - joystickEvent.type = JOYSTICK_AXIS_MOVE; - joystickEvent.index = event->jaxis.axis; - joystickEvent.x = event->jaxis.value / (event->jaxis.value > 0 ? 32767.0 : 32768.0); - joystickEvent.id = event->jaxis.which; + gamepadEvent.type = GAMEPAD_AXIS_MOVE; + gamepadEvent.axis = event->caxis.axis; + gamepadEvent.id = event->caxis.which; - JoystickEvent::Dispatch (&joystickEvent); + if (event->caxis.value > -analogAxisDeadZone && event->caxis.value < analogAxisDeadZone) + { + if (gamepadsAxisMap[event->caxis.which][event->caxis.axis] != 0) + { + + gamepadsAxisMap[event->caxis.which][event->caxis.axis] = 0; + gamepadEvent.axisValue = 0; + GamepadEvent::Dispatch(&gamepadEvent); } + break; + } + gamepadsAxisMap[event->caxis.which][event->caxis.axis] = event->caxis.value; + gamepadEvent.axisValue = event->caxis.value / (event->caxis.value > 0 ? 32767.0 : 32768.0); - case SDL_JOYBUTTONDOWN: + GamepadEvent::Dispatch(&gamepadEvent); + break; - if (!SDLJoystick::IsAccelerometer (event->jbutton.which)) { + case SDL_CONTROLLERBUTTONDOWN: - joystickEvent.type = JOYSTICK_BUTTON_DOWN; - joystickEvent.index = event->jbutton.button; - joystickEvent.id = event->jbutton.which; + gamepadEvent.type = GAMEPAD_BUTTON_DOWN; + gamepadEvent.button = event->cbutton.button; + gamepadEvent.id = event->cbutton.which; - JoystickEvent::Dispatch (&joystickEvent); + GamepadEvent::Dispatch(&gamepadEvent); + break; - } - break; + case SDL_CONTROLLERBUTTONUP: - case SDL_JOYBUTTONUP: + gamepadEvent.type = GAMEPAD_BUTTON_UP; + gamepadEvent.button = event->cbutton.button; + gamepadEvent.id = event->cbutton.which; - if (!SDLJoystick::IsAccelerometer (event->jbutton.which)) { + GamepadEvent::Dispatch(&gamepadEvent); + break; - joystickEvent.type = JOYSTICK_BUTTON_UP; - joystickEvent.index = event->jbutton.button; - joystickEvent.id = event->jbutton.which; + case SDL_CONTROLLERDEVICEADDED: - JoystickEvent::Dispatch (&joystickEvent); + if (SDLGamepad::Connect(event->cdevice.which)) + { - } - break; + gamepadEvent.type = GAMEPAD_CONNECT; + gamepadEvent.id = SDLGamepad::GetInstanceID(event->cdevice.which); + + GamepadEvent::Dispatch(&gamepadEvent); + } + + break; - case SDL_JOYHATMOTION: + case SDL_CONTROLLERDEVICEREMOVED: + { - if (!SDLJoystick::IsAccelerometer (event->jhat.which)) { + gamepadEvent.type = GAMEPAD_DISCONNECT; + gamepadEvent.id = event->cdevice.which; - joystickEvent.type = JOYSTICK_HAT_MOVE; - joystickEvent.index = event->jhat.hat; - joystickEvent.eventValue = event->jhat.value; - joystickEvent.id = event->jhat.which; + GamepadEvent::Dispatch(&gamepadEvent); + SDLGamepad::Disconnect(event->cdevice.which); + break; + } + } + } + } - JoystickEvent::Dispatch (&joystickEvent); + void SDLApplication::ProcessJoystickEvent(SDL_Event *event) + { - } - break; + if (JoystickEvent::callback) + { - case SDL_JOYDEVICEADDED: + switch (event->type) + { - if (SDLJoystick::Connect (event->jdevice.which)) { + case SDL_JOYAXISMOTION: - joystickEvent.type = JOYSTICK_CONNECT; - joystickEvent.id = SDLJoystick::GetInstanceID (event->jdevice.which); + if (!SDLJoystick::IsAccelerometer(event->jaxis.which)) + { - JoystickEvent::Dispatch (&joystickEvent); + joystickEvent.type = JOYSTICK_AXIS_MOVE; + joystickEvent.index = event->jaxis.axis; + joystickEvent.x = event->jaxis.value / (event->jaxis.value > 0 ? 32767.0 : 32768.0); + joystickEvent.id = event->jaxis.which; - } - break; + JoystickEvent::Dispatch(&joystickEvent); + } + break; - case SDL_JOYDEVICEREMOVED: + case SDL_JOYBUTTONDOWN: - if (!SDLJoystick::IsAccelerometer (event->jdevice.which)) { + if (!SDLJoystick::IsAccelerometer(event->jbutton.which)) + { - joystickEvent.type = JOYSTICK_DISCONNECT; - joystickEvent.id = event->jdevice.which; + joystickEvent.type = JOYSTICK_BUTTON_DOWN; + joystickEvent.index = event->jbutton.button; + joystickEvent.id = event->jbutton.which; - JoystickEvent::Dispatch (&joystickEvent); - SDLJoystick::Disconnect (event->jdevice.which); + JoystickEvent::Dispatch(&joystickEvent); + } + break; - } - break; + case SDL_JOYBUTTONUP: - } + if (!SDLJoystick::IsAccelerometer(event->jbutton.which)) + { - } + joystickEvent.type = JOYSTICK_BUTTON_UP; + joystickEvent.index = event->jbutton.button; + joystickEvent.id = event->jbutton.which; - } + JoystickEvent::Dispatch(&joystickEvent); + } + break; + case SDL_JOYHATMOTION: - void SDLApplication::ProcessKeyEvent (SDL_Event* event) { + if (!SDLJoystick::IsAccelerometer(event->jhat.which)) + { - if (KeyEvent::callback) { + joystickEvent.type = JOYSTICK_HAT_MOVE; + joystickEvent.index = event->jhat.hat; + joystickEvent.eventValue = event->jhat.value; + joystickEvent.id = event->jhat.which; - switch (event->type) { + JoystickEvent::Dispatch(&joystickEvent); + } + break; - case SDL_KEYDOWN: keyEvent.type = KEY_DOWN; break; - case SDL_KEYUP: keyEvent.type = KEY_UP; break; + case SDL_JOYDEVICEADDED: - } + if (SDLJoystick::Connect(event->jdevice.which)) + { - keyEvent.keyCode = event->key.keysym.sym; - keyEvent.modifier = event->key.keysym.mod; - keyEvent.windowID = event->key.windowID; + joystickEvent.type = JOYSTICK_CONNECT; + joystickEvent.id = SDLJoystick::GetInstanceID(event->jdevice.which); - if (keyEvent.type == KEY_DOWN) { + JoystickEvent::Dispatch(&joystickEvent); + } + break; - if (keyEvent.keyCode == SDLK_CAPSLOCK) keyEvent.modifier |= KMOD_CAPS; - if (keyEvent.keyCode == SDLK_LALT) keyEvent.modifier |= KMOD_LALT; - if (keyEvent.keyCode == SDLK_LCTRL) keyEvent.modifier |= KMOD_LCTRL; - if (keyEvent.keyCode == SDLK_LGUI) keyEvent.modifier |= KMOD_LGUI; - if (keyEvent.keyCode == SDLK_LSHIFT) keyEvent.modifier |= KMOD_LSHIFT; - if (keyEvent.keyCode == SDLK_MODE) keyEvent.modifier |= KMOD_MODE; - if (keyEvent.keyCode == SDLK_NUMLOCKCLEAR) keyEvent.modifier |= KMOD_NUM; - if (keyEvent.keyCode == SDLK_RALT) keyEvent.modifier |= KMOD_RALT; - if (keyEvent.keyCode == SDLK_RCTRL) keyEvent.modifier |= KMOD_RCTRL; - if (keyEvent.keyCode == SDLK_RGUI) keyEvent.modifier |= KMOD_RGUI; - if (keyEvent.keyCode == SDLK_RSHIFT) keyEvent.modifier |= KMOD_RSHIFT; + case SDL_JOYDEVICEREMOVED: - } + if (!SDLJoystick::IsAccelerometer(event->jdevice.which)) + { - KeyEvent::Dispatch (&keyEvent); + joystickEvent.type = JOYSTICK_DISCONNECT; + joystickEvent.id = event->jdevice.which; + JoystickEvent::Dispatch(&joystickEvent); + SDLJoystick::Disconnect(event->jdevice.which); + } + break; + } } - } + void SDLApplication::ProcessKeyEvent(SDL_Event *event) + { - void SDLApplication::ProcessMouseEvent (SDL_Event* event) { + if (KeyEvent::callback) + { - if (MouseEvent::callback) { + switch (event->type) + { - switch (event->type) { + case SDL_KEYDOWN: + keyEvent.type = KEY_DOWN; + break; + case SDL_KEYUP: + keyEvent.type = KEY_UP; + break; + } + + keyEvent.keyCode = event->key.keysym.sym; + keyEvent.modifier = event->key.keysym.mod; + keyEvent.windowID = event->key.windowID; - case SDL_MOUSEMOTION: + if (keyEvent.type == KEY_DOWN) + { + + if (keyEvent.keyCode == SDLK_CAPSLOCK) + keyEvent.modifier |= KMOD_CAPS; + if (keyEvent.keyCode == SDLK_LALT) + keyEvent.modifier |= KMOD_LALT; + if (keyEvent.keyCode == SDLK_LCTRL) + keyEvent.modifier |= KMOD_LCTRL; + if (keyEvent.keyCode == SDLK_LGUI) + keyEvent.modifier |= KMOD_LGUI; + if (keyEvent.keyCode == SDLK_LSHIFT) + keyEvent.modifier |= KMOD_LSHIFT; + if (keyEvent.keyCode == SDLK_MODE) + keyEvent.modifier |= KMOD_MODE; + if (keyEvent.keyCode == SDLK_NUMLOCKCLEAR) + keyEvent.modifier |= KMOD_NUM; + if (keyEvent.keyCode == SDLK_RALT) + keyEvent.modifier |= KMOD_RALT; + if (keyEvent.keyCode == SDLK_RCTRL) + keyEvent.modifier |= KMOD_RCTRL; + if (keyEvent.keyCode == SDLK_RGUI) + keyEvent.modifier |= KMOD_RGUI; + if (keyEvent.keyCode == SDLK_RSHIFT) + keyEvent.modifier |= KMOD_RSHIFT; + } - mouseEvent.type = MOUSE_MOVE; - mouseEvent.x = event->motion.x; - mouseEvent.y = event->motion.y; - mouseEvent.movementX = event->motion.xrel; - mouseEvent.movementY = event->motion.yrel; - break; + KeyEvent::Dispatch(&keyEvent); + } + } - case SDL_MOUSEBUTTONDOWN: + void SDLApplication::ProcessMouseEvent(SDL_Event *event) + { - SDL_CaptureMouse (SDL_TRUE); + if (MouseEvent::callback) + { - mouseEvent.type = MOUSE_DOWN; - mouseEvent.button = event->button.button - 1; - mouseEvent.x = event->button.x; - mouseEvent.y = event->button.y; - mouseEvent.clickCount = event->button.clicks; - break; + switch (event->type) + { - case SDL_MOUSEBUTTONUP: + case SDL_MOUSEMOTION: - SDL_CaptureMouse (SDL_FALSE); + mouseEvent.type = MOUSE_MOVE; + mouseEvent.x = event->motion.x; + mouseEvent.y = event->motion.y; + mouseEvent.movementX = event->motion.xrel; + mouseEvent.movementY = event->motion.yrel; + break; - mouseEvent.type = MOUSE_UP; - mouseEvent.button = event->button.button - 1; - mouseEvent.x = event->button.x; - mouseEvent.y = event->button.y; - mouseEvent.clickCount = event->button.clicks; - break; + case SDL_MOUSEBUTTONDOWN: + + SDL_CaptureMouse(SDL_TRUE); + + mouseEvent.type = MOUSE_DOWN; + mouseEvent.button = event->button.button - 1; + mouseEvent.x = event->button.x; + mouseEvent.y = event->button.y; + mouseEvent.clickCount = event->button.clicks; + break; - case SDL_MOUSEWHEEL: + case SDL_MOUSEBUTTONUP: - mouseEvent.type = MOUSE_WHEEL; + SDL_CaptureMouse(SDL_FALSE); - if (event->wheel.direction == SDL_MOUSEWHEEL_FLIPPED) { + mouseEvent.type = MOUSE_UP; + mouseEvent.button = event->button.button - 1; + mouseEvent.x = event->button.x; + mouseEvent.y = event->button.y; + mouseEvent.clickCount = event->button.clicks; + break; - mouseEvent.x = -event->wheel.x; - mouseEvent.y = -event->wheel.y; + case SDL_MOUSEWHEEL: - } else { + mouseEvent.type = MOUSE_WHEEL; - mouseEvent.x = event->wheel.x; - mouseEvent.y = event->wheel.y; + if (event->wheel.direction == SDL_MOUSEWHEEL_FLIPPED) + { - } - break; + mouseEvent.x = -event->wheel.x; + mouseEvent.y = -event->wheel.y; + } + else + { + mouseEvent.x = event->wheel.x; + mouseEvent.y = event->wheel.y; + } + break; } mouseEvent.windowID = event->button.windowID; - MouseEvent::Dispatch (&mouseEvent); - + MouseEvent::Dispatch(&mouseEvent); } - } + void SDLApplication::ProcessSensorEvent(SDL_Event *event) + { - void SDLApplication::ProcessSensorEvent (SDL_Event* event) { - - if (SensorEvent::callback) { + if (SensorEvent::callback) + { double value = event->jaxis.value / 32767.0f; - switch (event->jaxis.axis) { - - case 0: sensorEvent.x = value; break; - case 1: sensorEvent.y = value; break; - case 2: sensorEvent.z = value; break; - default: break; + switch (event->jaxis.axis) + { + case 0: + sensorEvent.x = value; + break; + case 1: + sensorEvent.y = value; + break; + case 2: + sensorEvent.z = value; + break; + default: + break; } - SensorEvent::Dispatch (&sensorEvent); - + SensorEvent::Dispatch(&sensorEvent); } - } + void SDLApplication::ProcessTextEvent(SDL_Event *event) + { - void SDLApplication::ProcessTextEvent (SDL_Event* event) { - - if (TextEvent::callback) { + if (TextEvent::callback) + { - switch (event->type) { + switch (event->type) + { - case SDL_TEXTINPUT: - - textEvent.type = TEXT_INPUT; - break; + case SDL_TEXTINPUT: - case SDL_TEXTEDITING: + textEvent.type = TEXT_INPUT; + break; - textEvent.type = TEXT_EDIT; - textEvent.start = event->edit.start; - textEvent.length = event->edit.length; - break; + case SDL_TEXTEDITING: + textEvent.type = TEXT_EDIT; + textEvent.start = event->edit.start; + textEvent.length = event->edit.length; + break; } - if (textEvent.text) { - - free (textEvent.text); + if (textEvent.text) + { + free(textEvent.text); } - textEvent.text = (vbyte*)malloc (strlen (event->text.text) + 1); - strcpy ((char*)textEvent.text, event->text.text); + textEvent.text = (vbyte *)malloc(strlen(event->text.text) + 1); + strcpy((char *)textEvent.text, event->text.text); textEvent.windowID = event->text.windowID; - TextEvent::Dispatch (&textEvent); - + TextEvent::Dispatch(&textEvent); } - } + void SDLApplication::ProcessTouchEvent(SDL_Event *event) + { - void SDLApplication::ProcessTouchEvent (SDL_Event* event) { + if (TouchEvent::callback) + { - if (TouchEvent::callback) { + switch (event->type) + { - switch (event->type) { - - case SDL_FINGERMOTION: - - touchEvent.type = TOUCH_MOVE; - break; + case SDL_FINGERMOTION: - case SDL_FINGERDOWN: + touchEvent.type = TOUCH_MOVE; + break; - touchEvent.type = TOUCH_START; - break; + case SDL_FINGERDOWN: - case SDL_FINGERUP: + touchEvent.type = TOUCH_START; + break; - touchEvent.type = TOUCH_END; - break; + case SDL_FINGERUP: + touchEvent.type = TOUCH_END; + break; } touchEvent.x = event->tfinger.x; @@ -773,60 +1197,88 @@ namespace lime { touchEvent.pressure = event->tfinger.pressure; touchEvent.device = event->tfinger.touchId; - TouchEvent::Dispatch (&touchEvent); - + TouchEvent::Dispatch(&touchEvent); } - } + void SDLApplication::ProcessWindowEvent(SDL_Event *event) + { - void SDLApplication::ProcessWindowEvent (SDL_Event* event) { - - if (WindowEvent::callback) { + if (WindowEvent::callback) + { - switch (event->window.event) { + switch (event->window.event) + { - case SDL_WINDOWEVENT_SHOWN: windowEvent.type = WINDOW_SHOW; break; - case SDL_WINDOWEVENT_CLOSE: windowEvent.type = WINDOW_CLOSE; break; - case SDL_WINDOWEVENT_HIDDEN: windowEvent.type = WINDOW_HIDE; break; - case SDL_WINDOWEVENT_ENTER: windowEvent.type = WINDOW_ENTER; break; - case SDL_WINDOWEVENT_FOCUS_GAINED: windowEvent.type = WINDOW_FOCUS_IN; break; - case SDL_WINDOWEVENT_FOCUS_LOST: windowEvent.type = WINDOW_FOCUS_OUT; break; - case SDL_WINDOWEVENT_LEAVE: windowEvent.type = WINDOW_LEAVE; break; - case SDL_WINDOWEVENT_MAXIMIZED: windowEvent.type = WINDOW_MAXIMIZE; break; - case SDL_WINDOWEVENT_MINIMIZED: windowEvent.type = WINDOW_MINIMIZE; break; - case SDL_WINDOWEVENT_EXPOSED: windowEvent.type = WINDOW_EXPOSE; break; - - case SDL_WINDOWEVENT_MOVED: + case SDL_WINDOWEVENT_SHOWN: + windowEvent.type = WINDOW_SHOW; + break; + case SDL_WINDOWEVENT_CLOSE: + windowEvent.type = WINDOW_CLOSE; + break; + case SDL_WINDOWEVENT_HIDDEN: + windowEvent.type = WINDOW_HIDE; + break; + case SDL_WINDOWEVENT_ENTER: + windowEvent.type = WINDOW_ENTER; + break; + case SDL_WINDOWEVENT_FOCUS_GAINED: + windowEvent.type = WINDOW_FOCUS_IN; + break; + case SDL_WINDOWEVENT_FOCUS_LOST: + windowEvent.type = WINDOW_FOCUS_OUT; + break; + case SDL_WINDOWEVENT_LEAVE: + windowEvent.type = WINDOW_LEAVE; + break; + case SDL_WINDOWEVENT_MAXIMIZED: + windowEvent.type = WINDOW_MAXIMIZE; + break; + case SDL_WINDOWEVENT_MINIMIZED: + windowEvent.type = WINDOW_MINIMIZE; + break; + case SDL_WINDOWEVENT_EXPOSED: + windowEvent.type = WINDOW_EXPOSE; + break; - windowEvent.type = WINDOW_MOVE; - windowEvent.x = event->window.data1; - windowEvent.y = event->window.data2; - break; + case SDL_WINDOWEVENT_MOVED: - case SDL_WINDOWEVENT_SIZE_CHANGED: + windowEvent.type = WINDOW_MOVE; + windowEvent.x = event->window.data1; + windowEvent.y = event->window.data2; + break; - windowEvent.type = WINDOW_RESIZE; - windowEvent.width = event->window.data1; - windowEvent.height = event->window.data2; - break; + case SDL_WINDOWEVENT_SIZE_CHANGED: + case SDL_WINDOWEVENT_RESIZED: - case SDL_WINDOWEVENT_RESTORED: windowEvent.type = WINDOW_RESTORE; break; + windowEvent.type = WINDOW_RESIZE; + windowEvent.width = event->window.data1; + windowEvent.height = event->window.data2; + break; + case SDL_WINDOWEVENT_RESTORED: + windowEvent.type = WINDOW_RESTORE; + break; } windowEvent.windowID = event->window.windowID; - WindowEvent::Dispatch (&windowEvent); - + WindowEvent::Dispatch(&windowEvent); } - } - - int SDLApplication::Quit () { + int SDLApplication::Quit() + { applicationEvent.type = EXIT; - ApplicationEvent::Dispatch (&applicationEvent); + ApplicationEvent::Dispatch(&applicationEvent); +#if defined(HX_WINDOWS) && !defined(HX_WINRT) + if (modalWatchInstalled) + { + SDL_DelEventWatch(ModalEventWatch, this); + modalWatchInstalled = false; + } + SDL_AtomicSet(&s_nativeModalLoopDepth, 0); +#endif #ifdef LIME_SDL_SOUND Sound_Quit (); @@ -834,201 +1286,429 @@ namespace lime { SDL_QuitSubSystem (initFlags); - SDL_Quit (); + SDL_Quit(); return 0; - } + void SDLApplication::RegisterWindow(SDLWindow *window) + { - void SDLApplication::RegisterWindow (SDLWindow *window) { + if (window && std::find (windows.begin (), windows.end (), window) == windows.end ()) + { + windows.push_back (window); + window->SetVSyncMode (requestedVSyncMode); + RefreshVSyncState (); + } - #ifdef IPHONE - SDL_iPhoneSetAnimationCallback (window->sdlWindow, 1, UpdateFrame, NULL); - #endif +#ifdef IPHONE + SDL_iPhoneSetAnimationCallback(window->sdlWindow, 1, UpdateFrame, NULL); +#endif + } + + void SDLApplication::UnregisterWindow(SDLWindow *window) + { + windows.erase (std::remove (windows.begin (), windows.end (), window), windows.end ()); + RefreshVSyncState (); } + void SDLApplication::SetMainLoop(int profile, double frameRate, int timePrecision, int busyWait, int uncapMode) + { - void SDLApplication::SetFrameRate (double frameRate) { + requestedProfile = profile; + requestedFrameRate = frameRate; + requestedTimePrecisionMode = timePrecision; + requestedBusyWaitMode = busyWait; + requestedUncapMode = uncapMode; + ApplyMainLoopSettings(); + } - if (frameRate > 0) { + void SDLApplication::SetFrameRate(double frameRate) + { - framePeriod = 1000.0 / frameRate; + requestedFrameRate = frameRate; + ApplyMainLoopSettings(); + } - } else { + void SDLApplication::SetVSyncMode(int vsyncMode) + { - framePeriod = 1000.0; + requestedVSyncMode = vsyncMode; + for (std::vector::iterator iter = windows.begin (); iter != windows.end (); ++iter) + { + if (*iter) + { + (*iter)->SetVSyncMode (requestedVSyncMode); + } } + RefreshVSyncState(); } + bool SDLApplication::Update() + { - static SDL_TimerID timerID = 0; - bool timerActive = false; - bool firstTime = true; + SDL_Event event; + event.type = -1; - Uint32 OnTimer (Uint32 interval, void *) { +#if (!defined(IPHONE) && !defined(EMSCRIPTEN)) - SDL_Event event; - SDL_UserEvent userevent; - userevent.type = SDL_USEREVENT; - userevent.code = 0; - userevent.data1 = NULL; - userevent.data2 = NULL; - event.type = SDL_USEREVENT; - event.user = userevent; + if (active && !firstTime && requestedUncapMode != MAIN_LOOP_UNCAP_HARD && WaitEvent(&event)) + { - timerActive = false; - timerID = 0; + HandleEvent(&event); + event.type = -1; + if (!active) + return active; + } - SDL_PushEvent (&event); + firstTime = false; - return 0; +#endif - } + while (SDL_PollEvent(&event)) + { + + HandleEvent(&event); + event.type = -1; + if (!active) + return active; + } + currentUpdate = GetCurrentTimeMs(); - bool SDLApplication::Update () { +#if defined(IPHONE) || defined(EMSCRIPTEN) - SDL_Event event; - event.type = -1; + if (IsFrameDue(currentUpdate)) + { - #if (!defined (IPHONE) && !defined (EMSCRIPTEN)) + event.type = SDL_USEREVENT; + HandleEvent(&event); + event.type = -1; + } - if (active && (firstTime || WaitEvent (&event))) { +#else - firstTime = false; + if (IsFrameDue(currentUpdate)) + { - HandleEvent (&event); + event.type = SDL_USEREVENT; + HandleEvent(&event); event.type = -1; - if (!active) - return active; + } - #endif +#endif - while (SDL_PollEvent (&event)) { + return active; + } - HandleEvent (&event); - event.type = -1; - if (!active) - return active; + void SDLApplication::UpdateFrame() + { - } +#ifdef EMSCRIPTEN + System::GCTryExitBlocking(); +#endif - currentUpdate = SDL_GetTicks (); + currentApplication->Update(); - #if defined (IPHONE) || defined (EMSCRIPTEN) +#ifdef EMSCRIPTEN + System::GCTryEnterBlocking(); +#endif + } - if (currentUpdate >= nextUpdate) { + void SDLApplication::UpdateFrame(void *) + { - event.type = SDL_USEREVENT; - HandleEvent (&event); - event.type = -1; + UpdateFrame(); + } - } + int SDLApplication::WaitEvent(SDL_Event *event) + { - #else +#if defined(HX_MACOS) || defined(ANDROID) - if (currentUpdate >= nextUpdate) { + for (;;) + { - if (timerActive) SDL_RemoveTimer (timerID); - OnTimer (0, 0); + double now = GetCurrentTimeMs(); + double remaining = nextUpdate - now; - } else if (!timerActive) { + if (schedulerUnthrottled || remaining <= 0.0) + { - timerActive = true; - timerID = SDL_AddTimer (nextUpdate - currentUpdate, OnTimer, 0); + SDL_zero(*event); + event->type = SDL_USEREVENT; + return 1; + } + + int waitMs = (int)(remaining + 0.999); + if (waitMs < 1) + waitMs = 1; + if (!allowBusyWait) + { + if (waitMs > 16) + waitMs = 16; } + else if (!busyWaitOnly) + { - } + CalibrateSleepGuard(); + Uint32 guardMs = GetSleepGuardMs(); + if (remaining > (double)guardMs + 1.0) + { - #endif + waitMs = (int)(remaining - (double)guardMs); + if (waitMs > 8) + waitMs = 8; + } + } - return active; + Uint32 waitStart = SDL_GetTicks(); + System::GCEnterBlocking(); + int result = SDL_WaitEventTimeout(event, waitMs); + System::GCExitBlocking(); + Uint32 waitElapsed = SDL_GetTicks() - waitStart; - } + if (result == 1) + return 1; + if (result == -1) + return 0; + if (allowBusyWait && !busyWaitOnly) + UpdateSleepGuard((Uint32)waitMs, waitElapsed); - void SDLApplication::UpdateFrame () { + if (allowBusyWait && busyWaitOnly) + { - #ifdef EMSCRIPTEN - System::GCTryExitBlocking (); - #endif + while ((nextUpdate - GetCurrentTimeMs()) > 0.0) + { - currentApplication->Update (); + SDL_PumpEvents(); - #ifdef EMSCRIPTEN - System::GCTryEnterBlocking (); - #endif + switch (SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) + { - } + case -1: + return 0; + case 1: + return 1; + + default: + break; + } + } - void SDLApplication::UpdateFrame (void*) { + SDL_zero(*event); + event->type = SDL_USEREVENT; + return 1; + } + } - UpdateFrame (); +#else - } + bool isBlocking = false; + SDL_AtomicSet(&s_waitEventBlocking, 0); + for (;;) + { - int SDLApplication::WaitEvent (SDL_Event *event) { + SDL_PumpEvents(); - #if defined(HX_MACOS) || defined(ANDROID) + switch (SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) + { - System::GCEnterBlocking (); - int result = SDL_WaitEvent (event); - System::GCExitBlocking (); - return result; + case -1: - #else + if (isBlocking) + { + SDL_AtomicSet(&s_waitEventBlocking, 0); + System::GCExitBlocking(); + } + return 0; - bool isBlocking = false; + case 1: - for(;;) { + if (isBlocking) + { + SDL_AtomicSet(&s_waitEventBlocking, 0); + System::GCExitBlocking(); + } + return 1; - SDL_PumpEvents (); + default: - switch (SDL_PeepEvents (event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) { + if (!isBlocking) + { + System::GCEnterBlocking(); + SDL_AtomicSet(&s_waitEventBlocking, 1); + } + isBlocking = true; - case -1: + double now = GetCurrentTimeMs(); + double remaining = nextUpdate - now; - if (isBlocking) System::GCExitBlocking (); - return 0; + if (schedulerUnthrottled || remaining <= 0.0) + { - case 1: + SDL_zero(*event); + event->type = SDL_USEREVENT; - if (isBlocking) System::GCExitBlocking (); + if (isBlocking) + { + SDL_AtomicSet(&s_waitEventBlocking, 0); + System::GCExitBlocking(); + } return 1; + } - default: + if (!allowBusyWait) + { + int waitMs = (int)(remaining + 0.999); + if (waitMs < 1) + waitMs = 1; + if (waitMs > 16) + waitMs = 16; + + SDL_zero(*event); + Uint32 waitStart = SDL_GetTicks(); + int waitResult = SDL_WaitEventTimeout(event, waitMs); + Uint32 waitElapsed = SDL_GetTicks() - waitStart; + + if (waitResult == 1) + { + + if (isBlocking) + { + SDL_AtomicSet(&s_waitEventBlocking, 0); + System::GCExitBlocking(); + } + return 1; + } + else if (waitResult == -1) + { - if (!isBlocking) System::GCEnterBlocking (); - isBlocking = true; - SDL_Delay (1); + if (isBlocking) + { + SDL_AtomicSet(&s_waitEventBlocking, 0); + System::GCExitBlocking(); + } + return 0; + } + + UpdateSleepGuard((Uint32)waitMs, waitElapsed); break; + } - } + if (!busyWaitOnly) + { - } + CalibrateSleepGuard(); - #endif + Uint32 guardMs = GetSleepGuardMs(); + if (remaining > (double)guardMs + 1.0) + { - } + Uint32 waitMs = (Uint32)(remaining - (double)guardMs); + if (waitMs > 8) + waitMs = 8; + + SDL_zero(*event); + Uint32 waitStart = SDL_GetTicks(); + int waitResult = SDL_WaitEventTimeout(event, (int)waitMs); + Uint32 waitElapsed = SDL_GetTicks() - waitStart; + if (waitResult == 1) + { - Application* CreateApplication () { + if (isBlocking) + { + SDL_AtomicSet(&s_waitEventBlocking, 0); + System::GCExitBlocking(); + } + return 1; + } + else if (waitResult == -1) + { - return new SDLApplication (); + if (isBlocking) + { + SDL_AtomicSet(&s_waitEventBlocking, 0); + System::GCExitBlocking(); + } + return 0; + } + UpdateSleepGuard(waitMs, waitElapsed); + break; + } + } + + // Busy-wait the final remainder for tighter frame pacing. + for (;;) + { + + SDL_PumpEvents(); + + switch (SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) + { + + case -1: + + if (isBlocking) + { + SDL_AtomicSet(&s_waitEventBlocking, 0); + System::GCExitBlocking(); + } + return 0; + + case 1: + + if (isBlocking) + { + SDL_AtomicSet(&s_waitEventBlocking, 0); + System::GCExitBlocking(); + } + return 1; + + default: + + if ((nextUpdate - GetCurrentTimeMs()) <= 0.0) + { + + SDL_zero(*event); + event->type = SDL_USEREVENT; + + if (isBlocking) + { + SDL_AtomicSet(&s_waitEventBlocking, 0); + System::GCExitBlocking(); + } + return 1; + } + + break; + } + } + + break; + } + } + +#endif } + Application *CreateApplication() + { -} + return new SDLApplication(); + } +} #ifdef ANDROID -int SDL_main (int argc, char *argv[]) { return 0; } +int SDL_main(int argc, char *argv[]) { return 0; } #endif diff --git a/project/src/backend/sdl/SDLApplication.h b/project/src/backend/sdl/SDLApplication.h index 679de5e932..397aa7ebc2 100644 --- a/project/src/backend/sdl/SDLApplication.h +++ b/project/src/backend/sdl/SDLApplication.h @@ -3,6 +3,7 @@ #include +#include #include #include #include @@ -33,14 +34,35 @@ namespace lime { virtual int Exec (); virtual void Init (); virtual int Quit (); + virtual void SetMainLoop (int profile, double frameRate, int timePrecision, int busyWait, int uncapMode); virtual void SetFrameRate (double frameRate); + virtual void SetVSyncMode (int vsyncMode); virtual bool Update (); void RegisterWindow (SDLWindow *window); + void UnregisterWindow (SDLWindow *window); +#if defined(HX_WINDOWS) && !defined(HX_WINRT) + static void EnterNativeModalLoop (); + static void ExitNativeModalLoop (); +#endif private: + void AdvanceNextUpdate (); + void ApplyMainLoopSettings (); + void CalibrateSleepGuard (bool force = false); + void DispatchFrame (double now, bool renderFrame = true); + double GetCurrentTimeMs () const; + double GetDisplayRefreshRate () const; + Uint32 GetSleepGuardMs () const; void HandleEvent (SDL_Event* event); + bool IsFrameDue (double now) const; + bool IsSchedulerUnthrottled () const; + void RefreshVSyncState (); +#if defined(HX_WINDOWS) && !defined(HX_WINRT) + void PumpOneFrameFromWatch (SDL_Event* watchEvent = 0); + static int ModalEventWatch (void* userdata, SDL_Event* event); +#endif void ProcessClipboardEvent (SDL_Event* event); void ProcessDropEvent (SDL_Event* event); void ProcessGamepadEvent (SDL_Event* event); @@ -51,6 +73,7 @@ namespace lime { void ProcessTextEvent (SDL_Event* event); void ProcessTouchEvent (SDL_Event* event); void ProcessWindowEvent (SDL_Event* event); + void UpdateSleepGuard (Uint32 requestedMs, Uint32 elapsedMs); int WaitEvent (SDL_Event* event); static void UpdateFrame (); @@ -58,25 +81,91 @@ namespace lime { static SDLApplication* currentApplication; + enum MainLoopProfileMode { + + MAIN_LOOP_PROFILE_BALANCED = 0, + MAIN_LOOP_PROFILE_PRECISION = 1, + MAIN_LOOP_PROFILE_LOW_ENERGY = 2, + MAIN_LOOP_PROFILE_UNCAPPED = 3 + + }; + + enum MainLoopTimePrecisionMode { + + MAIN_LOOP_TIME_PRECISION_AUTO = 0, + MAIN_LOOP_TIME_PRECISION_MILLISECOND = 1, + MAIN_LOOP_TIME_PRECISION_HIGH_RESOLUTION = 2 + + }; + + enum MainLoopBusyWaitMode { + + MAIN_LOOP_BUSY_WAIT_AUTO = 0, + MAIN_LOOP_BUSY_WAIT_OFF = 1, + MAIN_LOOP_BUSY_WAIT_ON = 2 + + }; + + enum MainLoopUncapMode { + + MAIN_LOOP_UNCAP_OFF = 0, + MAIN_LOOP_UNCAP_SOFT = 1, + MAIN_LOOP_UNCAP_HARD = 2 + + }; + + enum MainLoopVSyncMode { + + MAIN_LOOP_VSYNC_OFF = 0, + MAIN_LOOP_VSYNC_ON = 1, + MAIN_LOOP_VSYNC_ADAPTIVE = 2, + MAIN_LOOP_VSYNC_AUTO = 3 + + }; + bool active; + bool allowBusyWait; ApplicationEvent applicationEvent; + bool busyWaitOnly; ClipboardEvent clipboardEvent; - Uint32 currentUpdate; + double currentUpdate; + double displayRefreshRate; double framePeriod; Uint32 initFlags; DropEvent dropEvent; + bool firstTime; GamepadEvent gamepadEvent; JoystickEvent joystickEvent; KeyEvent keyEvent; - Uint32 lastUpdate; + double lastUpdate; + Uint32 lastSleepCalibration; MouseEvent mouseEvent; - Uint32 nextUpdate; + double nextUpdate; OrientationEvent orientationEvent; + Uint64 performanceFrequency; + bool realVSyncActive; + int requestedBusyWaitMode; + double requestedFrameRate; + int requestedProfile; + int requestedTimePrecisionMode; + int requestedUncapMode; + int requestedVSyncMode; RenderEvent renderEvent; SensorEvent sensorEvent; + bool schedulerUnthrottled; + double sleepGuardMs; TextEvent textEvent; TouchEvent touchEvent; + bool useDisplayDrivenFallback; + bool useHighResolutionTimer; WindowEvent windowEvent; + std::vector windows; +#if defined(HX_WINDOWS) && !defined(HX_WINRT) + bool modalWatchInstalled; + Uint32 mainThreadID; + int pendingResizeDispatchSkips; + int pendingWatchRenderSkips; +#endif }; @@ -84,4 +173,4 @@ namespace lime { } -#endif \ No newline at end of file +#endif diff --git a/project/src/backend/sdl/SDLWindow.cpp b/project/src/backend/sdl/SDLWindow.cpp index 635894655d..f8e3eb70c7 100644 --- a/project/src/backend/sdl/SDLWindow.cpp +++ b/project/src/backend/sdl/SDLWindow.cpp @@ -30,9 +30,172 @@ namespace lime { static bool displayModeSet = false; +#if defined (HX_WINDOWS) && !defined (HX_WINRT) + static const wchar_t* LIME_SDL_OLD_RESIZE_WNDPROC_PROP = L"LimeSDL.OldResizeWndProc"; + static const wchar_t* LIME_SDL_WINDOW_ID_PROP = L"LimeSDL.WindowID"; + static const wchar_t* LIME_SDL_LAST_RESIZE_WIDTH_PROP = L"LimeSDL.LastResizeWidth"; + static const wchar_t* LIME_SDL_LAST_RESIZE_HEIGHT_PROP = L"LimeSDL.LastResizeHeight"; + static const wchar_t* LIME_SDL_LAST_RESIZE_TICK_PROP = L"LimeSDL.LastResizeTick"; + static const Uint32 LIME_SDL_MIN_RESIZE_PUSH_INTERVAL_MS = 8; + + static bool ShouldQueueLiveResizeEvent (HWND hwnd, int width, int height, bool throttled) { + + if (width < 1 || height < 1) return false; + + int lastWidth = (int)(INT_PTR)GetPropW (hwnd, LIME_SDL_LAST_RESIZE_WIDTH_PROP); + int lastHeight = (int)(INT_PTR)GetPropW (hwnd, LIME_SDL_LAST_RESIZE_HEIGHT_PROP); + if (width == lastWidth && height == lastHeight) return false; + + Uint32 now = SDL_GetTicks (); + if (throttled) { + + Uint32 lastTick = (Uint32)(UINT_PTR)GetPropW (hwnd, LIME_SDL_LAST_RESIZE_TICK_PROP); + if (lastTick != 0 && (Uint32)(now - lastTick) < LIME_SDL_MIN_RESIZE_PUSH_INTERVAL_MS) { + + return false; + + } + + } + + SetPropW (hwnd, LIME_SDL_LAST_RESIZE_WIDTH_PROP, (HANDLE)(INT_PTR)width); + SetPropW (hwnd, LIME_SDL_LAST_RESIZE_HEIGHT_PROP, (HANDLE)(INT_PTR)height); + SetPropW (hwnd, LIME_SDL_LAST_RESIZE_TICK_PROP, (HANDLE)(UINT_PTR)now); + return true; + + } + + static void PushLiveResizeEvent (HWND hwnd, int width, int height, bool throttled) { + + if (!ShouldQueueLiveResizeEvent (hwnd, width, height, throttled)) return; + + Uint32 windowID = (Uint32)(UINT_PTR)GetPropW (hwnd, LIME_SDL_WINDOW_ID_PROP); + if (!windowID) return; + + SDL_Event event; + SDL_zero (event); + event.type = SDL_WINDOWEVENT; + event.window.event = SDL_WINDOWEVENT_SIZE_CHANGED; + event.window.windowID = windowID; + event.window.data1 = width; + event.window.data2 = height; + SDL_PushEvent (&event); + + } + + static void PushLiveResizeEventFromRect (HWND hwnd, const RECT* windowRect) { + + if (!windowRect) return; + + RECT currentWindowRect; + RECT currentClientRect; + if (!GetWindowRect (hwnd, ¤tWindowRect)) return; + if (!GetClientRect (hwnd, ¤tClientRect)) return; + + POINT currentClientTopLeft = { currentClientRect.left, currentClientRect.top }; + POINT currentClientBottomRight = { currentClientRect.right, currentClientRect.bottom }; + if (!ClientToScreen (hwnd, ¤tClientTopLeft) || !ClientToScreen (hwnd, ¤tClientBottomRight)) return; + + int nonClientWidth = (currentWindowRect.right - currentWindowRect.left) - (currentClientBottomRight.x - currentClientTopLeft.x); + int nonClientHeight = (currentWindowRect.bottom - currentWindowRect.top) - (currentClientBottomRight.y - currentClientTopLeft.y); + if (nonClientWidth < 0) nonClientWidth = 0; + if (nonClientHeight < 0) nonClientHeight = 0; + + int width = (windowRect->right - windowRect->left) - nonClientWidth; + int height = (windowRect->bottom - windowRect->top) - nonClientHeight; + PushLiveResizeEvent (hwnd, width, height, true); + + } + + static LRESULT CALLBACK LimeResizeWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { + + if (message == WM_ENTERSIZEMOVE) { + + SDLApplication::EnterNativeModalLoop (); + + } else if (message == WM_EXITSIZEMOVE) { + + SDLApplication::ExitNativeModalLoop (); + + } else if (message == WM_SIZING) { + + PushLiveResizeEventFromRect (hwnd, (const RECT*)lParam); + + } else if (message == WM_SIZE) { + + if (wParam != SIZE_MINIMIZED) { + + // Always send WM_SIZE updates (especially final size) without throttling. + PushLiveResizeEvent (hwnd, LOWORD (lParam), HIWORD (lParam), false); + + } + + } + + WNDPROC oldWndProc = (WNDPROC)GetPropW (hwnd, LIME_SDL_OLD_RESIZE_WNDPROC_PROP); + if (oldWndProc) { + + return CallWindowProc (oldWndProc, hwnd, message, wParam, lParam); + + } + + return DefWindowProc (hwnd, message, wParam, lParam); + + } + + static void InstallResizeEventHook (SDL_Window* sdlWindow) { + + if (!sdlWindow) return; + + SDL_SysWMinfo wminfo; + SDL_VERSION (&wminfo.version); + if (SDL_GetWindowWMInfo (sdlWindow, &wminfo) != 1) return; + + HWND hwnd = wminfo.info.win.window; + if (!hwnd) return; + if (GetPropW (hwnd, LIME_SDL_OLD_RESIZE_WNDPROC_PROP)) return; + + SetLastError (0); + LONG_PTR previous = SetWindowLongPtr (hwnd, GWLP_WNDPROC, (LONG_PTR)LimeResizeWndProc); + if (previous == 0 && GetLastError () != 0) return; + + SetPropW (hwnd, LIME_SDL_OLD_RESIZE_WNDPROC_PROP, (HANDLE)previous); + SetPropW (hwnd, LIME_SDL_WINDOW_ID_PROP, (HANDLE)(UINT_PTR)SDL_GetWindowID (sdlWindow)); + + } + + static void RestoreResizeEventHook (SDL_Window* sdlWindow) { + + if (!sdlWindow) return; + + SDL_SysWMinfo wminfo; + SDL_VERSION (&wminfo.version); + if (SDL_GetWindowWMInfo (sdlWindow, &wminfo) != 1) return; + + HWND hwnd = wminfo.info.win.window; + if (!hwnd) return; + + WNDPROC oldWndProc = (WNDPROC)GetPropW (hwnd, LIME_SDL_OLD_RESIZE_WNDPROC_PROP); + if (oldWndProc) { + + SetWindowLongPtr (hwnd, GWLP_WNDPROC, (LONG_PTR)oldWndProc); + + } + + RemovePropW (hwnd, LIME_SDL_WINDOW_ID_PROP); + RemovePropW (hwnd, LIME_SDL_OLD_RESIZE_WNDPROC_PROP); + RemovePropW (hwnd, LIME_SDL_LAST_RESIZE_WIDTH_PROP); + RemovePropW (hwnd, LIME_SDL_LAST_RESIZE_HEIGHT_PROP); + RemovePropW (hwnd, LIME_SDL_LAST_RESIZE_TICK_PROP); + + } +#endif + SDLWindow::SDLWindow (Application* application, int width, int height, int flags, const char* title) { + activeSwapInterval = 0; + requestedVSyncMode = (flags & WINDOW_FLAG_VSYNC) ? 1 : 0; sdlTexture = 0; sdlRenderer = 0; context = 0; @@ -167,6 +330,10 @@ namespace lime { } + #if defined (HX_WINDOWS) && !defined (HX_WINRT) + InstallResizeEventHook (sdlWindow); + #endif + #if defined (HX_WINDOWS) && !defined (HX_WINRT) HINSTANCE handle = ::GetModuleHandle (nullptr); @@ -219,15 +386,7 @@ namespace lime { if (context && SDL_GL_MakeCurrent (sdlWindow, context) == 0) { - if (flags & WINDOW_FLAG_VSYNC) { - - SDL_GL_SetSwapInterval (1); - - } else { - - SDL_GL_SetSwapInterval (0); - - } + SetVSyncMode (requestedVSyncMode); OpenGLBindings::Init (); @@ -297,8 +456,18 @@ namespace lime { SDLWindow::~SDLWindow () { + if (currentApplication) { + + ((SDLApplication*)currentApplication)->UnregisterWindow (this); + + } + if (sdlWindow) { + #if defined (HX_WINDOWS) && !defined (HX_WINRT) + RestoreResizeEventHook (sdlWindow); + #endif + SDL_DestroyWindow (sdlWindow); sdlWindow = 0; @@ -352,6 +521,16 @@ namespace lime { if (sdlWindow) { + if (currentApplication) { + + ((SDLApplication*)currentApplication)->UnregisterWindow (this); + + } + + #if defined (HX_WINDOWS) && !defined (HX_WINRT) + RestoreResizeEventHook (sdlWindow); + #endif + SDL_DestroyWindow (sdlWindow); sdlWindow = 0; @@ -392,6 +571,40 @@ namespace lime { } + int SDLWindow::GetVSyncInterval () const { + + return activeSwapInterval; + + } + + + double SDLWindow::GetRefreshRate () const { + + if (!sdlWindow) { + + return 60.0; + + } + + SDL_DisplayMode displayMode; + if (SDL_GetWindowDisplayMode (sdlWindow, &displayMode) == 0 && displayMode.refresh_rate > 0) { + + return displayMode.refresh_rate; + + } + + int displayIndex = SDL_GetWindowDisplayIndex (sdlWindow); + if (displayIndex >= 0 && SDL_GetCurrentDisplayMode (displayIndex, &displayMode) == 0 && displayMode.refresh_rate > 0) { + + return displayMode.refresh_rate; + + } + + return 60.0; + + } + + void* SDLWindow::ContextLock (bool useCFFIValue) { if (sdlRenderer) { @@ -1115,6 +1328,82 @@ namespace lime { } + void SDLWindow::SetVSyncMode (int vsyncMode) { + + requestedVSyncMode = vsyncMode; + activeSwapInterval = 0; + + if (!sdlWindow || !context || sdlRenderer) { + + flags &= ~WINDOW_FLAG_VSYNC; + return; + + } + + SDL_Window* oldWindow = SDL_GL_GetCurrentWindow (); + SDL_GLContext oldContext = SDL_GL_GetCurrentContext (); + bool restoreContext = (oldWindow != sdlWindow || oldContext != context); + + if (restoreContext) { + + SDL_GL_MakeCurrent (sdlWindow, context); + + } + + switch (vsyncMode) { + + case 1: + + if (SDL_GL_SetSwapInterval (1) == 0) { + + activeSwapInterval = 1; + + } + + break; + + case 2: + case 3: + + if (SDL_GL_SetSwapInterval (-1) == 0) { + + activeSwapInterval = -1; + + } else if (SDL_GL_SetSwapInterval (1) == 0) { + + activeSwapInterval = 1; + + } + + break; + + default: + + SDL_GL_SetSwapInterval (0); + activeSwapInterval = 0; + break; + + } + + if (activeSwapInterval == 0) { + + SDL_GL_SetSwapInterval (0); + flags &= ~WINDOW_FLAG_VSYNC; + + } else { + + flags |= WINDOW_FLAG_VSYNC; + + } + + if (restoreContext && oldWindow && oldContext) { + + SDL_GL_MakeCurrent (oldWindow, oldContext); + + } + } + + const char* SDLWindow::SetTitle (const char* title) { SDL_SetWindowTitle (sdlWindow, title); diff --git a/project/src/backend/sdl/SDLWindow.h b/project/src/backend/sdl/SDLWindow.h index 4e328f10a4..b7aff0f308 100644 --- a/project/src/backend/sdl/SDLWindow.h +++ b/project/src/backend/sdl/SDLWindow.h @@ -57,18 +57,23 @@ namespace lime { virtual void SetTextInputEnabled (bool enabled); virtual void SetTextInputRect (Rectangle *rect); virtual const char* SetTitle (const char* title); + virtual void SetVSyncMode (int vsyncMode); virtual bool SetVisible (bool visible); virtual bool SetAlwaysOnTop (bool alwaysOnTop); virtual void WarpMouse (int x, int y); + virtual int GetVSyncInterval () const; + virtual double GetRefreshRate () const; SDL_Renderer* sdlRenderer; SDL_Texture* sdlTexture; SDL_Window* sdlWindow; private: + int activeSwapInterval; SDL_GLContext context; int contextHeight; int contextWidth; + int requestedVSyncMode; }; diff --git a/project/src/graphics/opengl/OpenGLBindings.cpp b/project/src/graphics/opengl/OpenGLBindings.cpp index 31f71096ee..08f77d0106 100644 --- a/project/src/graphics/opengl/OpenGLBindings.cpp +++ b/project/src/graphics/opengl/OpenGLBindings.cpp @@ -29,6 +29,12 @@ namespace lime { + // TODO(lime): `defined (LIME_GLES3_API) || !defined (LIME_GLES)` is a + // stopgap for desktop-valid modern GL wrappers. Desktop proc loading already + // exists, but `LIME_GLES3_API` is too narrow a gate for desktop GL. Audit the + // remaining GLES3-only wrappers and replace this pattern with an explicit + // desktop-GL macro/capability gate later, rather than broadening everything + // mechanically. bool OpenGLBindings::initialized = false; @@ -93,6 +99,45 @@ namespace lime { } + void hl_gc_gl_object (HL_CFFIPointer* handle) { + + gc_gl_mutex.Lock (); + + void* object = handle->ptr; + + if (glObjectTypes.find (object) != glObjectTypes.end ()) { + + GLObjectType type = glObjectTypes[object]; + + if (type != TYPE_SYNC) { + + GLuint id = glObjectIDs[object]; + + gc_gl_id.push_back (id); + gc_gl_type.push_back (type); + + glObjects[type].erase (id); + glObjectIDs.erase (object); + glObjectTypes.erase (object); + + } else { + + void* ptr = glObjectPtrs[object]; + + gc_gl_ptr.push_back (ptr); + + glObjectPtrs.erase (object); + glObjectTypes.erase (object); + + } + + } + + gc_gl_mutex.Unlock (); + + } + + void gc_gl_run () { if (gc_gl_id.size () > 0) { @@ -386,8 +431,10 @@ namespace lime { void lime_gl_bind_sampler (int unit, int sampler) { - #ifdef LIME_GLES3_API - glBindSampler (unit, sampler); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glBindSampler) { + glBindSampler (unit, sampler); + } #endif } @@ -395,8 +442,10 @@ namespace lime { HL_PRIM void HL_NAME(hl_gl_bind_sampler) (int unit, int sampler) { - #ifdef LIME_GLES3_API - glBindSampler (unit, sampler); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glBindSampler) { + glBindSampler (unit, sampler); + } #endif } @@ -436,8 +485,10 @@ namespace lime { void lime_gl_bind_vertex_array (int vertexArray) { - #ifdef LIME_GLES3_API - glBindVertexArray (vertexArray); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glBindVertexArray) { + glBindVertexArray (vertexArray); + } #endif } @@ -445,8 +496,10 @@ namespace lime { HL_PRIM void HL_NAME(hl_gl_bind_vertex_array) (int vertexArray) { - #ifdef LIME_GLES3_API - glBindVertexArray (vertexArray); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glBindVertexArray) { + glBindVertexArray (vertexArray); + } #endif } @@ -524,8 +577,10 @@ namespace lime { void lime_gl_blit_framebuffer (int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, int mask, int filter) { - #ifdef LIME_GLES3_API - glBlitFramebuffer (srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glBlitFramebuffer) { + glBlitFramebuffer (srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + } #endif } @@ -533,8 +588,10 @@ namespace lime { HL_PRIM void HL_NAME(hl_gl_blit_framebuffer) (int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, int mask, int filter) { - #ifdef LIME_GLES3_API - glBlitFramebuffer (srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glBlitFramebuffer) { + glBlitFramebuffer (srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + } #endif } @@ -600,8 +657,10 @@ namespace lime { void lime_gl_clear_bufferfi (int buffer, int drawBuffer, float depth, int stencil) { - #ifdef LIME_GLES3_API - glClearBufferfi (buffer, drawBuffer, depth, stencil); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glClearBufferfi) { + glClearBufferfi (buffer, drawBuffer, depth, stencil); + } #endif } @@ -609,8 +668,10 @@ namespace lime { HL_PRIM void HL_NAME(hl_gl_clear_bufferfi) (int buffer, int drawBuffer, float depth, int stencil) { - #ifdef LIME_GLES3_API - glClearBufferfi (buffer, drawBuffer, depth, stencil); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glClearBufferfi) { + glClearBufferfi (buffer, drawBuffer, depth, stencil); + } #endif } @@ -618,8 +679,10 @@ namespace lime { void lime_gl_clear_bufferfv (int buffer, int drawBuffer, double data) { - #ifdef LIME_GLES3_API - glClearBufferfv (buffer, drawBuffer, (GLfloat*)(uintptr_t)data); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glClearBufferfv) { + glClearBufferfv (buffer, drawBuffer, (GLfloat*)(uintptr_t)data); + } #endif } @@ -627,8 +690,10 @@ namespace lime { HL_PRIM void HL_NAME(hl_gl_clear_bufferfv) (int buffer, int drawBuffer, double data) { - #ifdef LIME_GLES3_API - glClearBufferfv (buffer, drawBuffer, (GLfloat*)(uintptr_t)data); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glClearBufferfv) { + glClearBufferfv (buffer, drawBuffer, (GLfloat*)(uintptr_t)data); + } #endif } @@ -636,8 +701,10 @@ namespace lime { void lime_gl_clear_bufferiv (int buffer, int drawBuffer, double data) { - #ifdef LIME_GLES3_API - glClearBufferiv (buffer, drawBuffer, (GLint*)(uintptr_t)data); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glClearBufferiv) { + glClearBufferiv (buffer, drawBuffer, (GLint*)(uintptr_t)data); + } #endif } @@ -645,8 +712,10 @@ namespace lime { HL_PRIM void HL_NAME(hl_gl_clear_bufferiv) (int buffer, int drawBuffer, double data) { - #ifdef LIME_GLES3_API - glClearBufferiv (buffer, drawBuffer, (GLint*)(uintptr_t)data); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glClearBufferiv) { + glClearBufferiv (buffer, drawBuffer, (GLint*)(uintptr_t)data); + } #endif } @@ -654,8 +723,10 @@ namespace lime { void lime_gl_clear_bufferuiv (int buffer, int drawBuffer, double data) { - #ifdef LIME_GLES3_API - glClearBufferuiv (buffer, drawBuffer, (GLuint*)(uintptr_t)data); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glClearBufferuiv) { + glClearBufferuiv (buffer, drawBuffer, (GLuint*)(uintptr_t)data); + } #endif } @@ -663,8 +734,10 @@ namespace lime { HL_PRIM void HL_NAME(hl_gl_clear_bufferuiv) (int buffer, int drawBuffer, double data) { - #ifdef LIME_GLES3_API - glClearBufferuiv (buffer, drawBuffer, (GLuint*)(uintptr_t)data); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glClearBufferuiv) { + glClearBufferuiv (buffer, drawBuffer, (GLuint*)(uintptr_t)data); + } #endif } @@ -838,8 +911,10 @@ namespace lime { void lime_gl_copy_buffer_sub_data (int readTarget, int writeTarget, double readOffset, double writeOffset, int size) { - #ifdef LIME_GLES3_API - glCopyBufferSubData (readTarget, writeTarget, (GLintptr)(uintptr_t)readOffset, (GLintptr)(uintptr_t)writeOffset, size); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glCopyBufferSubData) { + glCopyBufferSubData (readTarget, writeTarget, (GLintptr)(uintptr_t)readOffset, (GLintptr)(uintptr_t)writeOffset, size); + } #endif } @@ -847,8 +922,10 @@ namespace lime { HL_PRIM void HL_NAME(hl_gl_copy_buffer_sub_data) (int readTarget, int writeTarget, double readOffset, double writeOffset, int size) { - #ifdef LIME_GLES3_API - glCopyBufferSubData (readTarget, writeTarget, (GLintptr)(uintptr_t)readOffset, (GLintptr)(uintptr_t)writeOffset, size); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glCopyBufferSubData) { + glCopyBufferSubData (readTarget, writeTarget, (GLintptr)(uintptr_t)readOffset, (GLintptr)(uintptr_t)writeOffset, size); + } #endif } @@ -884,8 +961,10 @@ namespace lime { void lime_gl_copy_tex_sub_image_3d (int target, int level, int xoffset, int yoffset, int zoffset, int x, int y, int width, int height) { - #ifdef LIME_GLES3_API - glCopyTexSubImage3D (target, level, xoffset, yoffset, zoffset, x, y, width, height); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glCopyTexSubImage3D) { + glCopyTexSubImage3D (target, level, xoffset, yoffset, zoffset, x, y, width, height); + } #endif } @@ -893,8 +972,10 @@ namespace lime { HL_PRIM void HL_NAME(hl_gl_copy_tex_sub_image_3d) (int target, int level, int xoffset, int yoffset, int zoffset, int x, int y, int width, int height) { - #ifdef LIME_GLES3_API - glCopyTexSubImage3D (target, level, xoffset, yoffset, zoffset, x, y, width, height); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glCopyTexSubImage3D) { + glCopyTexSubImage3D (target, level, xoffset, yoffset, zoffset, x, y, width, height); + } #endif } @@ -993,8 +1074,10 @@ namespace lime { int lime_gl_create_sampler () { GLuint id = 0; - #ifdef LIME_GLES3_API - glGenSamplers (1, &id); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glGenSamplers) { + glGenSamplers (1, &id); + } #endif return id; @@ -1004,8 +1087,10 @@ namespace lime { HL_PRIM int HL_NAME(hl_gl_create_sampler) () { GLuint id = 0; - #ifdef LIME_GLES3_API - glGenSamplers (1, &id); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glGenSamplers) { + glGenSamplers (1, &id); + } #endif return id; @@ -1069,8 +1154,10 @@ namespace lime { int lime_gl_create_vertex_array () { GLuint id = 0; - #ifdef LIME_GLES3_API - glGenVertexArrays (1, &id); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glGenVertexArrays) { + glGenVertexArrays (1, &id); + } #endif return id; @@ -1080,8 +1167,10 @@ namespace lime { HL_PRIM int HL_NAME(hl_gl_create_vertex_array) () { GLuint id = 0; - #ifdef LIME_GLES3_API - glGenVertexArrays (1, &id); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glGenVertexArrays) { + glGenVertexArrays (1, &id); + } #endif return id; @@ -1178,8 +1267,10 @@ namespace lime { void lime_gl_delete_sampler (int sampler) { - #ifdef LIME_GLES3_API - glDeleteSamplers (1, (GLuint*)&sampler); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glDeleteSamplers) { + glDeleteSamplers (1, (GLuint*)&sampler); + } #endif } @@ -1187,8 +1278,10 @@ namespace lime { HL_PRIM void HL_NAME(hl_gl_delete_sampler) (int sampler) { - #ifdef LIME_GLES3_API - glDeleteSamplers (1, (GLuint*)&sampler); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glDeleteSamplers) { + glDeleteSamplers (1, (GLuint*)&sampler); + } #endif } @@ -1262,8 +1355,10 @@ namespace lime { void lime_gl_delete_vertex_array (int vertexArray) { - #ifdef LIME_GLES3_API - glDeleteVertexArrays (1, (GLuint*)&vertexArray); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glDeleteVertexArrays) { + glDeleteVertexArrays (1, (GLuint*)&vertexArray); + } #endif } @@ -1271,8 +1366,10 @@ namespace lime { HL_PRIM void HL_NAME(hl_gl_delete_vertex_array) (int vertexArray) { - #ifdef LIME_GLES3_API - glDeleteVertexArrays (1, (GLuint*)&vertexArray); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glDeleteVertexArrays) { + glDeleteVertexArrays (1, (GLuint*)&vertexArray); + } #endif } @@ -1386,8 +1483,10 @@ namespace lime { void lime_gl_draw_arrays_instanced (int mode, int first, int count, int instanceCount) { - #ifdef LIME_GLES3_API - glDrawArraysInstanced (mode, first, count, instanceCount); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glDrawArraysInstanced) { + glDrawArraysInstanced (mode, first, count, instanceCount); + } #endif } @@ -1395,8 +1494,10 @@ namespace lime { HL_PRIM void HL_NAME(hl_gl_draw_arrays_instanced) (int mode, int first, int count, int instanceCount) { - #ifdef LIME_GLES3_API - glDrawArraysInstanced (mode, first, count, instanceCount); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glDrawArraysInstanced) { + glDrawArraysInstanced (mode, first, count, instanceCount); + } #endif } @@ -1404,17 +1505,19 @@ namespace lime { void lime_gl_draw_buffers (value buffers) { - #ifdef LIME_GLES3_API - GLsizei size = val_array_size (buffers); - GLenum *_buffers = (GLenum*)alloca (size * sizeof(GLenum)); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glDrawBuffers) { + GLsizei size = val_array_size (buffers); + GLenum *_buffers = (GLenum*)alloca (size * sizeof(GLenum)); - for (int i = 0; i < size; i++) { + for (int i = 0; i < size; i++) { - _buffers[i] = val_int (val_array_i (buffers, i)); + _buffers[i] = val_int (val_array_i (buffers, i)); - } + } - glDrawBuffers (size, _buffers); + glDrawBuffers (size, _buffers); + } #endif } @@ -1422,9 +1525,11 @@ namespace lime { HL_PRIM void HL_NAME(hl_gl_draw_buffers) (hl_varray* buffers) { - #ifdef LIME_GLES3_API - GLsizei size = buffers->size; - glDrawBuffers (size, (GLenum*)hl_aptr (buffers, int)); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glDrawBuffers) { + GLsizei size = buffers->size; + glDrawBuffers (size, (GLenum*)hl_aptr (buffers, int)); + } #endif } @@ -1446,8 +1551,10 @@ namespace lime { void lime_gl_draw_elements_instanced (int mode, int count, int type, double offset, int instanceCount) { - #ifdef LIME_GLES3_API - glDrawElementsInstanced (mode, count, type, (void*)(uintptr_t)offset, instanceCount); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glDrawElementsInstanced) { + glDrawElementsInstanced (mode, count, type, (void*)(uintptr_t)offset, instanceCount); + } #endif } @@ -1455,8 +1562,10 @@ namespace lime { HL_PRIM void HL_NAME(hl_gl_draw_elements_instanced) (int mode, int count, int type, double offset, int instanceCount) { - #ifdef LIME_GLES3_API - glDrawElementsInstanced (mode, count, type, (void*)(uintptr_t)offset, instanceCount); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glDrawElementsInstanced) { + glDrawElementsInstanced (mode, count, type, (void*)(uintptr_t)offset, instanceCount); + } #endif } @@ -1464,8 +1573,10 @@ namespace lime { void lime_gl_draw_range_elements (int mode, int start, int end, int count, int type, double offset) { - #ifdef LIME_GLES3_API - glDrawRangeElements (mode, start, end, count, type, (void*)(uintptr_t)offset); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glDrawRangeElements) { + glDrawRangeElements (mode, start, end, count, type, (void*)(uintptr_t)offset); + } #endif } @@ -1473,8 +1584,10 @@ namespace lime { HL_PRIM void HL_NAME(hl_gl_draw_range_elements) (int mode, int start, int end, int count, int type, double offset) { - #ifdef LIME_GLES3_API - glDrawRangeElements (mode, start, end, count, type, (void*)(uintptr_t)offset); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glDrawRangeElements) { + glDrawRangeElements (mode, start, end, count, type, (void*)(uintptr_t)offset); + } #endif } @@ -1562,7 +1675,7 @@ namespace lime { #ifdef LIME_GLES3_API GLsync result = glFenceSync (condition, flags); - HL_CFFIPointer* handle = HLCFFIPointer (result, (hl_finalizer)gc_gl_object); + HL_CFFIPointer* handle = HLCFFIPointer (result, (hl_finalizer)hl_gc_gl_object); glObjectPtrs[handle] = result; return handle; #else @@ -1630,8 +1743,10 @@ namespace lime { void lime_gl_framebuffer_texture_layer (int target, int attachment, int texture, int level, int layer) { - #ifdef LIME_GLES3_API - glFramebufferTextureLayer (target, attachment, texture, level, layer); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glFramebufferTextureLayer) { + glFramebufferTextureLayer (target, attachment, texture, level, layer); + } #endif } @@ -1639,8 +1754,10 @@ namespace lime { HL_PRIM void HL_NAME(hl_gl_framebuffer_texture_layer) (int target, int attachment, int texture, int level, int layer) { - #ifdef LIME_GLES3_API - glFramebufferTextureLayer (target, attachment, texture, level, layer); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glFramebufferTextureLayer) { + glFramebufferTextureLayer (target, attachment, texture, level, layer); + } #endif } @@ -2630,8 +2747,10 @@ namespace lime { float lime_gl_get_sampler_parameterf (int sampler, int pname) { GLfloat param = 0; - #ifdef LIME_GLES3_API - glGetSamplerParameterfv (sampler, pname, ¶m); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glGetSamplerParameterfv) { + glGetSamplerParameterfv (sampler, pname, ¶m); + } #endif return param; @@ -2641,8 +2760,10 @@ namespace lime { HL_PRIM float HL_NAME(hl_gl_get_sampler_parameterf) (int sampler, int pname) { GLfloat param = 0; - #ifdef LIME_GLES3_API - glGetSamplerParameterfv (sampler, pname, ¶m); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glGetSamplerParameterfv) { + glGetSamplerParameterfv (sampler, pname, ¶m); + } #endif return param; @@ -2651,8 +2772,10 @@ namespace lime { void lime_gl_get_sampler_parameterfv (int sampler, int pname, double params) { - #ifdef LIME_GLES3_API - glGetSamplerParameterfv (sampler, pname, (GLfloat*)(uintptr_t)params); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glGetSamplerParameterfv) { + glGetSamplerParameterfv (sampler, pname, (GLfloat*)(uintptr_t)params); + } #endif } @@ -2660,8 +2783,10 @@ namespace lime { HL_PRIM void HL_NAME(hl_gl_get_sampler_parameterfv) (int sampler, int pname, double params) { - #ifdef LIME_GLES3_API - glGetSamplerParameterfv (sampler, pname, (GLfloat*)(uintptr_t)params); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glGetSamplerParameterfv) { + glGetSamplerParameterfv (sampler, pname, (GLfloat*)(uintptr_t)params); + } #endif } @@ -2670,8 +2795,10 @@ namespace lime { int lime_gl_get_sampler_parameteri (int sampler, int pname) { GLint param = 0; - #ifdef LIME_GLES3_API - glGetSamplerParameteriv (sampler, pname, ¶m); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glGetSamplerParameteriv) { + glGetSamplerParameteriv (sampler, pname, ¶m); + } #endif return param; @@ -2681,8 +2808,10 @@ namespace lime { HL_PRIM int HL_NAME(hl_gl_get_sampler_parameteri) (int sampler, int pname) { GLint param = 0; - #ifdef LIME_GLES3_API - glGetSamplerParameteriv (sampler, pname, ¶m); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glGetSamplerParameteriv) { + glGetSamplerParameteriv (sampler, pname, ¶m); + } #endif return param; @@ -2691,8 +2820,10 @@ namespace lime { void lime_gl_get_sampler_parameteriv (int sampler, int pname, double params) { - #ifdef LIME_GLES3_API - glGetSamplerParameteriv (sampler, pname, (GLint*)(uintptr_t)params); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glGetSamplerParameteriv) { + glGetSamplerParameteriv (sampler, pname, (GLint*)(uintptr_t)params); + } #endif } @@ -2700,8 +2831,10 @@ namespace lime { HL_PRIM void HL_NAME(hl_gl_get_sampler_parameteriv) (int sampler, int pname, double params) { - #ifdef LIME_GLES3_API - glGetSamplerParameteriv (sampler, pname, (GLint*)(uintptr_t)params); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glGetSamplerParameteriv) { + glGetSamplerParameteriv (sampler, pname, (GLint*)(uintptr_t)params); + } #endif } @@ -3449,17 +3582,19 @@ namespace lime { void lime_gl_invalidate_framebuffer (int target, value attachments) { - #ifdef LIME_GLES3_API - GLint size = val_array_size (attachments); - GLenum *_attachments = (GLenum*)alloca (size * sizeof(GLenum)); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glInvalidateFramebuffer) { + GLint size = val_array_size (attachments); + GLenum *_attachments = (GLenum*)alloca (size * sizeof(GLenum)); - for (int i = 0; i < size; i++) { + for (int i = 0; i < size; i++) { - _attachments[i] = val_int (val_array_i (attachments, i)); + _attachments[i] = val_int (val_array_i (attachments, i)); - } + } - glInvalidateFramebuffer (target, size, _attachments); + glInvalidateFramebuffer (target, size, _attachments); + } #endif } @@ -3467,9 +3602,11 @@ namespace lime { HL_PRIM void HL_NAME(hl_gl_invalidate_framebuffer) (int target, varray* attachments) { - #ifdef LIME_GLES3_API - GLint size = attachments->size; - glInvalidateFramebuffer (target, size, (GLenum*)hl_aptr (attachments, int)); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glInvalidateFramebuffer) { + GLint size = attachments->size; + glInvalidateFramebuffer (target, size, (GLenum*)hl_aptr (attachments, int)); + } #endif } @@ -3477,17 +3614,19 @@ namespace lime { void lime_gl_invalidate_sub_framebuffer (int target, value attachments, int x, int y, int width, int height) { - #ifdef LIME_GLES3_API - GLint size = val_array_size (attachments); - GLenum *_attachments = (GLenum*)alloca (size * sizeof(GLenum)); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glInvalidateSubFramebuffer) { + GLint size = val_array_size (attachments); + GLenum *_attachments = (GLenum*)alloca (size * sizeof(GLenum)); - for (int i = 0; i < size; i++) { + for (int i = 0; i < size; i++) { - _attachments[i] = val_int (val_array_i (attachments, i)); + _attachments[i] = val_int (val_array_i (attachments, i)); - } + } - glInvalidateSubFramebuffer (target, size, _attachments, x, y, width, height); + glInvalidateSubFramebuffer (target, size, _attachments, x, y, width, height); + } #endif } @@ -3495,9 +3634,11 @@ namespace lime { HL_PRIM void HL_NAME(hl_gl_invalidate_sub_framebuffer) (int target, varray* attachments, int x, int y, int width, int height) { - #ifdef LIME_GLES3_API - GLint size = attachments->size; - glInvalidateSubFramebuffer (target, size, (GLenum*)hl_aptr (attachments, int), x, y, width, height); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glInvalidateSubFramebuffer) { + GLint size = attachments->size; + glInvalidateSubFramebuffer (target, size, (GLenum*)hl_aptr (attachments, int), x, y, width, height); + } #endif } @@ -3597,8 +3738,8 @@ namespace lime { bool lime_gl_is_sampler (int handle) { - #ifdef LIME_GLES3_API - return glIsSampler (handle); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + return glIsSampler ? glIsSampler (handle) : false; #else return false; #endif @@ -3608,8 +3749,8 @@ namespace lime { HL_PRIM bool HL_NAME(hl_gl_is_sampler) (int handle) { - #ifdef LIME_GLES3_API - return glIsSampler (handle); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + return glIsSampler ? glIsSampler (handle) : false; #else return false; #endif @@ -3693,8 +3834,8 @@ namespace lime { bool lime_gl_is_vertex_array (int handle) { - #ifdef LIME_GLES3_API - return glIsQuery (handle); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + return glIsVertexArray ? glIsVertexArray (handle) : false; #else return false; #endif @@ -3704,8 +3845,8 @@ namespace lime { HL_PRIM bool HL_NAME(hl_gl_is_vertex_array) (int handle) { - #ifdef LIME_GLES3_API - return glIsQuery (handle); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + return glIsVertexArray ? glIsVertexArray (handle) : false; #else return false; #endif @@ -3878,7 +4019,7 @@ namespace lime { HL_PRIM HL_CFFIPointer* HL_NAME(hl_gl_object_register) (int id, int type, void* object) { GLObjectType _type = (GLObjectType)type; - HL_CFFIPointer* handle = HLCFFIPointer ((vobj*)object, (hl_finalizer)gc_gl_object); + HL_CFFIPointer* handle = HLCFFIPointer ((vobj*)object, (hl_finalizer)hl_gc_gl_object); //if (glObjects[_type].find (id) != glObjects[_type].end ()) { // @@ -3986,8 +4127,10 @@ namespace lime { void lime_gl_read_buffer (int src) { - #ifdef LIME_GLES3_API - glReadBuffer (src); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glReadBuffer) { + glReadBuffer (src); + } #endif } @@ -3995,8 +4138,10 @@ namespace lime { HL_PRIM void HL_NAME(hl_gl_read_buffer) (int src) { - #ifdef LIME_GLES3_API - glReadBuffer (src); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glReadBuffer) { + glReadBuffer (src); + } #endif } @@ -4050,8 +4195,10 @@ namespace lime { void lime_gl_renderbuffer_storage_multisample (int target, int samples, int internalformat, int width, int height) { - #ifdef LIME_GLES3_API - glRenderbufferStorageMultisample (target, samples, internalformat, width, height); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glRenderbufferStorageMultisample) { + glRenderbufferStorageMultisample (target, samples, internalformat, width, height); + } #endif } @@ -4059,8 +4206,10 @@ namespace lime { HL_PRIM void HL_NAME(hl_gl_renderbuffer_storage_multisample) (int target, int samples, int internalformat, int width, int height) { - #ifdef LIME_GLES3_API - glRenderbufferStorageMultisample (target, samples, internalformat, width, height); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glRenderbufferStorageMultisample) { + glRenderbufferStorageMultisample (target, samples, internalformat, width, height); + } #endif } @@ -4104,8 +4253,10 @@ namespace lime { void lime_gl_sampler_parameterf (int sampler, int pname, float param) { - #ifdef LIME_GLES3_API - glSamplerParameterf (sampler, pname, param); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glSamplerParameterf) { + glSamplerParameterf (sampler, pname, param); + } #endif } @@ -4113,8 +4264,10 @@ namespace lime { HL_PRIM void HL_NAME(hl_gl_sampler_parameterf) (int sampler, int pname, float param) { - #ifdef LIME_GLES3_API - glSamplerParameterf (sampler, pname, param); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glSamplerParameterf) { + glSamplerParameterf (sampler, pname, param); + } #endif } @@ -4122,8 +4275,10 @@ namespace lime { void lime_gl_sampler_parameteri (int sampler, int pname, int param) { - #ifdef LIME_GLES3_API - glSamplerParameteri (sampler, pname, param); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glSamplerParameteri) { + glSamplerParameteri (sampler, pname, param); + } #endif } @@ -4131,8 +4286,10 @@ namespace lime { HL_PRIM void HL_NAME(hl_gl_sampler_parameteri) (int sampler, int pname, int param) { - #ifdef LIME_GLES3_API - glSamplerParameteri (sampler, pname, param); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glSamplerParameteri) { + glSamplerParameteri (sampler, pname, param); + } #endif } @@ -4295,8 +4452,10 @@ namespace lime { void lime_gl_tex_image_3d (int target, int level, int internalformat, int width, int height, int depth, int border, int format, int type, double data) { - #ifdef LIME_GLES3_API - glTexImage3D (target, level, internalformat, width, height, depth, border, format, type, (void*)(uintptr_t)data); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glTexImage3D) { + glTexImage3D (target, level, internalformat, width, height, depth, border, format, type, (void*)(uintptr_t)data); + } #endif } @@ -4304,8 +4463,10 @@ namespace lime { HL_PRIM void HL_NAME(hl_gl_tex_image_3d) (int target, int level, int internalformat, int width, int height, int depth, int border, int format, int type, double data) { - #ifdef LIME_GLES3_API - glTexImage3D (target, level, internalformat, width, height, depth, border, format, type, (void*)(uintptr_t)data); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glTexImage3D) { + glTexImage3D (target, level, internalformat, width, height, depth, border, format, type, (void*)(uintptr_t)data); + } #endif } @@ -4341,8 +4502,10 @@ namespace lime { void lime_gl_tex_storage_2d (int target, int level, int internalformat, int width, int height) { - #ifdef LIME_GLES3_API - glTexStorage2D (target, level, internalformat, width, height); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glTexStorage2D) { + glTexStorage2D (target, level, internalformat, width, height); + } #endif } @@ -4350,8 +4513,10 @@ namespace lime { HL_PRIM void HL_NAME(hl_gl_tex_storage_2d) (int target, int level, int internalformat, int width, int height) { - #ifdef LIME_GLES3_API - glTexStorage2D (target, level, internalformat, width, height); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glTexStorage2D) { + glTexStorage2D (target, level, internalformat, width, height); + } #endif } @@ -4359,8 +4524,10 @@ namespace lime { void lime_gl_tex_storage_3d (int target, int level, int internalformat, int width, int height, int depth) { - #ifdef LIME_GLES3_API - glTexStorage3D (target, level, internalformat, width, height, depth); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glTexStorage3D) { + glTexStorage3D (target, level, internalformat, width, height, depth); + } #endif } @@ -4368,8 +4535,10 @@ namespace lime { HL_PRIM void HL_NAME(hl_gl_tex_storage_3d) (int target, int level, int internalformat, int width, int height, int depth) { - #ifdef LIME_GLES3_API - glTexStorage3D (target, level, internalformat, width, height, depth); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glTexStorage3D) { + glTexStorage3D (target, level, internalformat, width, height, depth); + } #endif } @@ -4391,8 +4560,10 @@ namespace lime { void lime_gl_tex_sub_image_3d (int target, int level, int xoffset, int yoffset, int zoffset, int width, int height, int depth, int format, int type, double data) { - #ifdef LIME_GLES3_API - glTexSubImage3D (target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, (void*)(uintptr_t)data); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glTexSubImage3D) { + glTexSubImage3D (target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, (void*)(uintptr_t)data); + } #endif } @@ -4400,8 +4571,10 @@ namespace lime { HL_PRIM void HL_NAME(hl_gl_tex_sub_image_3d) (int target, int level, int xoffset, int yoffset, int zoffset, int width, int height, int depth, int format, int type, double data) { - #ifdef LIME_GLES3_API - glTexSubImage3D (target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, (void*)(uintptr_t)data); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glTexSubImage3D) { + glTexSubImage3D (target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, (void*)(uintptr_t)data); + } #endif } @@ -5023,8 +5196,10 @@ namespace lime { void lime_gl_vertex_attrib_divisor (int index, int divisor) { - #ifdef LIME_GLES3_API - glVertexAttribDivisor (index, divisor); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glVertexAttribDivisor) { + glVertexAttribDivisor (index, divisor); + } #endif } @@ -5032,8 +5207,10 @@ namespace lime { HL_PRIM void HL_NAME(hl_gl_vertex_attrib_divisor) (int index, int divisor) { - #ifdef LIME_GLES3_API - glVertexAttribDivisor (index, divisor); + #if defined (LIME_GLES3_API) || !defined (LIME_GLES) + if (glVertexAttribDivisor) { + glVertexAttribDivisor (index, divisor); + } #endif } @@ -5901,4 +6078,4 @@ extern "C" int lime_opengl_register_prims () { return 0; -} \ No newline at end of file +} diff --git a/src/lime/_internal/backend/air/AIRApplication.hx b/src/lime/_internal/backend/air/AIRApplication.hx index d0e6b4ebe7..448c829cad 100644 --- a/src/lime/_internal/backend/air/AIRApplication.hx +++ b/src/lime/_internal/backend/air/AIRApplication.hx @@ -36,6 +36,11 @@ class AIRApplication extends FlashApplication override public function getDeviceOrientation():Orientation { + if (parent == null || parent.window == null || parent.window.stage == null) + { + return UNKNOWN; + } + switch (parent.window.stage.deviceOrientation) { case DEFAULT: diff --git a/src/lime/_internal/backend/air/AIRWindow.hx b/src/lime/_internal/backend/air/AIRWindow.hx index 0c5e022fda..6f37173899 100644 --- a/src/lime/_internal/backend/air/AIRWindow.hx +++ b/src/lime/_internal/backend/air/AIRWindow.hx @@ -97,7 +97,10 @@ class AIRWindow extends FlashWindow if (FlashApplication.createFirstWindow) { - nativeWindow = Lib.current.stage.nativeWindow; + if (Lib.current.stage != null) + { + nativeWindow = Lib.current.stage.nativeWindow; + } #if munit hidden = true; @@ -171,7 +174,10 @@ class AIRWindow extends FlashWindow parent.context.attributes.stencil = true; } - parent.stage.addEventListener(StageOrientationEvent.ORIENTATION_CHANGE, handleStageOrientationChangeEvent); + if (parent.stage != null) + { + parent.stage.addEventListener(StageOrientationEvent.ORIENTATION_CHANGE, handleStageOrientationChangeEvent); + } } public override function focus():Void @@ -184,6 +190,11 @@ class AIRWindow extends FlashWindow private function handleStageOrientationChangeEvent(event:StageOrientationEvent):Void { + if (parent == null || parent.stage == null || parent.application == null) + { + return; + } + if (parent.application.window == parent) { var newDeviceOrientation:Orientation = UNKNOWN; diff --git a/src/lime/_internal/backend/flash/FlashApplication.hx b/src/lime/_internal/backend/flash/FlashApplication.hx index 0ecd207273..ef1ea4afc8 100644 --- a/src/lime/_internal/backend/flash/FlashApplication.hx +++ b/src/lime/_internal/backend/flash/FlashApplication.hx @@ -3,6 +3,9 @@ package lime._internal.backend.flash; import flash.ui.MultitouchInputMode; import flash.ui.Multitouch; import lime.app.Application; +import lime.app.FrameOptions; +import lime.app.FrameProfile; +import lime.app.VSyncMode; import lime.media.AudioManager; import lime.system.Orientation; import lime.ui.Window; @@ -20,7 +23,6 @@ class FlashApplication this.parent = parent; AudioManager.init(); - createFirstWindow = true; // Initial window is already created parent.createWindow({}); @@ -30,14 +32,23 @@ class FlashApplication public function exec():Int { Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT; - return 0; } + public function configureFrameTiming(profile:FrameProfile, frameRate:Float, options:FrameOptions):Void + { + if (parent.window != null && parent.window.stage != null) + { + parent.window.stage.frameRate = (frameRate > 0) ? frameRate : 1; + } + } + public function exit():Void {} public function getDeviceOrientation():Orientation { return UNKNOWN; } + + public function setVSyncMode(mode:VSyncMode):Void {} } diff --git a/src/lime/_internal/backend/flash/FlashWindow.hx b/src/lime/_internal/backend/flash/FlashWindow.hx index 1935a11208..2654d08ff8 100644 --- a/src/lime/_internal/backend/flash/FlashWindow.hx +++ b/src/lime/_internal/backend/flash/FlashWindow.hx @@ -225,8 +225,7 @@ class FlashWindow "middleMouseMove", "middleMouseUp" #if ((!openfl && !disable_flash_right_click) - || enable_flash_right_click), "rightMouseDown", "rightMouseMove", "rightMouseUp" - #end + || enable_flash_right_click), "rightMouseDown", "rightMouseMove", "rightMouseUp" #end ]; for (event in events) @@ -274,13 +273,14 @@ class FlashWindow contextAttributes.background = stage.color; } - setFrameRate(Reflect.hasField(attributes, "frameRate") ? attributes.frameRate : 60); + frameRate = parent.application.__resolveFrameRate(attributes); + + if (parent.stage != null) parent.stage.frameRate = frameRate; context.attributes = contextAttributes; parent.context = context; // TODO: Wait for application.exec? - cacheTime = Lib.getTimer(); // handleApplicationEvent (null); @@ -323,7 +323,6 @@ class FlashWindow if (event.type == KeyboardEvent.KEY_DOWN) { parent.onKeyDown.dispatch(keyCode, modifier); - if (parent.textInputEnabled) { parent.onTextInput.dispatch(String.fromCharCode(event.charCode)); @@ -348,26 +347,23 @@ class FlashWindow { case "mouseDown", "middleMouseDown", "rightMouseDown": parent.onMouseDown.dispatch(event.stageX, event.stageY, button); - case "mouseMove": if (mouseLeft) { mouseLeft = false; parent.onEnter.dispatch(); } - var mouseX = event.stageX; - var mouseY = event.stageY; + var mouseY = event.stageY; parent.onMouseMove.dispatch(mouseX, mouseY); - parent.onMouseMoveRelative.dispatch(mouseX - cacheMouseX, mouseY - cacheMouseY); + parent.onMouseMoveRelative.dispatch(mouseX - cacheMouseX, mouseY - cacheMouseY); cacheMouseX = mouseX; - cacheMouseY = mouseY; + cacheMouseY = mouseY; case "mouseUp", "middleMouseUp", "rightMouseUp": parent.onMouseUp.dispatch(event.stageX, event.stageY, button); - case "mouseWheel": parent.onMouseWheel.dispatch(0, event.delta, MouseWheelMode.LINES); @@ -384,7 +380,6 @@ class FlashWindow { case TouchEvent.TOUCH_BEGIN: var touch = unusedTouchesPool.pop(); - if (touch == null) { touch = new Touch(x / parent.__width, y / parent.__height, event.touchPointID, 0, 0, event.pressure, parent.id); @@ -395,20 +390,20 @@ class FlashWindow touch.y = y / parent.__height; touch.id = event.touchPointID; touch.dx = 0; + touch.dy = 0; touch.pressure = event.pressure; + touch.device = parent.id; } currentTouches.set(event.touchPointID, touch); - Touch.onStart.dispatch(touch); if (event.isPrimaryTouchPoint) { parent.onMouseDown.dispatch(x, y, LEFT); } - case TouchEvent.TOUCH_END: var touch = currentTouches.get(event.touchPointID); @@ -416,24 +411,22 @@ class FlashWindow { var cacheX = touch.x; var cacheY = touch.y; - touch.x = x / parent.__width; + touch.y = y / parent.__height; touch.dx = touch.x - cacheX; + touch.dy = touch.y - cacheY; touch.pressure = event.pressure; Touch.onEnd.dispatch(touch); - currentTouches.remove(event.touchPointID); unusedTouchesPool.add(touch); - if (event.isPrimaryTouchPoint) { parent.onMouseUp.dispatch(x, y, 0); } } - case TouchEvent.TOUCH_MOVE: var touch = currentTouches.get(event.touchPointID); @@ -441,15 +434,14 @@ class FlashWindow { var cacheX = touch.x; var cacheY = touch.y; - touch.x = x / parent.__width; + touch.y = y / parent.__height; touch.dx = touch.x - cacheX; + touch.dy = touch.y - cacheY; touch.pressure = event.pressure; - Touch.onMove.dispatch(touch); - if (event.isPrimaryTouchPoint) { parent.onMouseMove.dispatch(x, y); @@ -464,13 +456,10 @@ class FlashWindow { case Event.ACTIVATE: parent.onActivate.dispatch(); - case Event.DEACTIVATE: parent.onDeactivate.dispatch(); - case FocusEvent.FOCUS_IN: parent.onFocusIn.dispatch(); - case FocusEvent.FOCUS_OUT: parent.onFocusOut.dispatch(); @@ -481,7 +470,6 @@ class FlashWindow case Event.RESIZE: parent.__width = parent.stage.stageWidth; parent.__height = parent.stage.stageHeight; - parent.onResize.dispatch(parent.__width, parent.__height); default: @@ -491,7 +479,6 @@ class FlashWindow public function readPixels(rect:Rectangle):Image { var stageRect = new Rectangle(0, 0, parent.stage.stageWidth, parent.stage.stageHeight); - if (rect == null) { rect = stageRect; @@ -506,11 +493,10 @@ class FlashWindow var bitmapData = new BitmapData(Std.int(rect.width), Std.int(rect.height)); var matrix = new Matrix(); + matrix.tx = -rect.x; matrix.ty = -rect.y; - bitmapData.draw(parent.stage, matrix); - return Image.fromBitmapData(bitmapData); } else @@ -533,7 +519,6 @@ class FlashWindow { Mouse.show(); } - Mouse.cursor = switch (value) { case ARROW: FlashMouseCursor.ARROW; @@ -546,14 +531,13 @@ class FlashWindow case RESIZE_WE: FlashMouseCursor.HAND; case TEXT: FlashMouseCursor.IBEAM; case WAIT: FlashMouseCursor.ARROW; + case WAIT_ARROW: FlashMouseCursor.ARROW; default: FlashMouseCursor.AUTO; } } - cursor = value; } - return cursor; } @@ -564,7 +548,7 @@ class FlashWindow public function getFrameRate():Float { - return frameRate; + return (parent.application != null) ? parent.application.__getFrameRate() : frameRate; } public function getMouseLock():Bool @@ -597,9 +581,8 @@ class FlashWindow public function setFrameRate(value:Float):Float { - frameRate = value; - if (parent.stage != null) parent.stage.frameRate = value; - return value; + frameRate = (parent.application != null) ? parent.application.__setFrameRateFromWindow(value) : value; + return frameRate; } public function setFullscreen(value:Bool):Bool diff --git a/src/lime/_internal/backend/html5/HTML5Application.hx b/src/lime/_internal/backend/html5/HTML5Application.hx index 6800c87cad..278ae6c6d9 100644 --- a/src/lime/_internal/backend/html5/HTML5Application.hx +++ b/src/lime/_internal/backend/html5/HTML5Application.hx @@ -4,6 +4,9 @@ import js.html.DeviceMotionEvent; import js.html.KeyboardEvent; import js.Browser; import lime.app.Application; +import lime.app.FrameOptions; +import lime.app.FrameProfile; +import lime.app.VSyncMode; import lime.media.AudioManager; import lime.system.Orientation; import lime.system.Sensor; @@ -40,14 +43,14 @@ class HTML5Application public inline function new(parent:Application) { this.parent = parent; - currentUpdate = 0; lastUpdate = 0; + nextUpdate = 0; framePeriod = -1; - AudioManager.init(); accelerometer = Sensor.registerSensor(SensorType.ACCELEROMETER, 0); + updateFramePeriod(); } private function convertKeyCode(keyCode:Int):KeyCode @@ -56,7 +59,6 @@ class HTML5Application { return keyCode + 32; } - switch (keyCode) { case 12: @@ -255,6 +257,7 @@ class HTML5Application return KeyCode.LEFT_BRACKET; case 220: return KeyCode.BACKSLASH; + case 221: return KeyCode.RIGHT_BRACKET; case 222: @@ -266,7 +269,6 @@ class HTML5Application case 226: return KeyCode.BACKSLASH; } - return keyCode; } @@ -276,21 +278,20 @@ class HTML5Application Browser.window.addEventListener("keyup", handleKeyEvent, false); Browser.window.addEventListener("focus", handleWindowEvent, false); Browser.window.addEventListener("blur", handleWindowEvent, false); + Browser.window.addEventListener("resize", handleWindowEvent, false); Browser.window.addEventListener("beforeunload", handleWindowEvent, false); - if (Reflect.hasField(Browser.window, "Accelerometer")) { Browser.window.addEventListener("devicemotion", handleSensorEvent, false); } - #if stats stats = untyped #if haxe4 js.Syntax.code #else __js__ #end ("new Stats ()"); stats.domElement.style.position = "absolute"; stats.domElement.style.top = "0px"; + Browser.document.body.appendChild(stats.domElement); #end - untyped #if haxe4 js.Syntax.code #else __js__ #end (" if (!CanvasRenderingContext2D.prototype.isPointInStroke) { CanvasRenderingContext2D.prototype.isPointInStroke = function (path, x, y) { @@ -341,11 +342,8 @@ class HTML5Application window.requestAnimFrame = window.requestAnimationFrame; "); - lastUpdate = Browser.window.performance.now(); - handleApplicationEvent(); - return 0; } @@ -372,27 +370,32 @@ class HTML5Application return UNKNOWN; } + public function configureFrameTiming(profile:FrameProfile, frameRate:Float, options:FrameOptions):Void + { + updateFramePeriod(); + } + + public function setVSyncMode(mode:VSyncMode):Void + { + updateFramePeriod(); + } + private function handleApplicationEvent(?__):Void { // TODO: Support independent window frame rates - for (window in parent.__windows) { window.__backend.updateSize(); } - updateGameDevices(); currentUpdate = Browser.window.performance.now(); - if (currentUpdate >= nextUpdate) { #if stats stats.begin(); #end - deltaTime = currentUpdate - lastUpdate; - for (window in parent.__windows) { parent.onUpdate.dispatch(Std.int(deltaTime)); @@ -411,10 +414,8 @@ class HTML5Application { nextUpdate = currentUpdate - (currentUpdate % framePeriod) + framePeriod; } - lastUpdate = currentUpdate; } - Browser.window.requestAnimationFrame(cast handleApplicationEvent); } @@ -423,22 +424,16 @@ class HTML5Application if (parent.window != null) { // space and arrow keys - // switch (event.keyCode) { - // case 32, 37, 38, 39, 40: event.preventDefault (); // } - // TODO: Use event.key instead where supported - var keyCode = cast convertKeyCode(event.keyCode != null ? event.keyCode : event.which); var modifier = (event.shiftKey ? (KeyModifier.SHIFT) : 0) | (event.ctrlKey ? (KeyModifier.CTRL) : 0) | (event.altKey ? (KeyModifier.ALT) : 0) | (event.metaKey ? (KeyModifier.META) : 0); - if (event.type == "keydown") { parent.window.onKeyDown.dispatch(keyCode, modifier); - if (parent.window.onKeyDown.canceled && event.cancelable) { event.preventDefault(); @@ -447,7 +442,6 @@ class HTML5Application else { parent.window.onKeyUp.dispatch(keyCode, modifier); - if (parent.window.onKeyUp.canceled && event.cancelable) { event.preventDefault(); @@ -461,6 +455,33 @@ class HTML5Application accelerometer.onUpdate.dispatch(event.accelerationIncludingGravity.x, event.accelerationIncludingGravity.y, event.accelerationIncludingGravity.z); } + private function updateFramePeriod():Void + { + var requestedFrameRate = parent.__frameRate; + var shouldUseDisplayDriven = false; + switch (parent.__vsyncMode) + { + case On, Adaptive, Auto: + shouldUseDisplayDriven = (requestedFrameRate > 0 && requestedFrameRate >= 60); + + default: + shouldUseDisplayDriven = (requestedFrameRate >= 60); + } + + if (shouldUseDisplayDriven) + { + framePeriod = -1; + } + else if (requestedFrameRate > 0) + { + framePeriod = 1000 / requestedFrameRate; + } + else + { + framePeriod = 1000; + } + } + private function handleWindowEvent(event:js.html.Event):Void { if (parent.window != null) @@ -490,6 +511,7 @@ class HTML5Application { parent.window.onFocusOut.dispatch(); parent.window.onDeactivate.dispatch(); + hidden = true; } } @@ -502,7 +524,6 @@ class HTML5Application hidden = false; } } - case "resize": parent.window.__backend.handleResizeEvent(event); @@ -511,12 +532,11 @@ class HTML5Application // but returns later without reloading the page. This triggers // a window.onClose(), without us creating the window again. // + // For now, let focus in/out and activate/deactivate trigger // on blur and focus, and do not dispatch a closed window event // since it may actually never close. - // if (!event.defaultPrevented) { - // parent.window.onClose.dispatch (); // if (parent.window != null && parent.window.onClose.canceled && event.cancelable) { @@ -524,7 +544,6 @@ class HTML5Application // event.preventDefault (); // } - // } } } @@ -534,22 +553,17 @@ class HTML5Application { var devices = Joystick.__getDeviceData(); if (devices == null) return; - var id, gamepad, joystick, data:Dynamic, cache; - for (i in 0...devices.length) { id = i; data = devices[id]; - if (data == null) continue; - if (!gameDeviceCache.exists(id)) { cache = new GameDeviceData(); cache.id = id; cache.connected = data.connected; - for (i in 0...data.buttons.length) { cache.buttons.push(data.buttons[i].value); @@ -559,18 +573,14 @@ class HTML5Application { cache.axes.push(data.axes[i]); } - if (data.mapping == "standard") { cache.isGamepad = true; } - gameDeviceCache.set(id, cache); - if (data.connected) { Joystick.__connect(id); - if (cache.isGamepad) { Gamepad.__connect(id); @@ -579,10 +589,8 @@ class HTML5Application } cache = gameDeviceCache.get(id); - joystick = Joystick.devices.get(id); gamepad = Gamepad.devices.get(id); - if (data.connected) { var button:GamepadButton; @@ -614,13 +622,13 @@ class HTML5Application { joystick.onButtonUp.dispatch(i); } - if (gamepad != null) { button = switch (i) { case 0: GamepadButton.A; case 1: GamepadButton.B; + case 2: GamepadButton.X; case 3: GamepadButton.Y; case 4: GamepadButton.LEFT_SHOULDER; @@ -629,6 +637,7 @@ class HTML5Application case 9: GamepadButton.START; case 10: GamepadButton.LEFT_STICK; case 11: GamepadButton.RIGHT_STICK; + case 12: GamepadButton.DPAD_UP; case 13: GamepadButton.DPAD_DOWN; case 14: GamepadButton.DPAD_LEFT; @@ -636,7 +645,6 @@ class HTML5Application case 16: GamepadButton.GUIDE; default: continue; } - if (value > 0) { gamepad.onButtonDown.dispatch(button); @@ -647,11 +655,9 @@ class HTML5Application } } } - cache.buttons[i] = value; } } - for (i in 0...data.axes.length) { if (data.axes[i] != cache.axes[i]) @@ -665,7 +671,6 @@ class HTML5Application else if (cache.connected) { cache.connected = false; - Joystick.__disconnect(id); Gamepad.__disconnect(id); } diff --git a/src/lime/_internal/backend/html5/HTML5Window.hx b/src/lime/_internal/backend/html5/HTML5Window.hx index 8e7b662b08..1f9546877a 100644 --- a/src/lime/_internal/backend/html5/HTML5Window.hx +++ b/src/lime/_internal/backend/html5/HTML5Window.hx @@ -415,20 +415,7 @@ class HTML5Window public function getFrameRate():Float { - if (parent.application == null) return 0; - - if (parent.application.__backend.framePeriod < 0) - { - return 60; - } - else if (parent.application.__backend.framePeriod == 1000) - { - return 0; - } - else - { - return 1000 / parent.application.__backend.framePeriod; - } + return (parent.application != null) ? parent.application.__getFrameRate() : 0; } public function getMouseLock():Bool @@ -452,7 +439,6 @@ class HTML5Window { case "webglcontextlost": if (event.cancelable) event.preventDefault(); - // #if !display if (GL.context != null) { @@ -466,7 +452,6 @@ class HTML5Window case "webglcontextrestored": createContext(); - parent.onRenderContextRestored.dispatch(parent.context); default: @@ -506,17 +491,16 @@ class HTML5Window case "dragover": event.preventDefault(); return false; - case "drop": // TODO: Create a formal API that supports HTML5 file objects if (event.dataTransfer != null && event.dataTransfer.files.length > 0) { parent.onDropFile.dispatch(cast event.dataTransfer.files); + event.preventDefault(); return false; } } - return true; } @@ -540,7 +524,6 @@ class HTML5Window { isFullscreen = true; parent.__fullscreen = true; - if (requestedFullscreen) { requestedFullscreen = false; @@ -555,7 +538,6 @@ class HTML5Window // TODO: Handle a different way? parent.onRestore.dispatch(); // parent.onResize.dispatch (parent.__width, parent.__height); - var changeEvents = [ "fullscreenchange", "mozfullscreenchange", @@ -564,14 +546,15 @@ class HTML5Window ]; var errorEvents = [ "fullscreenerror", + "mozfullscreenerror", "webkitfullscreenerror", "MSFullscreenError" ]; - for (i in 0...changeEvents.length) { Browser.document.removeEventListener(changeEvents[i], handleFullscreenEvent, false); + Browser.document.removeEventListener(errorEvents[i], handleFullscreenEvent, false); } } @@ -603,8 +586,8 @@ class HTML5Window { return; } - // In order to ensure that the browser will fire clipboard events, we always need to have something selected. + // Therefore, `value` cannot be "". if (textInput.value != dummyCharacter) { @@ -623,7 +606,6 @@ class HTML5Window { var x = 0.0; var y = 0.0; - if (event.type != "wheel") { if (parent.element != null) @@ -654,7 +636,6 @@ class HTML5Window x = event.clientX; y = event.clientY; } - switch (event.type) { case "mousedown": @@ -671,6 +652,7 @@ class HTML5Window // dispatched. // Flash embedded in HTML worked similarly. Browser.window.addEventListener("mouseup", handleMouseEvent); + Browser.window.addEventListener("mousemove", handleMouseEvent); } // just to be safe, clear the flag on every mouse down @@ -689,7 +671,6 @@ class HTML5Window if (event.target == parent.element) { parent.onEnter.dispatch(); - if (parent.onEnter.canceled && event.cancelable) { event.preventDefault(); @@ -700,13 +681,11 @@ class HTML5Window if (event.target == parent.element) { parent.onLeave.dispatch(); - if (parent.onLeave.canceled && event.cancelable) { event.preventDefault(); } } - case "mouseup": // see comment below for mousemove for an explanation of // what the __stopMousePropagation flag is used for. @@ -718,7 +697,6 @@ class HTML5Window Browser.window.removeEventListener("mouseup", handleMouseEvent); Browser.window.removeEventListener("mousemove", handleMouseEvent); - __stopMousePropagation = event.currentTarget == parent.element; parent.clickCount = event.detail; @@ -729,24 +707,24 @@ class HTML5Window { event.preventDefault(); } - case "mousemove": // this same listener is added to the parent element and to + // the browser window for both the mousemove and the mouseup // event types, if mousedown happens first. this allows both // onMouseMove and onMouseUp to be dispatched if the mouse // moves outside the bounds of the parent element. - // since browser mouse events bubble, this listener will be // called for the parent element first, as long as the mouse // is still over the parent element. in that case, when the // listener is called for the browser window, it should + // return early so that onMouseMove or onMouseUp isn't // dispatched twice. this is done by checking the // __stopMousePropagation flag when the current target isn't // the parent element. - // however, if the mouse isn't over the parent element, the + // listener will be called only for the browser window, and // not the parent element. in that case, it can proceed to // dispatch either onMouseMove or onMouseUp, since this @@ -756,7 +734,6 @@ class HTML5Window // the mouse button isn't down, then the listener won't be // added to the browser window, and event won't be // dispatched outside the bounds of the parent element. - if (__stopMousePropagation && event.currentTarget != parent.element) { // why not call event.stopPropagation() here? well, @@ -765,6 +742,7 @@ class HTML5Window // parent element and on the browser window is just an // implementation detail and shouldn't affect other // listeners. + __stopMousePropagation = false; return; } @@ -774,16 +752,13 @@ class HTML5Window { parent.onMouseMove.dispatch(x, y); parent.onMouseMoveRelative.dispatch(x - cacheMouseX, y - cacheMouseY); - if ((parent.onMouseMove.canceled || parent.onMouseMoveRelative.canceled) && event.cancelable) { event.preventDefault(); } } - default: } - cacheMouseX = x; cacheMouseY = y; } @@ -792,13 +767,13 @@ class HTML5Window var deltaMode:MouseWheelMode = switch (untyped event.deltaMode) { case 0: PIXELS; + case 1: LINES; case 2: PAGES; + default: UNKNOWN; } - parent.onMouseWheel.dispatch(untyped event.deltaX, -untyped event.deltaY, deltaMode); - if (parent.onMouseWheel.canceled && event.cancelable) { event.preventDefault(); @@ -831,9 +806,7 @@ class HTML5Window private function handleTouchEvent(event:TouchEvent):Void { if (event.cancelable) event.preventDefault(); - var rect = null; - if (parent.element != null) { if (canvas != null) @@ -849,10 +822,8 @@ class HTML5Window rect = parent.element.getBoundingClientRect(); } } - var windowWidth:Float = setWidth; var windowHeight:Float = setHeight; - if (windowWidth == 0 || windowHeight == 0) { if (rect != null) @@ -866,8 +837,8 @@ class HTML5Window windowHeight = 1; } } - var touch:Touch; + var x:Float; var y:Float; var cacheX:Float; @@ -877,7 +848,6 @@ class HTML5Window { x = 0.0; y = 0.0; - if (rect != null) { x = (data.clientX - rect.left) * (windowWidth / rect.width); @@ -892,7 +862,6 @@ class HTML5Window if (event.type == "touchstart") { touch = unusedTouchesPool.pop(); - if (touch == null) { touch = new Touch(x / windowWidth, y / windowHeight, data.identifier, 0, 0, data.force, parent.id); @@ -903,20 +872,20 @@ class HTML5Window touch.y = y / windowHeight; touch.id = data.identifier; touch.dx = 0; + touch.dy = 0; touch.pressure = data.force; + touch.device = parent.id; } currentTouches.set(data.identifier, touch); - Touch.onStart.dispatch(touch); if (primaryTouch == null) { primaryTouch = touch; } - if (touch == primaryTouch) { parent.onMouseDown.dispatch(x, y, 0); @@ -930,8 +899,8 @@ class HTML5Window { cacheX = touch.x; cacheY = touch.y; - touch.x = x / windowWidth; + touch.y = y / windowHeight; touch.dx = touch.x - cacheX; touch.dy = touch.y - cacheY; @@ -946,31 +915,24 @@ class HTML5Window { parent.onMouseMove.dispatch(x, y); } - case "touchend": Touch.onEnd.dispatch(touch); - currentTouches.remove(data.identifier); unusedTouchesPool.add(touch); - if (touch == primaryTouch) { parent.onMouseUp.dispatch(x, y, 0); primaryTouch = null; } - case "touchcancel": Touch.onCancel.dispatch(touch); - currentTouches.remove(data.identifier); unusedTouchesPool.add(touch); - if (touch == primaryTouch) { // parent.onMouseUp.dispatch (x, y, 0); primaryTouch = null; } - default: } } @@ -981,14 +943,12 @@ class HTML5Window private function isDescendent(node:Node):Bool { if (node == parent.element) return true; - while (node != null) { if (node.parentNode == parent.element) { return true; } - node = node.parentNode; } @@ -1004,7 +964,6 @@ class HTML5Window if (canvas != null) { var stageRect = new Rectangle(0, 0, canvas.width, canvas.height); - if (rect == null) { rect = stageRect; @@ -1013,13 +972,12 @@ class HTML5Window { rect.intersection(stageRect, rect); } - if (rect.width > 0 && rect.height > 0) { var canvas2:CanvasElement = cast Browser.document.createElement("canvas"); canvas2.width = Std.int(rect.width); - canvas2.height = Std.int(rect.height); + canvas2.height = Std.int(rect.height); var context = canvas2.getContext("2d"); context.drawImage(canvas, -rect.x, -rect.y); @@ -1057,7 +1015,6 @@ class HTML5Window textArea.value = value; textArea.focus(); textArea.select(); - if (Browser.document.queryCommandEnabled("copy")) { Browser.document.execCommand("copy"); @@ -1090,14 +1047,13 @@ class HTML5Window case RESIZE_WE: "ew-resize"; case TEXT: "text"; case WAIT: "wait"; + case WAIT_ARROW: "wait"; default: "auto"; } } - cursor = value; } - return cursor; } @@ -1108,23 +1064,7 @@ class HTML5Window public function setFrameRate(value:Float):Float { - if (parent.application != null) - { - if (value >= 60) - { - if (parent == parent.application.window) parent.application.__backend.framePeriod = -1; - } - else if (value > 0) - { - if (parent == parent.application.window) parent.application.__backend.framePeriod = 1000 / value; - } - else - { - if (parent == parent.application.window) parent.application.__backend.framePeriod = 1000; - } - } - - return value; + return (parent.application != null) ? parent.application.__setFrameRateFromWindow(value) : value; } public function setFullscreen(value:Bool):Bool @@ -1134,7 +1074,6 @@ class HTML5Window if (!requestedFullscreen && !isFullscreen) { requestedFullscreen = true; - untyped { if (parent.element.requestFullscreen) @@ -1159,6 +1098,7 @@ class HTML5Window { document.addEventListener("MSFullscreenChange", handleFullscreenEvent, false); document.addEventListener("MSFullscreenError", handleFullscreenEvent, false); + parent.element.msRequestFullscreen(); } } @@ -1188,20 +1128,19 @@ class HTML5Window // image = image.clone (); // if (image.width != iconWidth || image.height != iconHeight) { + // // image.resize (iconWidth, iconHeight); // // } ImageCanvasUtil.convertToCanvas(image); - var link:LinkElement = cast Browser.document.querySelector("link[rel*='icon']"); if (link == null) { link = cast Browser.document.createElement("link"); } - link.type = "image/x-icon"; link.rel = "shortcut icon"; link.href = image.buffer.src.toDataURL("image/x-icon"); @@ -1241,23 +1180,23 @@ class HTML5Window // use password instead of text to avoid IME issues on Android textInput.type = Browser.navigator.userAgent.indexOf("Android") >= 0 ? 'password' : 'text'; #end + textInput.style.position = 'absolute'; textInput.style.opacity = "0"; + textInput.style.color = "transparent"; textInput.value = dummyCharacter; // See: handleInputEvent() untyped textInput.autocapitalize = "off"; untyped textInput.autocorrect = "off"; textInput.autocomplete = "off"; - // TODO: Position for mobile browsers better - textInput.style.left = "0px"; textInput.style.top = "50%"; - if (~/(iPad|iPhone|iPod).*OS 8_/gi.match(Browser.window.navigator.userAgent)) { textInput.style.fontSize = "0px"; + textInput.style.width = '0px'; textInput.style.height = '0px'; } @@ -1270,12 +1209,10 @@ class HTML5Window untyped (textInput.style).pointerEvents = 'none'; textInput.style.zIndex = "-10000000"; } - if (textInput.parentNode == null) { parent.element.appendChild(textInput); } - if (!textInputEnabled) { textInput.addEventListener('input', handleInputEvent, true); @@ -1286,7 +1223,6 @@ class HTML5Window textInput.addEventListener('compositionstart', handleCompositionstartEvent, true); textInput.addEventListener('compositionend', handleCompositionendEvent, true); } - textInput.focus(); textInput.select(); } @@ -1297,11 +1233,12 @@ class HTML5Window // call blur() before removing the compositionend listener // to ensure that incomplete IME input is committed textInput.blur(); - textInput.removeEventListener('input', handleInputEvent, true); + textInput.removeEventListener('blur', handleFocusEvent, true); textInput.removeEventListener('cut', handleCutOrCopyEvent, true); textInput.removeEventListener('copy', handleCutOrCopyEvent, true); + textInput.removeEventListener('paste', handlePasteEvent, true); textInput.removeEventListener('compositionstart', handleCompositionstartEvent, true); textInput.removeEventListener('compositionend', handleCompositionendEvent, true); @@ -1352,10 +1289,8 @@ class HTML5Window private function updateSize():Void { if (!parent.__resizable) return; - var elementWidth:Float; var elementHeight:Float; - if (parent.element != null) { elementWidth = parent.element.clientWidth; @@ -1366,12 +1301,10 @@ class HTML5Window elementWidth = Browser.window.innerWidth; elementHeight = Browser.window.innerHeight; } - if (elementWidth != cacheElementWidth || elementHeight != cacheElementHeight) { cacheElementWidth = elementWidth; cacheElementHeight = elementHeight; - var stretch = resizeElement || (setWidth == 0 && setHeight == 0); if (parent.element != null && (div == null || (div != null && stretch))) @@ -1381,16 +1314,16 @@ class HTML5Window if (parent.__width != elementWidth || parent.__height != elementHeight) { parent.__width = Std.int(elementWidth); - parent.__height = Std.int(elementHeight); + parent.__height = Std.int(elementHeight); if (canvas != null) { if (parent.element != cast canvas) { canvas.width = Math.round(elementWidth * scale); canvas.height = Math.round(elementHeight * scale); - canvas.style.width = elementWidth + "px"; + canvas.style.height = elementHeight + "px"; } } @@ -1407,12 +1340,10 @@ class HTML5Window { var scaleX = (setWidth != 0) ? (elementWidth / setWidth) : 1; var scaleY = (setHeight != 0) ? (elementHeight / setHeight) : 1; - var targetWidth = elementWidth; var targetHeight = elementHeight; var marginLeft = 0; var marginTop = 0; - if (scaleX < scaleY) { targetHeight = Math.floor(setHeight * scaleX); @@ -1423,7 +1354,6 @@ class HTML5Window targetWidth = Math.floor(setWidth * scaleY); marginLeft = Math.floor((elementWidth - targetWidth) / 2); } - if (canvas != null) { if (parent.element != cast canvas) @@ -1437,6 +1367,7 @@ class HTML5Window else { div.style.width = targetWidth + "px"; + div.style.height = targetHeight + "px"; div.style.marginLeft = marginLeft + "px"; div.style.marginTop = marginTop + "px"; diff --git a/src/lime/_internal/backend/native/NativeApplication.hx b/src/lime/_internal/backend/native/NativeApplication.hx index 7998723bd0..1be8e8df77 100644 --- a/src/lime/_internal/backend/native/NativeApplication.hx +++ b/src/lime/_internal/backend/native/NativeApplication.hx @@ -3,6 +3,12 @@ package lime._internal.backend.native; import haxe.Timer; import lime._internal.backend.native.NativeCFFI; import lime.app.Application; +import lime.app.BusyWaitMode; +import lime.app.FrameOptions; +import lime.app.FrameProfile; +import lime.app.TimePrecision; +import lime.app.UncapMode; +import lime.app.VSyncMode; import lime.graphics.opengl.GL; import lime.graphics.OpenGLRenderContext; import lime.graphics.RenderContext; @@ -65,7 +71,6 @@ class NativeApplication #if android private var deviceOrientationListener:OrientationChangeListener; #end - private var pauseTimer:Int; private var parent:Application; private var toggleFullscreen:Bool; @@ -82,20 +87,17 @@ class NativeApplication this.parent = parent; pauseTimer = -1; toggleFullscreen = true; - AudioManager.init(); #if (ios || android || tvos) Sensor.registerSensor(SensorType.ACCELEROMETER, 0); #end - #if android var setDeviceOrientationListener = JNI.createStaticMethod("org/haxe/lime/GameActivity", "setDeviceOrientationListener", "(Lorg/haxe/lime/HaxeObject;)V"); deviceOrientationListener = new OrientationChangeListener(handleJNIOrientationEvent); setDeviceOrientationListener(deviceOrientationListener); #end - #if (!macro && lime_cffi) handle = NativeCFFI.lime_application_create(); #end @@ -128,9 +130,11 @@ class NativeApplication NativeCFFI.lime_key_event_manager_register(handleKeyEvent, keyEventInfo); NativeCFFI.lime_mouse_event_manager_register(handleMouseEvent, mouseEventInfo); NativeCFFI.lime_render_event_manager_register(handleRenderEvent, renderEventInfo); + NativeCFFI.lime_text_event_manager_register(handleTextEvent, textEventInfo); NativeCFFI.lime_touch_event_manager_register(handleTouchEvent, touchEventInfo); NativeCFFI.lime_window_event_manager_register(handleWindowEvent, windowEventInfo); + #if (ios || android) NativeCFFI.lime_orientation_event_manager_register(handleOrientationEvent, orientationEventInfo); #end @@ -138,10 +142,8 @@ class NativeApplication NativeCFFI.lime_sensor_event_manager_register(handleSensorEvent, sensorEventInfo); #end #end - #if (nodejs && lime_cffi) NativeCFFI.lime_application_init(handle); - var eventLoop = function() { var active = NativeCFFI.lime_application_update(handle); @@ -156,7 +158,6 @@ class NativeApplication untyped setImmediate(eventLoop); } } - untyped setImmediate(eventLoop); return 0; #elseif lime_cffi @@ -169,14 +170,12 @@ class NativeApplication return result; #end #end - return 0; } public function exit():Void { AudioManager.shutdown(); - #if (!macro && lime_cffi) NativeCFFI.lime_application_quit(handle); #end @@ -191,6 +190,21 @@ class NativeApplication #end } + public function configureFrameTiming(profile:FrameProfile, frameRate:Float, options:FrameOptions):Void + { + #if (!macro && lime_cffi) + NativeCFFI.lime_application_set_main_loop(handle, __convertFrameProfile(profile), frameRate, __convertTimePrecision(options.timePrecision), + __convertBusyWaitMode(options.busyWait), __convertUncapMode(options.uncapMode)); + #end + } + + public function setVSyncMode(mode:VSyncMode):Void + { + #if (!macro && lime_cffi) + NativeCFFI.lime_application_set_vsync_mode(handle, __convertVSyncMode(mode)); + #end + } + private function handleApplicationEvent():Void { switch (applicationEventInfo.type) @@ -199,7 +213,6 @@ class NativeApplication updateTimer(); parent.onUpdate.dispatch(applicationEventInfo.deltaTime); - default: } } @@ -209,6 +222,61 @@ class NativeApplication Clipboard.__update(); } + private inline function __convertBusyWaitMode(value:BusyWaitMode):Int + { + return switch (value) + { + case Off: 1; + case On: 2; + + default: 0; + }; + } + + private inline function __convertFrameProfile(value:FrameProfile):Int + { + return switch (value) + { + case Precision: 1; + case LowEnergy: 2; + case Uncapped: 3; + + default: 0; + }; + } + + private inline function __convertTimePrecision(value:TimePrecision):Int + { + return switch (value) + { + case Millisecond: 1; + + case HighResolution: 2; + default: 0; + }; + } + + private inline function __convertUncapMode(value:UncapMode):Int + { + return switch (value) + { + case Soft: 1; + case Hard: 2; + default: 0; + }; + } + + private inline function __convertVSyncMode(value:VSyncMode):Int + { + return switch (value) + { + case On: 1; + case Adaptive: 2; + case Auto: 3; + default: 0; + }; + } + private function handleDropEvent():Void { for (window in parent.windows) @@ -220,19 +288,17 @@ class NativeApplication private function handleGamepadEvent():Void { switch (gamepadEventInfo.type) + { case AXIS_MOVE: var gamepad = Gamepad.devices.get(gamepadEventInfo.id); if (gamepad != null) gamepad.onAxisMove.dispatch(gamepadEventInfo.axis, gamepadEventInfo.axisValue); - case BUTTON_DOWN: var gamepad = Gamepad.devices.get(gamepadEventInfo.id); if (gamepad != null) gamepad.onButtonDown.dispatch(gamepadEventInfo.button); - case BUTTON_UP: var gamepad = Gamepad.devices.get(gamepadEventInfo.id); if (gamepad != null) gamepad.onButtonUp.dispatch(gamepadEventInfo.button); - case CONNECT: Gamepad.__connect(gamepadEventInfo.id); @@ -248,7 +314,6 @@ class NativeApplication case AXIS_MOVE: var joystick = Joystick.devices.get(joystickEventInfo.id); if (joystick != null) joystick.onAxisMove.dispatch(joystickEventInfo.index, joystickEventInfo.x); - case HAT_MOVE: var joystick = Joystick.devices.get(joystickEventInfo.id); if (joystick != null) joystick.onHatMove.dispatch(joystickEventInfo.index, joystickEventInfo.eventValue); @@ -256,14 +321,11 @@ class NativeApplication case BUTTON_DOWN: var joystick = Joystick.devices.get(joystickEventInfo.id); if (joystick != null) joystick.onButtonDown.dispatch(joystickEventInfo.index); - case BUTTON_UP: var joystick = Joystick.devices.get(joystickEventInfo.id); if (joystick != null) joystick.onButtonUp.dispatch(joystickEventInfo.index); - case CONNECT: Joystick.__connect(joystickEventInfo.id); - case DISCONNECT: Joystick.__disconnect(joystickEventInfo.id); } @@ -272,10 +334,10 @@ class NativeApplication private function handleKeyEvent():Void { var window = parent.__windowByID.get(keyEventInfo.windowID); - if (window != null) { var type:KeyEventType = keyEventInfo.type; + var int32:Float = keyEventInfo.keyCode; var keyCode:KeyCode = Std.int(int32); var modifier:KeyModifier = keyEventInfo.modifier; @@ -284,7 +346,6 @@ class NativeApplication { case KEY_DOWN: window.onKeyDown.dispatch(keyCode, modifier); - case KEY_UP: window.onKeyUp.dispatch(keyCode, modifier); } @@ -297,7 +358,6 @@ class NativeApplication if (toggleFullscreen && modifier.altKey && (!modifier.ctrlKey && !modifier.shiftKey && !modifier.metaKey)) { toggleFullscreen = false; - if (!window.onKeyDown.canceled) { window.fullscreen = !window.fullscreen; @@ -324,7 +384,6 @@ class NativeApplication if (toggleFullscreen && (modifier.ctrlKey && modifier.metaKey) && (!modifier.altKey && !modifier.shiftKey)) { toggleFullscreen = false; - if (!window.onKeyDown.canceled) { window.fullscreen = !window.fullscreen; @@ -341,7 +400,6 @@ class NativeApplication { var mainActivity = JNI.createStaticField("org/haxe/extension/Extension", "mainActivity", "Landroid/app/Activity;"); var moveTaskToBack = JNI.createMemberMethod("android/app/Activity", "moveTaskToBack", "(Z)Z"); - moveTaskToBack(mainActivity.get(), true); } #end @@ -358,21 +416,20 @@ class NativeApplication { case MOUSE_DOWN: window.clickCount = mouseEventInfo.clickCount; + window.onMouseDown.dispatch(mouseEventInfo.x, mouseEventInfo.y, mouseEventInfo.button); window.clickCount = 0; - case MOUSE_UP: window.clickCount = mouseEventInfo.clickCount; window.onMouseUp.dispatch(mouseEventInfo.x, mouseEventInfo.y, mouseEventInfo.button); - window.clickCount = 0; + window.clickCount = 0; case MOUSE_MOVE: window.onMouseMove.dispatch(mouseEventInfo.x, mouseEventInfo.y); - window.onMouseMoveRelative.dispatch(mouseEventInfo.movementX, mouseEventInfo.movementY); + window.onMouseMoveRelative.dispatch(mouseEventInfo.movementX, mouseEventInfo.movementY); case MOUSE_WHEEL: window.onMouseWheel.dispatch(mouseEventInfo.x, mouseEventInfo.y, UNKNOWN); - default: } } @@ -402,13 +459,10 @@ class NativeApplication private function handleRenderEvent():Void { // TODO: Allow windows to render independently - for (window in parent.__windows) { if (window == null) continue; - // parent.renderer = renderer; - switch (renderEventInfo.type) { case RENDER: @@ -431,17 +485,16 @@ class NativeApplication case OPENGL, OPENGLES, WEBGL: #if (lime_cffi && (lime_opengl || lime_opengles) && !display) var gl = window.context.gl; + (gl : NativeOpenGLRenderContext).__contextLost(); if (GL.context == gl) GL.context = null; #end - default: } window.context = null; window.onRenderContextLost.dispatch(); } - case RENDER_CONTEXT_RESTORED: if (window.__backend.useHardware) { @@ -457,7 +510,6 @@ class NativeApplication private function handleSensorEvent():Void { var sensor = Sensor.sensorByID.get(sensorEventInfo.id); - if (sensor != null) { sensor.onUpdate.dispatch(sensorEventInfo.x, sensorEventInfo.y, sensorEventInfo.z); @@ -471,13 +523,12 @@ class NativeApplication if (window != null) { switch (textEventInfo.type) + { case TEXT_INPUT: window.onTextInput.dispatch(CFFI.stringValue(textEventInfo.text)); - case TEXT_EDIT: window.onTextEdit.dispatch(CFFI.stringValue(textEventInfo.text), textEventInfo.start, textEventInfo.length); - default: } } @@ -489,7 +540,6 @@ class NativeApplication { case TOUCH_START: var touch = unusedTouchesPool.pop(); - if (touch == null) { touch = new Touch(touchEventInfo.x, touchEventInfo.y, touchEventInfo.id, touchEventInfo.dx, touchEventInfo.dy, touchEventInfo.pressure, @@ -503,13 +553,12 @@ class NativeApplication touch.dx = touchEventInfo.dx; touch.dy = touchEventInfo.dy; touch.pressure = touchEventInfo.pressure; + touch.device = touchEventInfo.device; } - currentTouches.set(touch.id, touch); Touch.onStart.dispatch(touch); - case TOUCH_END: var touch = currentTouches.get(touchEventInfo.id); @@ -518,29 +567,27 @@ class NativeApplication touch.x = touchEventInfo.x; touch.y = touchEventInfo.y; touch.dx = touchEventInfo.dx; + touch.dy = touchEventInfo.dy; touch.pressure = touchEventInfo.pressure; Touch.onEnd.dispatch(touch); - currentTouches.remove(touchEventInfo.id); unusedTouchesPool.add(touch); } case TOUCH_MOVE: var touch = currentTouches.get(touchEventInfo.id); - if (touch != null) { touch.x = touchEventInfo.x; touch.y = touchEventInfo.y; touch.dx = touchEventInfo.dx; + touch.dy = touchEventInfo.dy; touch.pressure = touchEventInfo.pressure; - Touch.onMove.dispatch(touch); } - default: } } @@ -548,7 +595,6 @@ class NativeApplication private function handleWindowEvent():Void { var window = parent.__windowByID.get(windowEventInfo.windowID); - if (window != null) { switch (windowEventInfo.type) @@ -557,7 +603,6 @@ class NativeApplication advanceTimer(); window.onActivate.dispatch(); AudioManager.resume(); - case WINDOW_CLOSE: window.close(); @@ -565,19 +610,15 @@ class NativeApplication window.onDeactivate.dispatch(); AudioManager.suspend(); pauseTimer = System.getTimer(); - case WINDOW_ENTER: window.onEnter.dispatch(); - case WINDOW_EXPOSE: window.onExpose.dispatch(); - case WINDOW_FOCUS_IN: window.onFocusIn.dispatch(); case WINDOW_FOCUS_OUT: window.onFocusOut.dispatch(); - case WINDOW_LEAVE: window.onLeave.dispatch(); @@ -610,7 +651,6 @@ class NativeApplication case WINDOW_SHOW: window.onShow.dispatch(); - case WINDOW_HIDE: window.onHide.dispatch(); } @@ -623,8 +663,8 @@ class NativeApplication if (Timer.sRunningTimers.length > 0) { var currentTime = System.getTimer(); - var foundStopped = false; + var foundStopped = false; for (timer in Timer.sRunningTimers) { if (timer.mRunning) @@ -649,7 +689,6 @@ class NativeApplication }); } } - #if (haxe_ver >= 4.2) #if target.threaded sys.thread.Thread.current().events.progress(); @@ -776,6 +815,7 @@ class NativeApplication this.type = type; this.id = id; this.index = index; + this.eventValue = value; this.x = x; this.y = y; @@ -840,6 +880,7 @@ class NativeApplication { this.type = type; this.windowID = 0; + this.x = x; this.y = y; this.button = button; @@ -897,6 +938,7 @@ class NativeApplication this.type = type; this.id = id; this.x = x; + this.y = y; this.z = z; } @@ -957,6 +999,7 @@ class NativeApplication { this.type = type; this.x = x; + this.y = y; this.id = id; this.dx = dx; diff --git a/src/lime/_internal/backend/native/NativeCFFI.hx b/src/lime/_internal/backend/native/NativeCFFI.hx index e8c84f7b8a..9da3fddac1 100644 --- a/src/lime/_internal/backend/native/NativeCFFI.hx +++ b/src/lime/_internal/backend/native/NativeCFFI.hx @@ -65,8 +65,13 @@ class NativeCFFI @:cffi private static function lime_application_quit(handle:Dynamic):Int; + @:cffi private static function lime_application_set_main_loop(handle:Dynamic, profile:Int, frameRate:Float, timePrecision:Int, busyWait:Int, + uncapMode:Int):Void; + @:cffi private static function lime_application_set_frame_rate(handle:Dynamic, value:Float):Void; + @:cffi private static function lime_application_set_vsync_mode(handle:Dynamic, value:Int):Void; + @:cffi private static function lime_application_update(handle:Dynamic):Bool; @:cffi private static function lime_audio_load(data:Dynamic, buffer:Dynamic):Dynamic; @@ -395,8 +400,12 @@ class NativeCFFI private static var lime_application_exec = new cpp.CallableInt>(cpp.Prime._loadPrime("lime", "lime_application_exec", "oi", false)); private static var lime_application_init = new cpp.Callablecpp.Void>(cpp.Prime._loadPrime("lime", "lime_application_init", "ov", false)); private static var lime_application_quit = new cpp.CallableInt>(cpp.Prime._loadPrime("lime", "lime_application_quit", "oi", false)); + private static var lime_application_set_main_loop = new cpp.CallableInt->Float->Int->Int->Int->cpp.Void>(cpp.Prime._loadPrime("lime", + "lime_application_set_main_loop", "oidiiiv", false)); private static var lime_application_set_frame_rate = new cpp.CallableFloat->cpp.Void>(cpp.Prime._loadPrime("lime", "lime_application_set_frame_rate", "odv", false)); + private static var lime_application_set_vsync_mode = new cpp.CallableInt->cpp.Void>(cpp.Prime._loadPrime("lime", + "lime_application_set_vsync_mode", "oiv", false)); private static var lime_application_update = new cpp.CallableBool>(cpp.Prime._loadPrime("lime", "lime_application_update", "ob", false)); private static var lime_audio_load = new cpp.Callablecpp.Object->cpp.Object>(cpp.Prime._loadPrime("lime", "lime_audio_load", "ooo", false)); private static var lime_audio_load_bytes = new cpp.Callablecpp.Object->cpp.Object>(cpp.Prime._loadPrime("lime", "lime_audio_load_bytes", @@ -685,7 +694,9 @@ class NativeCFFI private static var lime_application_exec = CFFI.load("lime", "lime_application_exec", 1); private static var lime_application_init = CFFI.load("lime", "lime_application_init", 1); private static var lime_application_quit = CFFI.load("lime", "lime_application_quit", 1); + private static var lime_application_set_main_loop = CFFI.load("lime", "lime_application_set_main_loop", -1); private static var lime_application_set_frame_rate = CFFI.load("lime", "lime_application_set_frame_rate", 2); + private static var lime_application_set_vsync_mode = CFFI.load("lime", "lime_application_set_vsync_mode", 2); private static var lime_application_update = CFFI.load("lime", "lime_application_update", 1); private static var lime_audio_load = CFFI.load("lime", "lime_audio_load", 2); private static var lime_audio_load_bytes = CFFI.load("lime", "lime_audio_load_bytes", 2); @@ -870,6 +881,11 @@ class NativeCFFI @:hlNative("lime", "hl_application_set_frame_rate") private static function lime_application_set_frame_rate(handle:CFFIPointer, value:Float):Void {} + @:hlNative("lime", "hl_application_set_main_loop") private static function lime_application_set_main_loop(handle:CFFIPointer, profile:Int, + frameRate:Float, timePrecision:Int, busyWait:Int, uncapMode:Int):Void {} + + @:hlNative("lime", "hl_application_set_vsync_mode") private static function lime_application_set_vsync_mode(handle:CFFIPointer, value:Int):Void {} + @:hlNative("lime", "hl_application_update") private static function lime_application_update(handle:CFFIPointer):Bool { return false; diff --git a/src/lime/_internal/backend/native/NativeWindow.hx b/src/lime/_internal/backend/native/NativeWindow.hx index d5430bcde8..eadad12d3d 100644 --- a/src/lime/_internal/backend/native/NativeWindow.hx +++ b/src/lime/_internal/backend/native/NativeWindow.hx @@ -3,6 +3,7 @@ package lime._internal.backend.native; import haxe.io.Bytes; import lime._internal.backend.native.NativeCFFI; import lime.app.Application; +import lime.app.VSyncMode; import lime.graphics.cairo.Cairo; import lime.graphics.cairo.CairoFormat; import lime.graphics.cairo.CairoImageSurface; @@ -57,15 +58,15 @@ class NativeWindow public function new(parent:Window) { this.parent = parent; - cursor = DEFAULT; displayMode = new DisplayMode(0, 0, 0, 0); - var attributes = parent.__attributes; var contextAttributes = Reflect.hasField(attributes, "context") ? attributes.context : {}; + + var resolvedFrameRate = parent.application.__resolveFrameRate(attributes); + var resolvedVSyncMode = parent.application.__resolveVSyncMode(attributes); var title = Reflect.hasField(attributes, "title") ? attributes.title : "Lime Application"; var flags = 0; - if (!Reflect.hasField(contextAttributes, "antialiasing")) contextAttributes.antialiasing = 0; if (!Reflect.hasField(contextAttributes, "background")) contextAttributes.background = 0; if (!Reflect.hasField(contextAttributes, "colorDepth")) contextAttributes.colorDepth = 24; @@ -73,21 +74,25 @@ class NativeWindow if (!Reflect.hasField(contextAttributes, "hardware")) contextAttributes.hardware = true; if (!Reflect.hasField(contextAttributes, "stencil")) contextAttributes.stencil = true; if (!Reflect.hasField(contextAttributes, "vsync")) contextAttributes.vsync = false; + if (!Reflect.hasField(contextAttributes, "vsyncMode") + || contextAttributes.vsyncMode == null) contextAttributes.vsyncMode = resolvedVSyncMode; + contextAttributes.vsync = (resolvedVSyncMode != VSyncMode.Off); #if (cairo || (!lime_opengl && !lime_opengles)) contextAttributes.type = CAIRO; #end if (Reflect.hasField(contextAttributes, "type") && contextAttributes.type == CAIRO) contextAttributes.hardware = false; - if (Reflect.hasField(attributes, "allowHighDPI") && attributes.allowHighDPI) flags |= cast WindowFlags.WINDOW_FLAG_ALLOW_HIGHDPI; + if (Reflect.hasField(attributes, "alwaysOnTop") && attributes.alwaysOnTop) flags |= cast WindowFlags.WINDOW_FLAG_ALWAYS_ON_TOP; if (Reflect.hasField(attributes, "borderless") && attributes.borderless) flags |= cast WindowFlags.WINDOW_FLAG_BORDERLESS; if (Reflect.hasField(attributes, "fullscreen") && attributes.fullscreen) flags |= cast WindowFlags.WINDOW_FLAG_FULLSCREEN; + if (Reflect.hasField(attributes, "hidden") && attributes.hidden) flags |= cast WindowFlags.WINDOW_FLAG_HIDDEN; if (Reflect.hasField(attributes, "maximized") && attributes.maximized) flags |= cast WindowFlags.WINDOW_FLAG_MAXIMIZED; if (Reflect.hasField(attributes, "minimized") && attributes.minimized) flags |= cast WindowFlags.WINDOW_FLAG_MINIMIZED; - if (Reflect.hasField(attributes, "resizable") && attributes.resizable) flags |= cast WindowFlags.WINDOW_FLAG_RESIZABLE; + if (Reflect.hasField(attributes, "resizable") && attributes.resizable) flags |= cast WindowFlags.WINDOW_FLAG_RESIZABLE; if (contextAttributes.antialiasing >= 4) { flags |= cast WindowFlags.WINDOW_FLAG_HW_AA_HIRES; @@ -99,83 +104,78 @@ class NativeWindow if (contextAttributes.colorDepth == 32) flags |= cast WindowFlags.WINDOW_FLAG_COLOR_DEPTH_32_BIT; if (contextAttributes.depth) flags |= cast WindowFlags.WINDOW_FLAG_DEPTH_BUFFER; + if (contextAttributes.hardware) flags |= cast WindowFlags.WINDOW_FLAG_HARDWARE; if (contextAttributes.stencil) flags |= cast WindowFlags.WINDOW_FLAG_STENCIL_BUFFER; if (contextAttributes.vsync) flags |= cast WindowFlags.WINDOW_FLAG_VSYNC; var width = Reflect.hasField(attributes, "width") ? attributes.width : #if desktop 800 #else 0 #end; - var height = Reflect.hasField(attributes, "height") ? attributes.height : #if desktop 600 #else 0 #end; + var height = Reflect.hasField(attributes, "height") ? attributes.height : #if desktop 600 #else 0 #end; #if (!macro && lime_cffi) handle = NativeCFFI.lime_window_create(parent.application.__backend.handle, width, height, flags, title); if (handle != null) { parent.__width = NativeCFFI.lime_window_get_width(handle); + parent.__height = NativeCFFI.lime_window_get_height(handle); parent.__x = NativeCFFI.lime_window_get_x(handle); parent.__y = NativeCFFI.lime_window_get_y(handle); parent.__hidden = (Reflect.hasField(attributes, "hidden") && attributes.hidden); + parent.id = NativeCFFI.lime_window_get_id(handle); } - parent.__scale = NativeCFFI.lime_window_get_scale(handle); var context = new RenderContext(); context.window = parent; - var contextType:String = CFFI.stringValue(NativeCFFI.lime_window_get_context_type(handle)); - switch (contextType) + { case "opengl": var gl = new NativeOpenGLRenderContext(); - useHardware = true; - contextAttributes.hardware = true; + contextAttributes.hardware = true; #if lime_opengl context.gl = gl; #end - context.gles2 = gl; context.webgl = gl; context.type = gl.type; - context.version = Std.string(gl.version); + context.version = Std.string(gl.version); if (gl.type == OPENGLES && gl.version >= 3) { context.gles3 = gl; context.webgl2 = gl; } - if (GL.context == null) { GL.context = gl; } - default: useHardware = false; - contextAttributes.hardware = false; + contextAttributes.hardware = false; #if lime_cairo context.cairo = cairo; context.type = CAIRO; context.version = ""; - parent.context = context; render(); #end + context.type = CAIRO; } - contextAttributes.type = context.type; context.attributes = contextAttributes; parent.context = context; - setFrameRate(Reflect.hasField(attributes, "frameRate") ? attributes.frameRate : 60); + frameRate = resolvedFrameRate; #end - // SDL 2 enables text input events by default, but we want them only // when requested. otherwise, we might get weird behavior like IME // candidate windows appearing unexpectedly when holding down a key. @@ -200,7 +200,6 @@ class NativeWindow { closing = true; parent.onClose.dispatch(); - if (!parent.onClose.canceled) { if (handle != null) @@ -208,6 +207,7 @@ class NativeWindow #if (!macro && lime_cffi) NativeCFFI.lime_window_close(handle); #end + handle = null; } } @@ -231,7 +231,6 @@ class NativeWindow #end NativeCFFI.lime_window_context_unlock(handle); } - NativeCFFI.lime_window_context_flip(handle); #end } @@ -264,7 +263,6 @@ class NativeWindow } #end } - return null; } @@ -290,7 +288,7 @@ class NativeWindow public function getFrameRate():Float { - return frameRate; + return (parent.application != null) ? parent.application.__getFrameRate() : frameRate; } public function getMouseLock():Bool @@ -301,7 +299,6 @@ class NativeWindow mouseLock = NativeCFFI.lime_window_get_mouse_lock(handle); #end } - return mouseLock; } @@ -313,7 +310,6 @@ class NativeWindow return NativeCFFI.lime_window_get_opacity(handle); #end } - return 1.0; } @@ -325,7 +321,6 @@ class NativeWindow return NativeCFFI.lime_window_get_text_input_enabled(handle); #end } - return false; } @@ -344,20 +339,22 @@ class NativeWindow var imageBuffer:ImageBuffer = null; switch (parent.context.type) + { case OPENGL, OPENGLES, WEBGL: var gl = parent.context.webgl; var windowWidth = Std.int(parent.__width * parent.__scale); - var windowHeight = Std.int(parent.__height * parent.__scale); + var windowHeight = Std.int(parent.__height * parent.__scale); var x:Int; var y:Int; + var width:Int; var height:Int; - if (rect != null) { x = Std.int(rect.x); + y = Std.int((windowHeight - rect.y) - rect.height); width = Std.int(rect.width); height = Std.int(rect.height); @@ -365,17 +362,14 @@ class NativeWindow else { x = 0; + y = 0; width = windowWidth; height = windowHeight; } - var data = new UInt8Array(width * height * 4); - gl.readPixels(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, data); - #if !js // TODO - var rowLength = width * 4; var srcPosition = (height - 1) * rowLength; var destPosition = 0; @@ -383,7 +377,6 @@ class NativeWindow var temp = Bytes.alloc(rowLength); var buffer = data.buffer; var rows = Std.int(height / 2); - while (rows-- > 0) { temp.blit(0, buffer, destPosition, rowLength); @@ -394,15 +387,14 @@ class NativeWindow srcPosition -= rowLength; } #end - imageBuffer = new ImageBuffer(data, width, height, 32, RGBA32); - default: #if (!macro && lime_cffi) #if !cs imageBuffer = NativeCFFI.lime_window_read_pixels(handle, rect, new ImageBuffer(new UInt8Array(Bytes.alloc(0)))); #else var data:Dynamic = NativeCFFI.lime_window_read_pixels(handle, rect, null); + if (data != null) { imageBuffer = new ImageBuffer(new UInt8Array(@:privateAccess new Bytes(data.data.length, data.data.b)), data.width, data.height, @@ -410,18 +402,15 @@ class NativeWindow } #end #end - if (imageBuffer != null) { imageBuffer.format = RGBA32; } } - if (imageBuffer != null) { return new Image(imageBuffer); } - return null; } @@ -429,17 +418,14 @@ class NativeWindow { #if (!macro && lime_cffi) NativeCFFI.lime_window_context_make_current(handle); - if (!useHardware) { #if lime_cairo var lock:Dynamic = NativeCFFI.lime_window_context_lock(handle); - if (lock != null && (cacheLock == null || cacheLock.pixels != lock.pixels || cacheLock.width != lock.width || cacheLock.height != lock.height)) { primarySurface = CairoImageSurface.create(lock.pixels, CairoFormat.ARGB32, lock.width, lock.height, lock.pitch); - if (cairo != null) { cairo.recreate(primarySurface); @@ -448,10 +434,8 @@ class NativeWindow { cairo = new Cairo(primarySurface); } - parent.context.cairo = cairo; } - cacheLock = lock; #else parent.context = null; @@ -521,15 +505,16 @@ class NativeWindow case MOVE: MOVE; case POINTER: POINTER; case RESIZE_NESW: RESIZE_NESW; + case RESIZE_NS: RESIZE_NS; case RESIZE_NWSE: RESIZE_NWSE; case RESIZE_WE: RESIZE_WE; + case TEXT: TEXT; case WAIT: WAIT; case WAIT_ARROW: WAIT_ARROW; default: DEFAULT; } - #if (!macro && lime_cffi) NativeCFFI.lime_window_set_cursor(handle, type); #end @@ -550,6 +535,7 @@ class NativeWindow NativeCFFI.lime_window_set_display_mode(handle, value, displayMode); #else var data:Dynamic = NativeCFFI.lime_window_set_display_mode(handle, value); + displayMode.width = data.width; displayMode.height = data.height; displayMode.pixelFormat = data.pixelFormat; @@ -557,7 +543,6 @@ class NativeWindow #end #end } - return displayMode; } @@ -568,10 +553,8 @@ class NativeWindow #if (!macro && lime_cffi) NativeCFFI.lime_window_set_mouse_lock(handle, value); #end - mouseLock = value; } - return mouseLock; } @@ -583,7 +566,6 @@ class NativeWindow NativeCFFI.lime_window_set_text_input_enabled(handle, value); #end } - return value; } @@ -601,16 +583,8 @@ class NativeWindow public function setFrameRate(value:Float):Float { - // TODO: Support multiple independent frame rates per window - - if (handle != null) - { - #if (!macro && lime_cffi) - NativeCFFI.lime_application_set_frame_rate(parent.application.__backend.handle, value); - #end - } - - return frameRate = value; + frameRate = (parent.application != null) ? parent.application.__setFrameRateFromWindow(value) : value; + return frameRate; } public function setFullscreen(value:Bool):Bool @@ -619,19 +593,16 @@ class NativeWindow { #if (!macro && lime_cffi) value = NativeCFFI.lime_window_set_fullscreen(handle, value); - parent.__width = NativeCFFI.lime_window_get_width(handle); parent.__height = NativeCFFI.lime_window_get_height(handle); parent.__x = NativeCFFI.lime_window_get_x(handle); parent.__y = NativeCFFI.lime_window_get_y(handle); #end - if (value) { parent.onFullscreen.dispatch(); } } - return value; } @@ -687,12 +658,10 @@ class NativeWindow NativeCFFI.lime_window_set_resizable(handle, value); // TODO: remove need for workaround - NativeCFFI.lime_window_set_borderless(handle, !parent.__borderless); NativeCFFI.lime_window_set_borderless(handle, parent.__borderless); #end } - return value; } @@ -704,7 +673,6 @@ class NativeWindow return NativeCFFI.lime_window_set_title(handle, value); #end } - return value; } @@ -716,7 +684,6 @@ class NativeWindow NativeCFFI.lime_window_set_visible(handle, value); #end } - return value; } diff --git a/src/lime/app/Application.hx b/src/lime/app/Application.hx index fb318ca617..10d128991e 100644 --- a/src/lime/app/Application.hx +++ b/src/lime/app/Application.hx @@ -50,6 +50,20 @@ class Application extends Module **/ public var modules(default, null):Array; + /** + Advanced frame pacing options for the current application. + On native targets, these settings apply to the shared + application main loop. + **/ + public var frameOptions(get, set):FrameOptions; + + /** + The current frame pacing profile for this application. + On native targets, this controls the shared application + main loop strategy. + **/ + public var frameProfile(get, set):FrameProfile; + /** Update events are dispatched each frame (usually just before rendering) **/ @@ -89,8 +103,20 @@ class Application extends Module **/ public var windows(get, null):Array; + /** + The requested vertical-sync behavior for this application. + On native targets, this applies to the shared application + render loop and active windows. + **/ + public var vsyncMode(get, set):VSyncMode; + @:noCompletion private var __backend:ApplicationBackend; + @:noCompletion private var __frameRate:Float; + @:noCompletion private var __frameConfigured:Bool; + @:noCompletion private var __frameOptions:FrameOptions; + @:noCompletion private var __frameProfile:FrameProfile; @:noCompletion private var __preloader:Preloader; + @:noCompletion private var __vsyncMode:VSyncMode; @:noCompletion private var __window:Window; @:noCompletion private var __windowByID:Map; @:noCompletion private var __windows:Array; @@ -102,7 +128,10 @@ class Application extends Module var p = untyped Application.prototype; untyped Object.defineProperties(p, { + "frameOptions": {get: p.get_frameOptions, set: p.set_frameOptions}, + "frameProfile": {get: p.get_frameProfile, set: p.set_frameProfile}, "preloader": {get: p.get_preloader}, + "vsyncMode": {get: p.get_vsyncMode, set: p.set_vsyncMode}, "window": {get: p.get_window}, "windows": {get: p.get_windows} }); @@ -123,10 +152,22 @@ class Application extends Module meta = new Map(); modules = new Array(); + __frameRate = 60; + __frameConfigured = false; + __frameOptions = + { + timePrecision: TimePrecision.Auto, + busyWait: BusyWaitMode.Auto, + uncapMode: UncapMode.Off + }; + __frameProfile = FrameProfile.Balanced; __windowByID = new Map(); __windows = new Array(); + __vsyncMode = VSyncMode.Off; __backend = new ApplicationBackend(this); + __backend.configureFrameTiming(__frameProfile, __frameRate, __copyFrameOptions(__frameOptions)); + __backend.setVSyncMode(__vsyncMode); __registerLimeModule(this); @@ -169,6 +210,15 @@ class Application extends Module return __backend.exec(); } + /** + Configure the frame pacing profile, optional pacing overrides, + and optional vertical-sync mode at runtime. + **/ + public function configureFrameTiming(profile:FrameProfile, ?options:FrameOptions, ?vsyncMode:VSyncMode):Void + { + __applyFrameConfiguration(profile, options, vsyncMode, true); + } + /** Called when a gamepad axis move event is fired @param gamepad The current gamepad @@ -517,6 +567,7 @@ class Application extends Module { var window = new Window(this, attributes); if (window.id == -1) return null; + __seedFrameConfiguration(attributes); return window; } @@ -642,6 +693,16 @@ class Application extends Module return __preloader; } + @:noCompletion private inline function get_frameOptions():FrameOptions + { + return __copyFrameOptions(__frameOptions); + } + + @:noCompletion private inline function get_frameProfile():FrameProfile + { + return __frameProfile; + } + @:noCompletion private inline function get_window():Window { return __window; @@ -652,10 +713,188 @@ class Application extends Module return __windows; } + @:noCompletion private inline function get_vsyncMode():VSyncMode + { + return __vsyncMode; + } + + @:noCompletion private function set_frameOptions(value:FrameOptions):FrameOptions + { + __applyFrameConfiguration(__frameProfile, value, __vsyncMode, true); + return __copyFrameOptions(__frameOptions); + } + + @:noCompletion private function set_frameProfile(value:FrameProfile):FrameProfile + { + __applyFrameConfiguration(value, __frameOptions, __vsyncMode, true); + return __frameProfile; + } + + @:noCompletion private function set_vsyncMode(value:VSyncMode):VSyncMode + { + __applyFrameConfiguration(__frameProfile, __frameOptions, value, true); + return __vsyncMode; + } + @:noCompletion private function get_deviceOrientation():Orientation { return __backend.getDeviceOrientation(); } + + @:noCompletion private function __applyFrameConfiguration(profile:FrameProfile, ?options:FrameOptions, ?vsyncMode:VSyncMode, lock:Bool):Void + { + __frameProfile = (profile != null) ? profile : __frameProfile; + __frameOptions = __normalizeFrameOptions(options, __frameOptions); + __vsyncMode = (vsyncMode != null) ? vsyncMode : __vsyncMode; + + if (lock) + { + __frameConfigured = true; + } + + if (__backend != null) + { + __backend.configureFrameTiming(__frameProfile, __frameRate, __copyFrameOptions(__frameOptions)); + __backend.setVSyncMode(__vsyncMode); + } + } + + @:noCompletion private function __copyFrameOptions(value:FrameOptions):FrameOptions + { + if (value == null) + { + return { + timePrecision: TimePrecision.Auto, + busyWait: BusyWaitMode.Auto, + uncapMode: UncapMode.Off + }; + } + + return { + timePrecision: value.timePrecision, + busyWait: value.busyWait, + uncapMode: value.uncapMode + }; + } + + @:noCompletion private function __normalizeFrameOptions(value:FrameOptions, fallback:FrameOptions):FrameOptions + { + var base = __copyFrameOptions(fallback); + + if (value == null) + { + return base; + } + + if (Reflect.hasField(value, "timePrecision")) base.timePrecision = value.timePrecision; + if (Reflect.hasField(value, "busyWait")) base.busyWait = value.busyWait; + if (Reflect.hasField(value, "uncapMode")) base.uncapMode = value.uncapMode; + + return base; + } + + @:noCompletion private function __resolveFrameRate(attributes:WindowAttributes):Float + { + if (__frameConfigured) + { + return __frameRate; + } + + if (attributes != null && Reflect.hasField(attributes, "frameRate")) + { + return __normalizeFrameRate(attributes.frameRate); + } + + return __frameRate; + } + + @:noCompletion private function __resolveFrameOptions(attributes:WindowAttributes):FrameOptions + { + if (__frameConfigured) + { + return __copyFrameOptions(__frameOptions); + } + + var options = __copyFrameOptions(__frameOptions); + + if (attributes != null) + { + if (Reflect.hasField(attributes, "frameOptions") && attributes.frameOptions != null) + { + options = __normalizeFrameOptions(attributes.frameOptions, options); + } + } + + return options; + } + + @:noCompletion private function __resolveFrameProfile(attributes:WindowAttributes):FrameProfile + { + if (__frameConfigured) + { + return __frameProfile; + } + + if (attributes != null && Reflect.hasField(attributes, "frameProfile") && attributes.frameProfile != null) + { + return attributes.frameProfile; + } + + return __frameProfile; + } + + @:noCompletion private function __resolveVSyncMode(attributes:WindowAttributes):VSyncMode + { + if (__frameConfigured) + { + return __vsyncMode; + } + + if (attributes != null && Reflect.hasField(attributes, "context") && attributes.context != null) + { + var context = attributes.context; + + if (Reflect.hasField(context, "vsyncMode") && context.vsyncMode != null) + { + return context.vsyncMode; + } + + if (Reflect.hasField(context, "vsync") && context.vsync) + { + return VSyncMode.On; + } + } + + return __vsyncMode; + } + + @:noCompletion private function __seedFrameConfiguration(attributes:WindowAttributes):Void + { + if (__frameConfigured) + { + return; + } + + __frameRate = __resolveFrameRate(attributes); + __applyFrameConfiguration(__resolveFrameProfile(attributes), __resolveFrameOptions(attributes), __resolveVSyncMode(attributes), true); + } + + @:noCompletion private function __setFrameRateFromWindow(value:Float):Float + { + __frameRate = __normalizeFrameRate(value); + __applyFrameConfiguration(__frameProfile, __frameOptions, __vsyncMode, true); + return __frameRate; + } + + @:noCompletion private inline function __getFrameRate():Float + { + return __frameRate; + } + + @:noCompletion private inline function __normalizeFrameRate(value:Float):Float + { + return (value > 10000) ? 10000 : value; + } } #if air diff --git a/src/lime/app/BusyWaitMode.hx b/src/lime/app/BusyWaitMode.hx new file mode 100644 index 0000000000..2d212c29a9 --- /dev/null +++ b/src/lime/app/BusyWaitMode.hx @@ -0,0 +1,16 @@ +package lime.app; + +/** + Controls whether Lime may busy-wait near frame deadlines. +**/ +#if (haxe_ver >= 4.0) enum #else @:enum #end abstract BusyWaitMode(String) to String +{ + /** Use Lime's default busy-wait behavior for the active profile. **/ + var Auto = "auto"; + + /** Disable busy-waiting and favor lower CPU usage. **/ + var Off = "off"; + + /** Allow busy-waiting for tighter frame pacing. **/ + var On = "on"; +} diff --git a/src/lime/app/FrameOptions.hx b/src/lime/app/FrameOptions.hx new file mode 100644 index 0000000000..d123587585 --- /dev/null +++ b/src/lime/app/FrameOptions.hx @@ -0,0 +1,17 @@ +package lime.app; + +/** + Advanced frame pacing overrides that can be combined with a + frame profile. +**/ +typedef FrameOptions = +{ + /** Select the timer precision used for frame pacing. **/ + @:optional var timePrecision:TimePrecision; + + /** Control whether Lime may busy-wait near frame deadlines. **/ + @:optional var busyWait:BusyWaitMode; + + /** Control how aggressively Lime uncaps the render loop. **/ + @:optional var uncapMode:UncapMode; +} diff --git a/src/lime/app/FrameProfile.hx b/src/lime/app/FrameProfile.hx new file mode 100644 index 0000000000..31886fb099 --- /dev/null +++ b/src/lime/app/FrameProfile.hx @@ -0,0 +1,19 @@ +package lime.app; + +/** + Built-in frame pacing profiles for Lime applications. +**/ +#if (haxe_ver >= 4.0) enum #else @:enum #end abstract FrameProfile(String) to String +{ + /** A balanced default profile that preserves Lime's existing pacing behavior. **/ + var Balanced = "balanced"; + + /** A profile that favors tighter pacing and high-resolution timing. **/ + var Precision = "precision"; + + /** A profile that favors lower CPU usage over the tightest pacing. **/ + var LowEnergy = "lowEnergy"; + + /** A profile intended for explicit uncapped or benchmark-style rendering. **/ + var Uncapped = "uncapped"; +} diff --git a/src/lime/app/TimePrecision.hx b/src/lime/app/TimePrecision.hx new file mode 100644 index 0000000000..d3180c5882 --- /dev/null +++ b/src/lime/app/TimePrecision.hx @@ -0,0 +1,16 @@ +package lime.app; + +/** + Selects the timer precision used for frame pacing. +**/ +#if (haxe_ver >= 4.0) enum #else @:enum #end abstract TimePrecision(String) to String +{ + /** Use Lime's default precision for the active profile and platform. **/ + var Auto = "auto"; + + /** Use millisecond precision timing. **/ + var Millisecond = "millisecond"; + + /** Use higher precision timing when it is available. **/ + var HighResolution = "highResolution"; +} diff --git a/src/lime/app/UncapMode.hx b/src/lime/app/UncapMode.hx new file mode 100644 index 0000000000..d0d94cc41e --- /dev/null +++ b/src/lime/app/UncapMode.hx @@ -0,0 +1,16 @@ +package lime.app; + +/** + Controls how aggressively Lime uncaps the frame loop. +**/ +#if (haxe_ver >= 4.0) enum #else @:enum #end abstract UncapMode(String) to String +{ + /** Keep normal frame-rate limiting behavior enabled. **/ + var Off = "off"; + + /** Relax frame throttling while preserving the normal event pump structure. **/ + var Soft = "soft"; + + /** Remove frame throttling as aggressively as possible. **/ + var Hard = "hard"; +} diff --git a/src/lime/app/VSyncMode.hx b/src/lime/app/VSyncMode.hx new file mode 100644 index 0000000000..26dfb300ee --- /dev/null +++ b/src/lime/app/VSyncMode.hx @@ -0,0 +1,19 @@ +package lime.app; + +/** + Selects the requested vertical-sync behavior for rendering. +**/ +#if (haxe_ver >= 4.0) enum #else @:enum #end abstract VSyncMode(String) from String to String +{ + /** Disable vertical sync. **/ + var Off = "off"; + + /** Request standard vertical sync. **/ + var On = "on"; + + /** Request adaptive vertical sync when the platform supports it. **/ + var Adaptive = "adaptive"; + + /** Let Lime choose the best available sync behavior with fallbacks. **/ + var Auto = "auto"; +} diff --git a/src/lime/graphics/RenderContextAttributes.hx b/src/lime/graphics/RenderContextAttributes.hx index 059e0a4899..e89603f6dc 100644 --- a/src/lime/graphics/RenderContextAttributes.hx +++ b/src/lime/graphics/RenderContextAttributes.hx @@ -1,5 +1,7 @@ package lime.graphics; +import lime.app.VSyncMode; + /** Additional options possible for a render context **/ @@ -52,7 +54,15 @@ typedef RenderContextAttributes = @:optional var version:String; /** - Whether vertical-sync (VSync) is enabled + Whether vertical-sync (VSync) is enabled. + This is the legacy boolean form; when both are provided, + `vsyncMode` takes precedence. **/ @:optional var vsync:Bool; + + /** + The requested vertical-sync behavior for this context. + This supersedes the legacy `vsync` boolean when both are set. + **/ + @:optional var vsyncMode:VSyncMode; } diff --git a/src/lime/system/Clipboard.hx b/src/lime/system/Clipboard.hx index f0cb891336..b17dd1c424 100644 --- a/src/lime/system/Clipboard.hx +++ b/src/lime/system/Clipboard.hx @@ -60,9 +60,10 @@ class Clipboard // Get & Set Methods private static function get_text():String { - // Native clipboard (except Xorg) calls __update when clipboard changes. - - #if (flash || js || html5) + // On some native platforms, __update() is called automatically when the + // native clipboard changes. On others, __update() needs to be called + // manually. + #if (flash || js || html5 || ios || tvos || android) __update(); #elseif linux // Xorg won't call __update until we call set_text at least once. diff --git a/src/lime/system/System.hx b/src/lime/system/System.hx index d7b21a1490..2817372234 100644 --- a/src/lime/system/System.hx +++ b/src/lime/system/System.hx @@ -3,6 +3,7 @@ package lime.system; import haxe.Constraints; import lime._internal.backend.native.NativeCFFI; import lime.app.Application; +import lime.app.VSyncMode; import lime.graphics.RenderContextAttributes; import lime.math.Rectangle; import lime.ui.WindowAttributes; @@ -129,11 +130,9 @@ class System public static function embed(projectName:String, element:Dynamic, width:Null = null, height:Null = null, config:Dynamic = null):Void { if (__applicationEntryPoint == null) return; - if (__applicationEntryPoint.exists(projectName)) { var htmlElement:Element = null; - if ((element is String)) { htmlElement = cast Browser.document.getElementById(element); @@ -164,11 +163,9 @@ class System } if (config == null) config = {}; - if (Reflect.hasField(config, "background") && (config.background is String)) { var background = StringTools.replace(Std.string(config.background), "#", ""); - if (background.indexOf("0x") > -1) { config.background = Std.parseInt(background); @@ -178,7 +175,6 @@ class System config.background = Std.parseInt("0x" + background); } } - config.element = htmlElement; config.width = width; config.height = height; @@ -211,14 +207,12 @@ class System if (currentApp != null) { currentApp.onExit.dispatch(code); - if (currentApp.onExit.canceled) { return; } } #end - #if sys Sys.exit(code); #elseif (js && html5) @@ -239,7 +233,6 @@ class System { #if (lime_cffi && !macro) var displayInfo:Dynamic = NativeCFFI.lime_system_get_display(id); - if (displayInfo != null) { var display = new Display(); @@ -247,23 +240,21 @@ class System display.name = CFFI.stringValue(displayInfo.name); display.bounds = new Rectangle(displayInfo.bounds.x, displayInfo.bounds.y, displayInfo.bounds.width, displayInfo.bounds.height); display.orientation = displayInfo.orientation; - #if android var getDisplaySafeArea = JNI.createStaticMethod("org/haxe/lime/GameActivity", "getDisplaySafeAreaInsets", "()[I"); var result = getDisplaySafeArea(); - display.safeArea = new Rectangle( - display.bounds.x + result[0], - display.bounds.y + result[1], - display.bounds.width - result[0] - result[2], - display.bounds.height - result[1] - result[3]); + display.safeArea = new Rectangle(display.bounds.x + + result[0], display.bounds.y + + result[1], display.bounds.width + - result[0] + - result[2], + display.bounds.height + - result[1] + - result[3]); #else - display.safeArea = new Rectangle( - displayInfo.safeArea.x, - displayInfo.safeArea.y, - displayInfo.safeArea.width, - displayInfo.safeArea.height); - #end + display.safeArea = new Rectangle(displayInfo.safeArea.x, displayInfo.safeArea.y, displayInfo.safeArea.width, displayInfo.safeArea.height); + #end #if ios var tablet = NativeCFFI.lime_system_get_ios_tablet(); var scale = Application.current.window.scale; @@ -281,25 +272,22 @@ class System #else display.dpi = displayInfo.dpi; #end - display.supportedModes = []; - var displayMode; - #if hl var supportedModes:hl.NativeArray = displayInfo.supportedModes; #else var supportedModes:Array = displayInfo.supportedModes; #end + for (mode in supportedModes) { displayMode = new DisplayMode(mode.width, mode.height, mode.refreshRate, mode.pixelFormat); + display.supportedModes.push(displayMode); } - var mode = displayInfo.currentMode; var currentMode = new DisplayMode(mode.width, mode.height, mode.refreshRate, mode.pixelFormat); - for (mode in display.supportedModes) { if (currentMode.pixelFormat == mode.pixelFormat @@ -308,12 +296,11 @@ class System && currentMode.refreshRate == mode.refreshRate) { currentMode = mode; + break; } } - display.currentMode = currentMode; - return display; } #elseif (flash || html5) @@ -322,24 +309,24 @@ class System var display = new Display(); display.id = 0; display.name = "Generic Display"; - #if flash display.dpi = Capabilities.screenDPI; display.currentMode = new DisplayMode(Std.int(Capabilities.screenResolutionX), Std.int(Capabilities.screenResolutionY), 60, ARGB32); #if air - switch (flash.Lib.current.stage.orientation) { + switch (flash.Lib.current.stage.orientation) + { case DEFAULT: display.orientation = PORTRAIT; case UPSIDE_DOWN: display.orientation = PORTRAIT_FLIPPED; case ROTATED_LEFT: display.orientation = LANDSCAPE_FLIPPED; + case ROTATED_RIGHT: display.orientation = LANDSCAPE; default: display.orientation = UNKNOWN; } - #else display.orientation = UNKNOWN; #end @@ -373,14 +360,13 @@ class System display.orientation = UNKNOWN; } #end - display.supportedModes = [display.currentMode]; + display.bounds = new Rectangle(0, 0, display.currentMode.width, display.currentMode.height); display.safeArea = new Rectangle(0, 0, display.currentMode.width, display.currentMode.height); return display; } #end - return null; } @@ -468,7 +454,6 @@ class System @:noCompletion private static function __copyMissingFields(target:Dynamic, source:Dynamic):Void { if (source == null || target == null) return; - for (field in Reflect.fields(source)) { if (!Reflect.hasField(target, field)) @@ -493,7 +478,6 @@ class System { var company = "MyCompany"; var file = "MyApplication"; - if (Application.current != null) { if (Application.current.meta.exists("company")) @@ -506,7 +490,6 @@ class System file = Application.current.meta.get("file"); } } - path = CFFI.stringValue(NativeCFFI.lime_system_get_directory(type, company, file)); } else @@ -524,7 +507,6 @@ class System { path += seperator; } - __directories.set(type, path); return path; } @@ -534,16 +516,15 @@ class System var propertyName = switch (type) { case APPLICATION: "applicationDirectory"; + case APPLICATION_STORAGE: "applicationStorageDirectory"; case DESKTOP: "desktopDirectory"; case DOCUMENTS: "documentsDirectory"; default: "userDirectory"; } - return Reflect.getProperty(Type.resolveClass("flash.filesystem.File"), propertyName).nativePath; } #end - return null; } @@ -562,7 +543,6 @@ class System for (argument in arguments) { equals = argument.indexOf("="); - if (equals > 0) { argValue = argument.substr(equals + 1); @@ -581,12 +561,11 @@ class System if (parameters != null) { if (attributes.parameters == null) attributes.parameters = {}; - if (attributes.context == null) attributes.context = {}; + if (attributes.context == null) attributes.context = {}; for (parameter in parameters.keys()) { argValue = parameters.get(parameter); - if (#if lime_disable_window_override false && #end StringTools.startsWith(parameter, windowParamPrefix)) { switch (parameter.substr(windowParamPrefix.length)) @@ -627,8 +606,14 @@ class System case "stencil", "stencil-buffer": attributes.context.stencil = __parseBool(argValue); // case "title": windowConfig.title = argValue; - case "vsync": - attributes.context.vsync = __parseBool(argValue); + case "vsync", "vsync-mode": + var vsyncMode = __parseVSyncMode(argValue); + if (vsyncMode != null) + { + attributes.context.vsyncMode = vsyncMode; + attributes.context.vsync = (vsyncMode != VSyncMode.Off); + } + case "width": attributes.width = Std.parseInt(argValue); case "x": @@ -652,13 +637,30 @@ class System return (value == "true"); } + @:noCompletion private static function __parseVSyncMode(value:String):Null + { + switch (value.toLowerCase()) + { + case "true", "on": + return VSyncMode.On; + case "false", "off": + return VSyncMode.Off; + case "adaptive": + return VSyncMode.Adaptive; + case "auto": + return VSyncMode.Auto; + + default: + return null; + } + } + @:noCompletion private static function __registerEntryPoint(projectName:String, entryPoint:Function):Void { if (__applicationEntryPoint == null) { __applicationEntryPoint = new Map(); } - __applicationEntryPoint[projectName] = entryPoint; } @@ -668,7 +670,6 @@ class System try { if (args == null) args = []; - var process = new Process(command, args); var value = StringTools.trim(process.stdout.readLine().toString()); process.close(); @@ -676,6 +677,7 @@ class System } catch (e:Dynamic) {} #end + return null; } @@ -714,7 +716,6 @@ class System { __applicationStorageDirectory = __getDirectory(APPLICATION_STORAGE); } - return __applicationStorageDirectory; } @@ -726,6 +727,7 @@ class System __deviceModel = CFFI.stringValue(NativeCFFI.lime_system_get_device_model()); #elseif android var manufacturer:String = JNI.createStaticField("android/os/Build", "MANUFACTURER", "Ljava/lang/String;").get(); + var model:String = JNI.createStaticField("android/os/Build", "MODEL", "Ljava/lang/String;").get(); if (manufacturer != null && model != null) { @@ -787,7 +789,6 @@ class System { __documentsDirectory = __getDirectory(DOCUMENTS); } - return __documentsDirectory; } @@ -818,7 +819,6 @@ class System { __fontsDirectory = __getDirectory(FONTS); } - return __fontsDirectory; } @@ -885,7 +885,6 @@ class System __platformName = "HTML5"; #end } - return __platformName; } @@ -909,7 +908,6 @@ class System __platformVersion = Capabilities.version; #end } - return __platformVersion; } @@ -919,7 +917,6 @@ class System { __userDirectory = __getDirectory(USER); } - return __userDirectory; } } diff --git a/src/lime/tools/ProjectXMLParser.hx b/src/lime/tools/ProjectXMLParser.hx index adf2ec188e..22b4395a36 100644 --- a/src/lime/tools/ProjectXMLParser.hx +++ b/src/lime/tools/ProjectXMLParser.hx @@ -1434,7 +1434,6 @@ class ProjectXMLParser extends HXProject sources.push(path); case "extension": - // deprecated case "haxedef": @@ -1536,7 +1535,6 @@ class ProjectXMLParser extends HXProject parseModuleElement(element, extensionPath); case "ssl": - // if (wantSslCertificate()) // parseSsl (element); @@ -1997,7 +1995,17 @@ class ProjectXMLParser extends HXProject { Reflect.setField(windows[id], "colorDepth", parsedValue); } - + case "vsync", "vsync-mode": + var parsedVSync = parseVSyncValue(value); + if (parsedVSync == null) + { + Log.warn("Ignoring unknown " + name + "=\"" + value + "\""); + } + else + { + Reflect.setField(windows[id], "vsync", parsedVSync != "off"); + Reflect.setField(windows[id], "vsyncMode", parsedVSync); + } default: if (Reflect.hasField(WindowData.expectedFields, name)) { @@ -2025,14 +2033,12 @@ class ProjectXMLParser extends HXProject { Log.error("\"" + projectFile + "\" contains invalid XML data", e); } - parseXML(xml, "", extensionPath); } private function substitute(string:String):String { var newString = string; - while (doubleVarMatch.match(newString)) { newString = doubleVarMatch.matchedLeft() @@ -2041,12 +2047,27 @@ class ProjectXMLParser extends HXProject + "}" + doubleVarMatch.matchedRight(); } - while (varMatch.match(newString)) { newString = varMatch.matchedLeft() + ProjectHelper.replaceVariable(this, varMatch.matched(1)) + varMatch.matchedRight(); } - return newString; } + + private static function parseVSyncValue(value:String):String + { + switch (value.toLowerCase()) + { + case "true", "on": + return "on"; + case "false", "off": + return "off"; + case "adaptive": + return "adaptive"; + case "auto": + return "auto"; + default: + return null; + } + } } diff --git a/src/lime/tools/WindowData.hx b/src/lime/tools/WindowData.hx index d861cd23b5..e0f461a5c9 100644 --- a/src/lime/tools/WindowData.hx +++ b/src/lime/tools/WindowData.hx @@ -14,6 +14,7 @@ abstract WindowData({ @:optional var resizable:Bool; @:optional var borderless:Bool; @:optional var vsync:Bool; + @:optional var vsyncMode:String; @:optional var fullscreen:Bool; @:optional var allowHighDPI:Bool; @:optional var alwaysOnTop:Bool; @@ -34,35 +35,37 @@ abstract WindowData({ }) from Dynamic { @:noCompletion - public static var expectedFields:WindowData = { - width: 0, - height: 0, - x: 0.0, - y: 0.0, - background: 0, - parameters: "", - fps: 0, - hardware: false, - display: 0, - resizable: false, - borderless: false, - vsync: false, - fullscreen: false, - allowHighDPI: false, - alwaysOnTop: false, - antialiasing: 0, - orientation: Orientation.AUTO, - allowShaders: false, - requireShaders: false, - depthBuffer: false, - stencilBuffer: false, - title: "", - #if (js && html5) - element: null, - #end - colorDepth: 0, - minimized: false, - maximized: false, - hidden: false - }; + public static var expectedFields:WindowData = + { + width: 0, + height: 0, + x: 0.0, + y: 0.0, + background: 0, + parameters: "", + fps: 0, + hardware: false, + display: 0, + resizable: false, + borderless: false, + vsync: false, + vsyncMode: null, + fullscreen: false, + allowHighDPI: false, + alwaysOnTop: false, + antialiasing: 0, + orientation: Orientation.AUTO, + allowShaders: false, + requireShaders: false, + depthBuffer: false, + stencilBuffer: false, + title: "", + #if (js && html5) + element: null, + #end + colorDepth: 0, + minimized: false, + maximized: false, + hidden: false + }; } diff --git a/src/lime/ui/Window.hx b/src/lime/ui/Window.hx index c097be051b..ac0ea3ebef 100644 --- a/src/lime/ui/Window.hx +++ b/src/lime/ui/Window.hx @@ -2,6 +2,7 @@ package lime.ui; import lime.app.Application; import lime.app.Event; +import lime.app.VSyncMode; import lime.graphics.Image; import lime.graphics.RenderContext; import lime.graphics.RenderContextAttributes; @@ -41,11 +42,20 @@ class Window /** * The current frame rate (measured in frames-per-second) of the window. * - * On some platforms, a frame rate of 60 or greater may imply vsync, which will - * perform more quickly on displays with a higher refresh rate + * On native targets, this forwards to the shared application frame pacing + * value for compatibility. On some platforms, a frame rate of 60 or greater + * may imply vsync, which will perform more quickly on displays with a + * higher refresh rate. **/ public var frameRate(get, set):Float; + /** + * The requested vertical-sync behavior for this window. + * + * On native targets, this is a convenience alias for the shared application + * vertical-sync setting. + **/ + public var vsyncMode(get, set):VSyncMode; public var fullscreen(get, set):Bool; public var height(get, set):Int; public var hidden(get, null):Bool; @@ -99,6 +109,7 @@ class Window Fired when the mouse is moved over the window. **/ public var onMouseMove(default, null) = new EventFloat->Void>(); + public var onMouseMoveRelative(default, null) = new EventFloat->Void>(); /** @@ -115,6 +126,7 @@ class Window Fired when the window is moved to a new position. **/ public var onMove(default, null) = new EventFloat->Void>(); + public var onRender(default, null) = new EventVoid>(); public var onRenderContextLost(default, null) = new EventVoid>(); public var onRenderContextRestored(default, null) = new EventVoid>(); @@ -128,7 +140,6 @@ class Window public var onShow(default, null) = new EventVoid>(); public var onTextEdit(default, null) = new EventInt->Int->Void>(); public var onTextInput(default, null) = new EventVoid>(); - public var opacity(get, set):Float; public var parameters:Dynamic; public var resizable(get, set):Bool; @@ -148,7 +159,6 @@ class Window @:allow(lime.app.Application) @:allow(lime._internal.backend.html5.HTML5Window) private var clickCount:Int = 0; - @:noCompletion private var __attributes:WindowAttributes; @:noCompletion private var __backend:WindowBackend; @:noCompletion private var __borderless:Bool; @@ -184,15 +194,19 @@ class Window "height": {get: p.get_height, set: p.set_height}, "maxHeight": {get: p.get_maxHeight, set: p.set_maxHeight}, "maximized": {get: p.get_maximized, set: p.set_maximized}, + "maxWidth": {get: p.get_maxWidth, set: p.set_maxWidth}, "minHeight": {get: p.get_minHeight, set: p.set_minHeight}, "minimized": {get: p.get_minimized, set: p.set_minimized}, "minWidth": {get: p.get_minWidth, set: p.set_minWidth}, "mouseLock": {get: p.get_mouseLock, set: p.set_mouseLock}, + "resizable": {get: p.get_resizable, set: p.set_resizable}, "scale": {get: p.get_scale}, + "textInputEnabled": {get: p.get_textInputEnabled, set: p.set_textInputEnabled}, "title": {get: p.get_title, set: p.set_title}, + "vsyncMode": {get: p.get_vsyncMode, set: p.set_vsyncMode}, "visible": {get: p.get_visible, set: p.set_visible}, "alwaysOnTop": {get: p.get_alwaysOnTop, set: p.set_alwaysOnTop}, "width": {get: p.get_width, set: p.set_width}, @@ -211,6 +225,7 @@ class Window __width = 0; __height = 0; + __fullscreen = false; __scale = 1; __x = 0; @@ -221,14 +236,10 @@ class Window __resizable = Reflect.hasField(__attributes, "resizable") ? __attributes.resizable : false; __maximized = Reflect.hasField(__attributes, "maximized") ? __attributes.maximized : false; __minimized = Reflect.hasField(__attributes, "minimized") ? __attributes.minimized : false; - id = -1; - __backend = new WindowBackend(this); - #if windows var mappings = [ - "8f0e1200000000000000504944564944,Acme,platform:Windows,x:b2,a:b0,b:b1,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2", "341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows", "ffff0000000000000000504944564944,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows", @@ -258,12 +269,15 @@ class Window "4f0415b3000000000000504944564944,Thrustmaster Dual Analog 3.2,platform:Windows,x:b1,a:b0,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3", "6f0e1e01000000000000504944564944,Rock Candy Gamepad for PS3,platform:Windows,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,guide:b12,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2", "83056020000000000000504944564944,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,y:b2,x:b3,start:b7,back:b6,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,platform:Windows", + "10080100000000000000504944564944,PS1 USB,platform:Windows,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftshoulder:b6,rightshoulder:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2", "49190204000000000000504944564944,Ipega PG-9023,a:b0,b:b1,x:b3,y:b4,back:b10,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b8,righttrigger:b9,platform:Windows", + "4f0423b3000000000000504944564944,Dual Trigger 3-in-1,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:b7,platform:Windows", "0d0f4900000000000000504944564944,Hatsune Miku Sho Controller,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows", "79004318000000000000504944564944,Mayflash GameCube Controller Adapter,platform:Windows,a:b1,b:b2,x:b0,y:b3,back:b0,start:b9,guide:b0,leftshoulder:b4,rightshoulder:b7,leftstick:b0,rightstick:b0,leftx:a0,lefty:a1,rightx:a5,righty:a2,lefttrigger:a3,righttrigger:a4,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2", "79000018000000000000504944564944,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows", + "2509e803000000000000504944564944,Mayflash Wii Classic Controller,a:b1,b:b0,x:b3,y:b2,back:b8,guide:b10,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:b11,dpdown:b13,dpleft:b12,dpright:b14,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows", "300f1001000000000000504944564944,Saitek P480 Rumble Pad,a:b2,b:b3,x:b0,y:b1,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b5,righttrigger:b7,platform:Windows", "10280900000000000000504944564944,8Bitdo SFC30 GamePad,a:b1,b:b0,y:b3,x:b4,start:b11,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,platform:Windows", @@ -275,13 +289,10 @@ class Window "c0111352000000000000504944564944,Battalife Joystick,platform:Windows,x:b4,a:b6,b:b7,y:b5,back:b2,start:b3,leftshoulder:b0,rightshoulder:b1,leftx:a0,lefty:a1", "100801e5000000000000504944564944,NEXT Classic USB Game Controller,a:b0,b:b1,back:b8,start:b9,rightx:a2,righty:a3,leftx:a0,lefty:a1,platform:Windows", "79000600000000000000504944564944,NGS Phantom,a:b2,b:b3,y:b1,x:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b6,righttrigger:b7,platform:Windows" - ]; - Gamepad.addMappings(mappings); #elseif mac var mappings = [ - "0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X", "6d0400000000000016c2000000000000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X", "6d0400000000000018c2000000000000,Logitech F510 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X", @@ -297,12 +308,15 @@ class Window "0d0f0000000000004d00000000000000,HORI Gem Pad 3,platform:Mac OS X,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7", "79000000000000000600000000000000,G-Shark GP-702,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b6,righttrigger:b7,platform:Mac OS X", "4f0400000000000015b3000000000000,Thrustmaster Dual Analog 3.2,platform:Mac OS X,x:b1,a:b0,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3", + "AD1B00000000000001F9000000000000,Gamestop BB-070 X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X", "050000005769696d6f74652028303000,Wii Remote,a:b4,b:b5,y:b9,x:b10,start:b6,guide:b8,back:b7,dpup:b2,dpleft:b0,dpdown:b3,dpright:b1,leftx:a0,lefty:a1,lefttrigger:b12,righttrigger:,leftshoulder:b11,platform:Mac OS X", + "83050000000000006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,x:b3,y:b2,back:b6,start:b7,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,platform:Mac OS X", "bd1200000000000015d0000000000000,Tomee SNES USB Controller,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,platform:Mac OS X", "79000000000000001100000000000000,Retrolink Classic Controller,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a3,lefty:a4,platform:Mac OS X", "5e04000000000000dd02000000000000,Xbox One Wired Controller,platform:Mac OS X,x:b2,a:b0,b:b1,y:b3,back:b9,guide:b10,start:b8,dpleft:b13,dpdown:b12,dpright:b14,dpup:b11,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b6,rightstick:b7,leftx:a0,lefty:a1,rightx:a3,righty:a4", + "5e04000000000000ea02000000000000,Xbox Wireless Controller,platform:Mac OS X,x:b2,a:b0,b:b1,y:b3,back:b9,guide:b10,start:b8,dpleft:b13,dpdown:b12,dpright:b14,dpup:b11,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b6,rightstick:b7,leftx:a0,lefty:a1,rightx:a3,righty:a4", "5e04000000000000e002000000000000,Xbox Wireless Controller,platform:Mac OS X,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b10,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a3,righty:a4", "050000005769696d6f74652028313800,Wii U Pro Controller,a:b16,b:b15,x:b18,y:b17,back:b7,guide:b8,start:b6,leftstick:b23,rightstick:b24,leftshoulder:b19,rightshoulder:b20,dpup:b11,dpdown:b12,dpleft:b13,dpright:b14,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b21,righttrigger:b22,platform:Mac OS X", @@ -314,13 +328,10 @@ class Window "10280000000000000900000000000000,8Bitdo SFC30 GamePad,a:b1,b:b0,x:b4,y:b3,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Mac OS X", "d814000000000000cecf000000000000,MC Cthulhu,platform:Mac OS X,leftx:,lefty:,rightx:,righty:,lefttrigger:b6,a:b1,b:b2,y:b3,x:b0,start:b9,back:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,righttrigger:b7", "0d0f0000000000006600000000000000,HORIPAD FPS PLUS 4,platform:Mac OS X,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:a4" - ]; - Gamepad.addMappings(mappings); #elseif linux var mappings = [ - "0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux", "03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux", "030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux", @@ -397,36 +408,38 @@ class Window "030000006f0e00003901000020060000,Afterglow Wired Controller for Xbox One,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,platform:Linux", "030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,platform:Linux,a:b0,b:b2,x:b1,y:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7", "05000000102800000900000000010000,8Bitdo SFC30 GamePad,platform:Linux,x:b4,a:b1,b:b0,y:b3,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1", + "03000000d81400000862000011010000,HitBox (PS3/PC) Analog Mode,platform:Linux,a:b1,b:b2,y:b3,x:b0,start:b12,guide:b9,back:b8,leftshoulder:b4,rightshoulder:b5,lefttrigger:b6,righttrigger:b7,leftx:a0,lefty:a1", "030000000d0f00000d00000000010000,hori,platform:Linux,a:b0,b:b6,y:b2,x:b1,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,start:b9,guide:b10,back:b8,leftshoulder:b3,rightshoulder:b7,leftx:b4,lefty:b5", + "03000000ad1b000016f0000090040000,Mad Catz Xbox 360 Controller,platform:Linux,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5", "03000000d814000007cd000011010000,Toodles 2008 Chimp PC/PS3,platform:Linux,a:b0,b:b1,y:b2,x:b3,start:b9,back:b8,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,lefttrigger:b6,righttrigger:b7", "03000000fd0500000030000000010000,InterAct GoPad I-73000 (Fighting Game Layout),platform:Linux,a:b3,b:b4,y:b1,x:b0,start:b7,back:b6,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5", "05000000010000000100000003000000,Nintendo Wiimote,platform:Linux,a:b0,b:b1,y:b3,x:b2,start:b9,guide:b10,back:b8,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7", + "030000005e0400008e02000062230000,Microsoft X-Box 360 pad,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4", "03000000a30600000901000000010000,Saitek P880,a:b2,b:b3,y:b1,x:b0,leftstick:b8,rightstick:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b6,righttrigger:b7,platform:Linux", "030000006f0e00000103000000020000,Logic3 Controller,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4", "05000000380700006652000025010000,Mad Catz C.T.R.L.R ,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3", + "030000005e0400008e02000073050000,Speedlink TORID Wireless Gamepad,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4", "03000000ad1b00002ef0000090040000,Mad Catz Fightpad SFxT,platform:Linux,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,lefttrigger:a2,righttrigger:a5", + "05000000a00500003232000001000000,8Bitdo Zero GamePad,platform:Linux,a:b0,b:b1,x:b3,y:b4,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1", "030000001008000001e5000010010000,NEXT Classic USB Game Controller,a:b0,b:b1,back:b8,start:b9,rightx:a2,righty:a3,leftx:a0,lefty:a1,platform:Linux", "03000000100800000300000010010000,USB Gamepad,platform:Linux,a:b2,b:b1,x:b3,y:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5", "05000000ac0500003232000001000000,VR-BOX,platform:Linux,a:b0,b:b1,x:b2,y:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5", - "03000000780000000600000010010000,Microntek USB Joystick,platform:Linux,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftx:a0,lefty:a1" + "03000000780000000600000010010000,Microntek USB Joystick,platform:Linux,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftx:a0,lefty:a1" ]; - Gamepad.addMappings(mappings); #elseif (ios || tvos) var mappings = [ - "4d466947616d65706164010000000000,MFi Extended Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,", "4d466947616d65706164020000000000,MFi Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b6,x:b2,y:b3,", - "4d466947616d65706164030000000000,MFi Apple TV Remote,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b6,x:b2,y:b3,", + "4d466947616d65706164030000000000,MFi Apple TV Remote,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b6,x:b2,y:b3,", ]; - Gamepad.addMappings(mappings); #end } @@ -449,7 +462,6 @@ class Window public function move(x:Int, y:Int):Void { __backend.move(x, y); - __x = x; __y = y; } @@ -479,8 +491,8 @@ class Window } __backend.resize(width, height); - __width = width; + __height = height; } @@ -490,7 +502,8 @@ class Window __minWidth = width; __minHeight = height; - if (__width < __minWidth || __height < __minHeight) { + if (__width < __minWidth || __height < __minHeight) + { resize(__width, __height); } } @@ -501,7 +514,8 @@ class Window __maxWidth = width; __maxHeight = height; - if (__width > __maxWidth || __height > __maxHeight) { + if (__width > __maxWidth || __height > __maxHeight) + { resize(__width, __height); } } @@ -512,7 +526,6 @@ class Window { return; } - __backend.setIcon(image); } @@ -572,6 +585,21 @@ class Window return __backend.setFrameRate(value); } + @:noCompletion private function get_vsyncMode():VSyncMode + { + return (application != null) ? application.vsyncMode : VSyncMode.Off; + } + + @:noCompletion private function set_vsyncMode(value:VSyncMode):VSyncMode + { + if (application != null) + { + application.vsyncMode = value; + return application.vsyncMode; + } + return value; + } + @:noCompletion private inline function get_fullscreen():Bool { return __fullscreen; @@ -694,6 +722,7 @@ class Window @:noCompletion private function set_resizable(value:Bool):Bool { __resizable = __backend.setResizable(value); + return __resizable; } diff --git a/src/lime/ui/WindowAttributes.hx b/src/lime/ui/WindowAttributes.hx index 4b6f023351..6887f8f649 100644 --- a/src/lime/ui/WindowAttributes.hx +++ b/src/lime/ui/WindowAttributes.hx @@ -1,5 +1,7 @@ package lime.ui; +import lime.app.FrameOptions; +import lime.app.FrameProfile; import lime.graphics.RenderContextAttributes; typedef WindowAttributes = @@ -10,7 +12,26 @@ typedef WindowAttributes = @:optional public var context:RenderContextAttributes; // @:optional public var display:Int; @:optional public var element:#if (js && html5 && !doc_gen) js.html.Element #else Dynamic #end; + + /** + The desired frame rate in frames-per-second for this window. + On native targets, the first window created will seed the + shared application frame pacing value. + **/ @:optional public var frameRate:Float; + + /** + Advanced frame pacing overrides for the application loop created + alongside this window. + **/ + @:optional public var frameOptions:FrameOptions; + + /** + The frame pacing profile to use when this window is created. + On native targets, the first window created will seed the + shared application frame profile. + **/ + @:optional public var frameProfile:FrameProfile; @:optional public var fullscreen:Bool; @:optional public var height:Int; @:optional public var hidden:Bool; diff --git a/src/lime/utils/ArrayBufferView.hx b/src/lime/utils/ArrayBufferView.hx index 23ece48edb..8b25a82c79 100644 --- a/src/lime/utils/ArrayBufferView.hx +++ b/src/lime/utils/ArrayBufferView.hx @@ -2,8 +2,14 @@ package lime.utils; #if (js && !doc_gen) typedef ArrayBufferView = #if haxe4 js.lib.ArrayBufferView #else js.html.ArrayBufferView #end; -#else #if !lime_debug @:fileXml('tags="haxe,release"') -@:noDebug #end +#else +import lime.system.System; +import lime.system.Endian; + +#if !lime_debug +@:fileXml('tags="haxe,release"') +@:noDebug +#end class ArrayBufferView { public var type = TypedArrayType.None; @@ -132,7 +138,20 @@ class ArrayBufferView { if (view != null && array == null) { - buffer.blit(toByteLength(offset), view.buffer, view.byteOffset, view.byteLength); + if (offset + view.length > this.length) { + throw TAError.RangeError; + } + if (bytesPerElement == view.bytesPerElement) + { + buffer.blit(toByteLength(offset), view.buffer, view.byteOffset, view.byteLength); + } + else + { + for (i in 0...view.length) + { + transferElement(view, i, this, offset + i); + } + } } else if (array != null && view == null) { @@ -166,6 +185,8 @@ class ArrayBufferView { if (end == null) end = length; var len = end - begin; + if (len < 0) len = 0; + if (len > this.length) len = this.length; var byte_offset = toByteLength(begin) + byteOffset; var view:ArrayBufferView = switch (type) @@ -280,6 +301,10 @@ class ArrayBufferView // Ideally, native semantics could be used, like cpp.NativeArray.blit var i = 0, len = array.length; + if (offset + len > this.length) { + throw TAError.RangeError; + } + switch (type) { case Int8: @@ -392,6 +417,61 @@ class ArrayBufferView throw "copyFromArray on a base type ArrayBuffer"; } } + + static function transferElement(fromView:ArrayBufferView, fromIndex:Int, toView:ArrayBufferView, toIndex:Int):Void + { + var fromValue:Dynamic = null; + var fromPos = fromView.byteOffset + (fromIndex * fromView.bytesPerElement); + switch (fromView.type) + { + case Int8: + fromValue = ArrayBufferIO.getInt8(fromView.buffer, fromPos); + case Int16: + fromValue = ArrayBufferIO.getInt16(fromView.buffer, fromPos); + case Int32: + fromValue = ArrayBufferIO.getInt32(fromView.buffer, fromPos); + case Uint8: + fromValue = ArrayBufferIO.getUint8(fromView.buffer, fromPos); + case Uint16: + fromValue = ArrayBufferIO.getUint16(fromView.buffer, fromPos); + case Uint32: + fromValue = ArrayBufferIO.getUint32(fromView.buffer, fromPos); + case Uint8Clamped: + fromValue = ArrayBufferIO.getUint8(fromView.buffer, fromPos); + case Float32: + fromValue = ArrayBufferIO.getFloat32(fromView.buffer, fromPos); + case Float64: + fromValue = ArrayBufferIO.getFloat64(fromView.buffer, fromPos); + case None: + throw "transferElement on a base type ArrayBuffer"; + } + + var toPos = toView.byteOffset + (toIndex * toView.bytesPerElement); + switch (toView.type) + { + case Int8: + ArrayBufferIO.setInt8(toView.buffer, toPos, fromValue); + case Int16: + ArrayBufferIO.setInt16(toView.buffer, toPos, fromValue); + case Int32: + ArrayBufferIO.setInt32(toView.buffer, toPos, fromValue); + case Uint8: + ArrayBufferIO.setUint8(toView.buffer, toPos, fromValue); + case Uint16: + ArrayBufferIO.setUint16(toView.buffer, toPos, fromValue); + case Uint32: + ArrayBufferIO.setUint32(toView.buffer, toPos, fromValue); + case Uint8Clamped: + ArrayBufferIO.setUint8Clamped(toView.buffer, toPos, fromValue); + case Float32: + ArrayBufferIO.setFloat32(toView.buffer, toPos, fromValue); + case Float64: + ArrayBufferIO.setFloat64(toView.buffer, toPos, fromValue); + case None: + throw "transferElement on a base type ArrayBuffer"; + } + } + } // ArrayBufferView #end // !js @@ -426,7 +506,8 @@ abstract TypedArrayType(Int) from Int to Int public static function getInt8(buffer:ArrayBuffer, byteOffset:Int):Int { #if cpp - return untyped __global__.__hxcpp_memory_get_byte(buffer.getData(), byteOffset); + var val:Int = untyped __global__.__hxcpp_memory_get_byte(buffer.getData(), byteOffset) & 0xFF; + return ((val & 0x80) != 0) ? (val - 0x100) : val; #else var val:Int = buffer.get(byteOffset); return ((val & 0x80) != 0) ? (val - 0x100) : val; @@ -440,10 +521,10 @@ abstract TypedArrayType(Int) from Int to Int public static function setInt8(buffer:ArrayBuffer, byteOffset:Int, value:Int) { #if cpp - untyped __global__.__hxcpp_memory_set_byte(buffer.getData(), byteOffset, value); + untyped __global__.__hxcpp_memory_set_byte(buffer.getData(), byteOffset, value & 0xFF); #elseif neko if (value == null) value = 0; - untyped __dollar__sset(buffer.b, byteOffset, value & 0xff); + untyped __dollar__sset(buffer.b, byteOffset, value & 0xFF); #else buffer.set(byteOffset, value); #end @@ -456,7 +537,7 @@ abstract TypedArrayType(Int) from Int to Int public static function getUint8(buffer:ArrayBuffer, byteOffset:Int):Null { #if cpp - return untyped __global__.__hxcpp_memory_get_byte(buffer.getData(), byteOffset) & 0xff; + return untyped __global__.__hxcpp_memory_get_byte(buffer.getData(), byteOffset) & 0xFF; #else return buffer.get(byteOffset); #end @@ -478,7 +559,7 @@ abstract TypedArrayType(Int) from Int to Int public static function setUint8(buffer:ArrayBuffer, byteOffset:Int, value:UInt) { #if cpp - untyped __global__.__hxcpp_memory_set_byte(buffer.getData(), byteOffset, value); + untyped __global__.__hxcpp_memory_set_byte(buffer.getData(), byteOffset, value & 0xFF); #else #if neko if (value == null) value = 0; @@ -505,13 +586,15 @@ abstract TypedArrayType(Int) from Int to Int public static function getInt16_BE(buffer:ArrayBuffer, byteOffset:Int):Int { #if cpp - untyped return __global__.__hxcpp_memory_get_i16(buffer.getData(), byteOffset); + var bufferData = buffer.getData(); + var ch1:Int = untyped __global__.__hxcpp_memory_get_byte(bufferData, byteOffset) & 0xFF; + var ch2:Int = untyped __global__.__hxcpp_memory_get_byte(bufferData, byteOffset + 1) & 0xFF; + var val = ((ch1 << 8) | ch2); + return ((val & 0x8000) != 0) ? (val - 0x10000) : (val); #else var ch1 = buffer.get(byteOffset); var ch2 = buffer.get(byteOffset + 1); - var val = ((ch1 << 8) | ch2); - return ((val & 0x8000) != 0) ? (val - 0x10000) : (val); #end } @@ -523,26 +606,28 @@ abstract TypedArrayType(Int) from Int to Int #elseif neko if (value == null) value = 0; untyped var b = buffer.b; - untyped __dollar__sset(b, byteOffset, (value) & 0xff); - untyped __dollar__sset(b, byteOffset + 1, (value >> 8) & 0xff); + untyped __dollar__sset(b, byteOffset, (value) & 0xFF); + untyped __dollar__sset(b, byteOffset + 1, (value >> 8) & 0xFF); #else - buffer.set(byteOffset, (value) & 0xff); - buffer.set(byteOffset + 1, (value >> 8) & 0xff); + buffer.set(byteOffset, (value) & 0xFF); + buffer.set(byteOffset + 1, (value >> 8) & 0xFF); #end } public static function setInt16_BE(buffer:ArrayBuffer, byteOffset:Int, value:Int) { #if cpp - untyped __global__.__hxcpp_memory_set_i16(buffer.getData(), byteOffset, value); + var bufferData = buffer.getData(); + untyped __global__.__hxcpp_memory_set_byte(bufferData, byteOffset, (value >> 8) & 0xFF); + untyped __global__.__hxcpp_memory_set_byte(bufferData, byteOffset + 1, value & 0xFF); #elseif neko if (value == null) value = 0; untyped var b = buffer.b; - untyped __dollar__sset(b, byteOffset, (value >> 8) & 0xff); - untyped __dollar__sset(b, byteOffset + 1, (value) & 0xff); + untyped __dollar__sset(b, byteOffset, (value >> 8) & 0xFF); + untyped __dollar__sset(b, byteOffset + 1, (value) & 0xFF); #else - buffer.set(byteOffset, (value >> 8) & 0xff); - buffer.set(byteOffset + 1, (value) & 0xff); + buffer.set(byteOffset, (value >> 8) & 0xFF); + buffer.set(byteOffset + 1, (value) & 0xFF); #end } // setInt16_BE @@ -553,7 +638,7 @@ abstract TypedArrayType(Int) from Int to Int public static function getUint16(buffer:ArrayBuffer, byteOffset:Int):Null { #if cpp - untyped return __global__.__hxcpp_memory_get_ui16(buffer.getData(), byteOffset) & 0xffff; + untyped return __global__.__hxcpp_memory_get_ui16(buffer.getData(), byteOffset) & 0xFFFF; #else var ch1 = buffer.get(byteOffset); var ch2 = buffer.get(byteOffset + 1); @@ -569,11 +654,13 @@ abstract TypedArrayType(Int) from Int to Int public static function getUint16_BE(buffer:ArrayBuffer, byteOffset:Int):Null { #if cpp - untyped return __global__.__hxcpp_memory_get_ui16(buffer.getData(), byteOffset) & 0xffff; + var bufferData = buffer.getData(); + var ch1:Int = untyped __global__.__hxcpp_memory_get_byte(bufferData, byteOffset) & 0xFF; + var ch2:Int = untyped __global__.__hxcpp_memory_get_byte(bufferData, byteOffset + 1) & 0xFF; + return ((ch1 << 8) | ch2); #else var ch1 = buffer.get(byteOffset); var ch2 = buffer.get(byteOffset + 1); - return ((ch1 << 8) | ch2); #end } @@ -598,10 +685,17 @@ abstract TypedArrayType(Int) from Int to Int public static function setUint16_BE(buffer:ArrayBuffer, byteOffset:Int, value:UInt) { #if cpp - // :todo: Big endian ui16 - untyped __global__.__hxcpp_memory_set_ui16(buffer.getData(), byteOffset, value); + var bufferData = buffer.getData(); + untyped __global__.__hxcpp_memory_set_byte(bufferData, byteOffset, (value >> 8) & 0xFF); + untyped __global__.__hxcpp_memory_set_byte(bufferData, byteOffset + 1, value & 0xFF); + #elseif neko + if (value == null) value = 0; + untyped var b = buffer.b; + untyped __dollar__sset(b, byteOffset, (value >> 8) & 0xFF); + untyped __dollar__sset(b, byteOffset + 1, (value) & 0xFF); #else - setInt16_BE(buffer, byteOffset, value); + buffer.set(byteOffset, (value >> 8) & 0xFF); + buffer.set(byteOffset + 1, (value) & 0xFF); #end } @@ -626,9 +720,18 @@ abstract TypedArrayType(Int) from Int to Int public static function getInt32_BE(buffer:ArrayBuffer, byteOffset:Int):Int { #if cpp - untyped return __global__.__hxcpp_memory_get_i32(buffer.getData(), byteOffset); + var bufferData = buffer.getData(); + var ch1:Int = untyped __global__.__hxcpp_memory_get_byte(bufferData, byteOffset) & 0xFF; + var ch2:Int = untyped __global__.__hxcpp_memory_get_byte(bufferData, byteOffset + 1) & 0xFF; + var ch3:Int = untyped __global__.__hxcpp_memory_get_byte(bufferData, byteOffset + 2) & 0xFF; + var ch4:Int = untyped __global__.__hxcpp_memory_get_byte(bufferData, byteOffset + 3) & 0xFF; + return (ch1 << 24) | (ch2 << 16) | (ch3 << 8) | ch4; #else - return buffer.getInt32(byteOffset); + var ch1 = buffer.get(byteOffset); + var ch2 = buffer.get(byteOffset + 1); + var ch3 = buffer.get(byteOffset + 2); + var ch4 = buffer.get(byteOffset + 3); + return (ch1 << 24) | (ch2 << 16) | (ch3 << 8) | ch4; #end } @@ -656,13 +759,23 @@ abstract TypedArrayType(Int) from Int to Int public static function setInt32_BE(buffer:ArrayBuffer, byteOffset:Int, value:Int) { #if cpp - untyped __global__.__hxcpp_memory_set_i32(buffer.getData(), byteOffset, value); - #else - #if neko + var bufferData = buffer.getData(); + untyped __global__.__hxcpp_memory_set_byte(bufferData, byteOffset, (value >> 24) & 0xFF); + untyped __global__.__hxcpp_memory_set_byte(bufferData, byteOffset + 1, (value >> 16) & 0xFF); + untyped __global__.__hxcpp_memory_set_byte(bufferData, byteOffset + 2, (value >> 8) & 0xFF); + untyped __global__.__hxcpp_memory_set_byte(bufferData, byteOffset + 3, value & 0xFF); + #elseif neko if (value == null) value = 0; - #end - - buffer.setInt32(byteOffset, value); + untyped var b = buffer.b; + untyped __dollar__sset(b, byteOffset, (value >> 24) & 0xFF); + untyped __dollar__sset(b, byteOffset + 1, (value >> 16) & 0xFF); + untyped __dollar__sset(b, byteOffset + 2, (value >> 8) & 0xFF); + untyped __dollar__sset(b, byteOffset + 3, value & 0xFF); + #else + buffer.set(byteOffset, (value >> 24) & 0xFF); + buffer.set(byteOffset + 1, (value >> 16) & 0xFF); + buffer.set(byteOffset + 2, (value >> 8) & 0xFF); + buffer.set(byteOffset + 3, value & 0xFF); #end } @@ -675,7 +788,11 @@ abstract TypedArrayType(Int) from Int to Int #if cpp untyped return __global__.__hxcpp_memory_get_ui32(buffer.getData(), byteOffset); #else - return getInt32(buffer, byteOffset); + var ch1:Int = buffer.get(byteOffset); + var ch2:Int = buffer.get(byteOffset + 1); + var ch3:Int = buffer.get(byteOffset + 2); + var ch4:Int = buffer.get(byteOffset + 3); + return ch1 | (ch2 << 8) | (ch3 << 16) | (ch4 << 24); #end } @@ -686,9 +803,18 @@ abstract TypedArrayType(Int) from Int to Int public static function getUint32_BE(buffer:ArrayBuffer, byteOffset:Int):Null { #if cpp - untyped return __global__.__hxcpp_memory_get_ui32(buffer.getData(), byteOffset); + var bufferData = buffer.getData(); + var ch1:Int = untyped __global__.__hxcpp_memory_get_byte(bufferData, byteOffset) & 0xFF; + var ch2:Int = untyped __global__.__hxcpp_memory_get_byte(bufferData, byteOffset + 1) & 0xFF; + var ch3:Int = untyped __global__.__hxcpp_memory_get_byte(bufferData, byteOffset + 2) & 0xFF; + var ch4:Int = untyped __global__.__hxcpp_memory_get_byte(bufferData, byteOffset + 3) & 0xFF; + return (ch1 << 24) | (ch2 << 16) | (ch3 << 8) | ch4; #else - return getInt32_BE(buffer, byteOffset); + var ch1 = buffer.get(byteOffset); + var ch2 = buffer.get(byteOffset + 1); + var ch3 = buffer.get(byteOffset + 2); + var ch4 = buffer.get(byteOffset + 3); + return (ch1 << 24) | (ch2 << 16) | (ch3 << 8) | ch4; #end } @@ -709,12 +835,26 @@ abstract TypedArrayType(Int) from Int to Int #if (haxe_ver >= 4.0) extern #else @:extern #end inline #end - public static function setUint32_BE(buffer:ArrayBuffer, byteOffset:Int, value:UInt) + public static function setUint32_BE(buffer:ArrayBuffer, byteOffset:Int, value:UInt):Void { #if cpp - untyped __global__.__hxcpp_memory_set_ui32(buffer.getData(), byteOffset, value); + var bufferData = buffer.getData(); + untyped __global__.__hxcpp_memory_set_byte(bufferData, byteOffset, (value >> 24) & 0xFF); + untyped __global__.__hxcpp_memory_set_byte(bufferData, byteOffset + 1, (value >> 16) & 0xFF); + untyped __global__.__hxcpp_memory_set_byte(bufferData, byteOffset + 2, (value >> 8) & 0xFF); + untyped __global__.__hxcpp_memory_set_byte(bufferData, byteOffset + 3, value & 0xFF); + #elseif neko + if (value == null) value = 0; + untyped var b = buffer.b; + untyped __dollar__sset(b, byteOffset, (value >> 24) & 0xFF); + untyped __dollar__sset(b, byteOffset + 1, (value >> 16) & 0xFF); + untyped __dollar__sset(b, byteOffset + 2, (value >> 8) & 0xFF); + untyped __dollar__sset(b, byteOffset + 3, value & 0xFF); #else - setInt32_BE(buffer, byteOffset, value); + buffer.set(byteOffset, (value >> 24) & 0xFF); + buffer.set(byteOffset + 1, (value >> 16) & 0xFF); + buffer.set(byteOffset + 2, (value >> 8) & 0xFF); + buffer.set(byteOffset + 3, value & 0xFF); #end } diff --git a/src/lime/utils/Bytes.hx b/src/lime/utils/Bytes.hx index ba0bf9013d..285a8cfca4 100644 --- a/src/lime/utils/Bytes.hx +++ b/src/lime/utils/Bytes.hx @@ -20,6 +20,8 @@ abstract Bytes(HaxeBytes) from HaxeBytes to HaxeBytes { #if js this = new HaxeBytes(bytesData); + // bytesData may have extra bytes. See https://github.com/HaxeFoundation/haxe/issues/8974 + this.length = length; #elseif hl this = new HaxeBytes(bytesData, length); #else diff --git a/templates/android/template/app/src/main/java/org/libsdl/app/SDLActivity.java b/templates/android/template/app/src/main/java/org/libsdl/app/SDLActivity.java index 8cb0679935..73a77ce1a4 100644 --- a/templates/android/template/app/src/main/java/org/libsdl/app/SDLActivity.java +++ b/templates/android/template/app/src/main/java/org/libsdl/app/SDLActivity.java @@ -2005,16 +2005,14 @@ public boolean setComposingText(CharSequence text, int newCursorPosition) { @Override public boolean deleteSurroundingText(int beforeLength, int afterLength) { - if (Build.VERSION.SDK_INT <= 29 /* Android 10.0 (Q) */) { - // Workaround to capture backspace key. Ref: http://stackoverflow.com/questions>/14560344/android-backspace-in-webview-baseinputconnection - // and https://bugzilla.libsdl.org/show_bug.cgi?id=2265 - if (beforeLength > 0 && afterLength == 0) { - // backspace(s) - while (beforeLength-- > 0) { - nativeGenerateScancodeForUnichar('\b'); - } - return true; - } + // Workaround to capture backspace key. Ref: http://stackoverflow.com/questions>/14560344/android-backspace-in-webview-baseinputconnection + // and https://bugzilla.libsdl.org/show_bug.cgi?id=2265 + if (beforeLength > 0 && afterLength == 0) { + // backspace(s) + while (beforeLength-- > 0) { + nativeGenerateScancodeForUnichar('\b'); + } + return true; } if (!super.deleteSurroundingText(beforeLength, afterLength)) { diff --git a/templates/haxe/ApplicationMain.hx b/templates/haxe/ApplicationMain.hx index 422fbcb030..96093a5059 100644 --- a/templates/haxe/ApplicationMain.hx +++ b/templates/haxe/ApplicationMain.hx @@ -63,7 +63,8 @@ import ::APP_MAIN::; hardware: ::hardware::, stencil: ::stencilBuffer::, type: null, - vsync: ::vsync:: + vsync: ::vsync::::if vsyncMode::, + vsyncMode: "::vsyncMode::"::end:: }; if (app.window == null) diff --git a/tests/unit/project.xml b/tests/unit/project.xml new file mode 100644 index 0000000000..b718c22131 --- /dev/null +++ b/tests/unit/project.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + +