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 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/unit/src/TestMain.hx b/tests/unit/src/TestMain.hx
new file mode 100644
index 0000000000..6978eb8d6c
--- /dev/null
+++ b/tests/unit/src/TestMain.hx
@@ -0,0 +1,18 @@
+import utest.Runner;
+import utest.ui.Report;
+import lime.app.Application;
+
+class TestMain extends Application {
+ public function new() {
+ super();
+
+ var runner = new Runner();
+ runner.addCase(new utils.ArrayBufferTest());
+ runner.addCase(new utils.UInt8ArrayTest());
+ runner.addCase(new utils.UInt16ArrayTest());
+ runner.addCase(new utils.UInt32ArrayTest());
+ runner.addCase(new utils.DataViewTest());
+ Report.create(runner);
+ runner.run();
+ }
+}
\ No newline at end of file
diff --git a/tests/unit/src/utils/ArrayBufferTest.hx b/tests/unit/src/utils/ArrayBufferTest.hx
new file mode 100644
index 0000000000..32dda5e2cf
--- /dev/null
+++ b/tests/unit/src/utils/ArrayBufferTest.hx
@@ -0,0 +1,69 @@
+package utils;
+
+import lime.utils.UInt8Array;
+import lime.utils.DataView;
+import lime.utils.ArrayBuffer;
+import utest.Assert;
+import utest.Test;
+
+class ArrayBufferTest extends Test {
+ public function new() {
+ super();
+ }
+
+ public function testByteLength():Void {
+ var buffer = new ArrayBuffer(4);
+ Assert.equals(4, buffer.byteLength);
+ }
+
+ public function testSubarray():Void {
+ var buffer = new ArrayBuffer(4);
+ var array = new UInt8Array(buffer);
+ array[0] = 0xca;
+ array[1] = 0xfe;
+ array[2] = 0xba;
+ array[3] = 0xbe;
+
+ var fourBuffer = buffer.slice(0, 4);
+ Assert.equals(4, fourBuffer.byteLength);
+ var fourArray = new UInt8Array(fourBuffer);
+ Assert.equals(4, fourArray.byteLength);
+ Assert.equals(0xca, fourArray[0]);
+ Assert.equals(0xfe, fourArray[1]);
+ Assert.equals(0xba, fourArray[2]);
+ Assert.equals(0xbe, fourArray[3]);
+
+ var twoStartBuffer = buffer.slice(0, 2);
+ Assert.equals(2, twoStartBuffer.byteLength);
+ var twoStartArray = new UInt8Array(twoStartBuffer);
+ Assert.equals(2, twoStartArray.byteLength);
+ Assert.equals(0xca, twoStartArray[0]);
+ Assert.equals(0xfe, twoStartArray[1]);
+
+ var twoEndBuffer = buffer.slice(2, 4);
+ Assert.equals(2, twoEndBuffer.byteLength);
+ var twoEndArray = new UInt8Array(twoEndBuffer);
+ Assert.equals(2, twoEndArray.byteLength);
+ Assert.equals(0xba, twoEndArray[0]);
+ Assert.equals(0xbe, twoEndArray[1]);
+
+ var endBeforeStartBuffer = buffer.slice(2, 1);
+ Assert.equals(0, endBeforeStartBuffer.byteLength);
+ var endBeforeStartArray = new UInt8Array(endBeforeStartBuffer);
+ Assert.equals(0, endBeforeStartArray.byteLength);
+
+ var endEqualsStartBuffer = buffer.slice(2, 2);
+ Assert.equals(0, endEqualsStartBuffer.byteLength);
+ var endEqualsStartArray = new UInt8Array(endEqualsStartBuffer);
+ Assert.equals(0, endEqualsStartArray.byteLength);
+
+ var beyondLengthBuffer = buffer.slice(0, 400);
+ Assert.equals(4, beyondLengthBuffer.byteLength);
+ var beyondLengthArray = new UInt8Array(beyondLengthBuffer);
+ Assert.equals(4, beyondLengthArray.byteLength);
+ Assert.equals(0xca, beyondLengthArray[0]);
+ Assert.equals(0xfe, beyondLengthArray[1]);
+ Assert.equals(0xba, beyondLengthArray[2]);
+ Assert.equals(0xbe, beyondLengthArray[3]);
+ }
+}
\ No newline at end of file
diff --git a/tests/unit/src/utils/DataViewTest.hx b/tests/unit/src/utils/DataViewTest.hx
new file mode 100644
index 0000000000..3fb397dfa2
--- /dev/null
+++ b/tests/unit/src/utils/DataViewTest.hx
@@ -0,0 +1,311 @@
+package utils;
+
+import haxe.Int64;
+import lime.utils.DataView;
+import lime.utils.ArrayBuffer;
+import utest.Assert;
+import utest.Test;
+
+class DataViewTest extends Test {
+ public function new() {
+ super();
+ }
+
+ public function testInt8():Void {
+ var values:Array = [0, 1, 2, 127, 128, 255, -1, -2, -128, -129];
+ var result:Array = [0, 1, 2, 127, -128, -1, -1, -2, -128, 127];
+ Assert.equals(values.length, result.length);
+ var count = values.length;
+ var buffer = new ArrayBuffer(count);
+ var dataView = new DataView(buffer);
+ for (i in 0...count) {
+ var value = values[i];
+ dataView.setInt8(i, value);
+ }
+ for (i in 0...count) {
+ var value = dataView.getInt8(i);
+ var expected = result[i];
+ Assert.equals(expected, value, 'Int8: expected $expected but got $value at index $i');
+ }
+ }
+
+ public function testUint8():Void {
+ var values:Array = [0, 1, 2, 255, 256, -1, -2, -255];
+ var result:Array = [0, 1, 2, 255, 0, 255, 254, 1];
+ Assert.equals(values.length, result.length);
+ var count = values.length;
+ var buffer = new ArrayBuffer(count);
+ var dataView = new DataView(buffer);
+ for (i in 0...count) {
+ var value = values[i];
+ dataView.setUint8(i, value);
+ }
+ for (i in 0...count) {
+ var value = dataView.getUint8(i);
+ var expected = result[i];
+ Assert.equals(expected, value, 'Uint8: expected $expected but got $value at index $i');
+ }
+ }
+
+ public function testInt16():Void {
+ var values:Array = [0, 1, 2, 32767, 32768, 65535, -1, -2, -32768, -32769];
+ var result:Array = [0, 1, 2, 32767, -32768, -1, -1, -2, -32768, 32767];
+ var resultBytesLE:Array> = [
+ [0x00, 0x00],
+ [0x01, 0x00],
+ [0x02, 0x00],
+ [0xff, 0x7f],
+ [0x00, 0x80],
+ [0xff, 0xff],
+ [0xff, 0xff],
+ [0xfe, 0xff],
+ [0x00, 0x80],
+ [0xff, 0x7f]
+ ];
+ Assert.equals(values.length, result.length);
+ Assert.equals(values.length, resultBytesLE.length);
+ var count = values.length;
+ var buffer = new ArrayBuffer(count * 2);
+ var dataView = new DataView(buffer);
+
+ // little endian
+ for (i in 0...count) {
+ var byteIndex = i * 2;
+ var value = values[i];
+ dataView.setInt16(byteIndex, value);
+ }
+ for (i in 0...count) {
+ var byteIndex = i * 2;
+ var value = dataView.getInt16(byteIndex);
+ var expected = result[i];
+ Assert.equals(expected, value, 'Int16 little endian: expected $expected but got $value at index $i');
+ var valueBytes = [
+ dataView.getUint8(byteIndex),
+ dataView.getUint8(byteIndex + 1)
+ ];
+ var expectedBytesLE = resultBytesLE[i];
+ Assert.equals(2, expectedBytesLE.length);
+ Assert.equals(expectedBytesLE[0], valueBytes[0], 'Int16 little endian: expected byte 0 to be ${StringTools.hex(expectedBytesLE[0])} but got ${StringTools.hex(valueBytes[0])} at index $i');
+ Assert.equals(expectedBytesLE[1], valueBytes[1], 'Int16 little endian: expected byte 1 to be ${StringTools.hex(expectedBytesLE[1])} but got ${StringTools.hex(valueBytes[1])} at index $i');
+ }
+
+ // big endian
+ for (i in 0...count) {
+ var byteIndex = i * 2;
+ var value = values[i];
+ dataView.setInt16(byteIndex, value, false);
+ }
+ for (i in 0...count) {
+ var byteIndex = i * 2;
+ var value = dataView.getInt16(byteIndex, false);
+ var expected = result[i];
+ Assert.equals(expected, value, 'Int16 big endian: expected $expected but got $value at index $i');
+ var valueBytes = [
+ dataView.getUint8(byteIndex),
+ dataView.getUint8(byteIndex + 1)
+ ];
+ var expectedBytesBE = resultBytesLE[i].copy();
+ expectedBytesBE.reverse(); // big endian is little endian reversed
+ Assert.equals(2, expectedBytesBE.length);
+ Assert.equals(expectedBytesBE[0], valueBytes[0], 'Int16 big endian: expected byte 0 to be ${StringTools.hex(expectedBytesBE[0])} but got ${StringTools.hex(valueBytes[0])} at index $i');
+ Assert.equals(expectedBytesBE[1], valueBytes[1], 'Int16 big endian: expected byte 1 to be ${StringTools.hex(expectedBytesBE[1])} but got ${StringTools.hex(valueBytes[1])} at index $i');
+ }
+ }
+
+ public function testUint16():Void {
+ var values:Array = [0, 1, 2, 65535, 65536, -1, -2, -65535];
+ var result:Array = [0, 1, 2, 65535, 0, 65535, 65534, 1];
+ var resultBytesLE:Array> = [
+ [0x00, 0x00],
+ [0x01, 0x00],
+ [0x02, 0x00],
+ [0xff, 0xff],
+ [0x00, 0x00],
+ [0xff, 0xff],
+ [0xfe, 0xff],
+ [0x01, 0x00]
+ ];
+ Assert.equals(values.length, result.length);
+ Assert.equals(values.length, resultBytesLE.length);
+ var count = values.length;
+ var buffer = new ArrayBuffer(count * 2);
+ var dataView = new DataView(buffer);
+
+ // little endian
+ for (i in 0...count) {
+ var byteIndex = i * 2;
+ var value = values[i];
+ dataView.setUint16(byteIndex, value);
+ }
+ for (i in 0...count) {
+ var byteIndex = i * 2;
+ var value = dataView.getUint16(byteIndex);
+ var expected = result[i];
+ Assert.equals(expected, value, 'Uint16 little endian: expected $expected but got $value at index $i');
+ var valueBytes = [
+ dataView.getUint8(byteIndex),
+ dataView.getUint8(byteIndex + 1)
+ ];
+ var expectedBytesLE = resultBytesLE[i];
+ Assert.equals(2, expectedBytesLE.length);
+ Assert.equals(expectedBytesLE[0], valueBytes[0], 'Uint16 little endian: expected byte 0 to be ${StringTools.hex(expectedBytesLE[0])} but got ${StringTools.hex(valueBytes[0])} at index $i');
+ Assert.equals(expectedBytesLE[1], valueBytes[1], 'Uint16 little endian: expected byte 1 to be ${StringTools.hex(expectedBytesLE[1])} but got ${StringTools.hex(valueBytes[1])} at index $i');
+ }
+
+ // big endian
+ for (i in 0...count) {
+ var byteIndex = i * 2;
+ var value = values[i];
+ dataView.setUint16(byteIndex, value, false);
+ }
+ for (i in 0...count) {
+ var byteIndex = i * 2;
+ var value = dataView.getUint16(byteIndex, false);
+ var expected = result[i];
+ Assert.equals(expected, value, 'Uint16 big endian: expected $expected but got $value at index $i');
+ var valueBytes = [
+ dataView.getUint8(byteIndex),
+ dataView.getUint8(byteIndex + 1)
+ ];
+ var expectedBytesBE = resultBytesLE[i].copy();
+ expectedBytesBE.reverse(); // big endian is little endian reversed
+ Assert.equals(2, expectedBytesBE.length);
+ Assert.equals(expectedBytesBE[0], valueBytes[0], 'Uint16 big endian: expected byte 0 to be ${StringTools.hex(expectedBytesBE[0])} but got ${StringTools.hex(valueBytes[0])} at index $i');
+ Assert.equals(expectedBytesBE[1], valueBytes[1], 'Uint16 big endian: expected byte 1 to be ${StringTools.hex(expectedBytesBE[1])} but got ${StringTools.hex(valueBytes[1])} at index $i');
+ }
+ }
+
+ public function testInt32():Void {
+ var values:Array = [0, 1, 2, 2147483647, -1, -2, -2147483648];
+ var result:Array = [0, 1, 2, 2147483647, -1, -2, -2147483648];
+ var resultBytesLE:Array> = [
+ [0x00, 0x00, 0x00, 0x00],
+ [0x01, 0x00, 0x00, 0x00],
+ [0x02, 0x00, 0x00, 0x00],
+ [0xff, 0xff, 0xff, 0x7f],
+ [0xff, 0xff, 0xff, 0xff],
+ [0xfe, 0xff, 0xff, 0xff],
+ [0x00, 0x00, 0x00, 0x80]
+ ];
+ Assert.equals(values.length, result.length);
+ Assert.equals(values.length, resultBytesLE.length);
+ var count = values.length;
+ var buffer = new ArrayBuffer(count * 4);
+ var dataView = new DataView(buffer);
+
+ // little endian
+ for (i in 0...count) {
+ var byteIndex = i * 4;
+ var value = values[i];
+ dataView.setInt32(byteIndex, value);
+ }
+ for (i in 0...count) {
+ var byteIndex = i * 4;
+ var value = dataView.getInt32(byteIndex);
+ var expected = result[i];
+ Assert.equals(expected, value, 'Int32 little endian: expected $expected but got $value at index $i');
+
+ var valueBytes = [
+ dataView.getUint8(byteIndex),
+ dataView.getUint8(byteIndex + 1),
+ dataView.getUint8(byteIndex + 2),
+ dataView.getUint8(byteIndex + 3)
+ ];
+ var expectedBytesLE = resultBytesLE[i];
+ Assert.equals(4, expectedBytesLE.length);
+ Assert.equals(expectedBytesLE[0], valueBytes[0], 'Int32 little endian: expected byte 0 to be ${StringTools.hex(expectedBytesLE[0])} but got ${StringTools.hex(valueBytes[0])} at index $i');
+ Assert.equals(expectedBytesLE[1], valueBytes[1], 'Int32 little endian: expected byte 1 to be ${StringTools.hex(expectedBytesLE[1])} but got ${StringTools.hex(valueBytes[1])} at index $i');
+ Assert.equals(expectedBytesLE[2], valueBytes[2], 'Int32 little endian: expected byte 2 to be ${StringTools.hex(expectedBytesLE[2])} but got ${StringTools.hex(valueBytes[2])} at index $i');
+ Assert.equals(expectedBytesLE[3], valueBytes[3], 'Int32 little endian: expected byte 3 to be ${StringTools.hex(expectedBytesLE[3])} but got ${StringTools.hex(valueBytes[3])} at index $i');
+ }
+
+ // big endian
+ for (i in 0...count) {
+ var byteIndex = i * 4;
+ var value = values[i];
+ dataView.setInt32(byteIndex, value, false);
+ }
+ for (i in 0...count) {
+ var byteIndex = i * 4;
+ var value = dataView.getInt32(byteIndex, false);
+ var expected = result[i];
+ Assert.equals(expected, value, 'Int32 big endian: expected $expected but got $value at index $i');
+
+ var valueBytes = [
+ dataView.getUint8(byteIndex),
+ dataView.getUint8(byteIndex + 1),
+ dataView.getUint8(byteIndex + 2),
+ dataView.getUint8(byteIndex + 3)
+ ];
+ var expectedBytesBE = resultBytesLE[i].copy();
+ expectedBytesBE.reverse(); // big endian is little endian reversed
+ Assert.equals(4, expectedBytesBE.length);
+ Assert.equals(expectedBytesBE[0], valueBytes[0], 'Int32 big endian: expected byte 0 to be ${StringTools.hex(expectedBytesBE[0])} but got ${StringTools.hex(valueBytes[0])} at index $i');
+ Assert.equals(expectedBytesBE[1], valueBytes[1], 'Int32 big endian: expected byte 1 to be ${StringTools.hex(expectedBytesBE[1])} but got ${StringTools.hex(valueBytes[1])} at index $i');
+ Assert.equals(expectedBytesBE[2], valueBytes[2], 'Int32 big endian: expected byte 2 to be ${StringTools.hex(expectedBytesBE[2])} but got ${StringTools.hex(valueBytes[2])} at index $i');
+ Assert.equals(expectedBytesBE[3], valueBytes[3], 'Int32 big endian: expected byte 3 to be ${StringTools.hex(expectedBytesBE[3])} but got ${StringTools.hex(valueBytes[3])} at index $i');
+ }
+ }
+
+ public function testUint32():Void {
+ var values:Array = [0, 1, 2, 0xffffffff, 0xdeadbeef, 0xcafebabe, 0xdecafbad];
+ var resultBytesLE:Array> = [
+ [0x00, 0x00, 0x00, 0x00],
+ [0x01, 0x00, 0x00, 0x00],
+ [0x02, 0x00, 0x00, 0x00],
+ [0xff, 0xff, 0xff, 0xff],
+ [0xef, 0xbe, 0xad, 0xde],
+ [0xbe, 0xba, 0xfe, 0xca],
+ [0xad, 0xfb, 0xca, 0xde]
+ ];
+ Assert.equals(values.length, resultBytesLE.length);
+ var count = values.length;
+ var buffer = new ArrayBuffer(count * 4);
+ var dataView = new DataView(buffer);
+
+ // little endian
+ for (i in 0...count) {
+ var byteIndex = i * 4;
+ var value = values[i];
+ dataView.setUint32(byteIndex, value);
+ }
+ for (i in 0...count) {
+ var byteIndex = i * 4;
+ var valueBytes = [
+ dataView.getUint8(byteIndex),
+ dataView.getUint8(byteIndex + 1),
+ dataView.getUint8(byteIndex + 2),
+ dataView.getUint8(byteIndex + 3)
+ ];
+ var expectedBytesLE = resultBytesLE[i];
+ Assert.equals(4, expectedBytesLE.length);
+ Assert.equals(expectedBytesLE[0], valueBytes[0], 'Uint32 little endian: expected byte 0 to be ${StringTools.hex(expectedBytesLE[0])} but got ${StringTools.hex(valueBytes[0])} at index $i');
+ Assert.equals(expectedBytesLE[1], valueBytes[1], 'Uint32 little endian: expected byte 1 to be ${StringTools.hex(expectedBytesLE[1])} but got ${StringTools.hex(valueBytes[1])} at index $i');
+ Assert.equals(expectedBytesLE[2], valueBytes[2], 'Uint32 little endian: expected byte 2 to be ${StringTools.hex(expectedBytesLE[2])} but got ${StringTools.hex(valueBytes[2])} at index $i');
+ Assert.equals(expectedBytesLE[3], valueBytes[3], 'Uint32 little endian: expected byte 3 to be ${StringTools.hex(expectedBytesLE[3])} but got ${StringTools.hex(valueBytes[3])} at index $i');
+ }
+
+ // big endian
+ for (i in 0...count) {
+ var byteIndex = i * 4;
+ var value = values[i];
+ dataView.setUint32(byteIndex, value, false);
+ }
+ for (i in 0...count) {
+ var byteIndex = i * 4;
+ var valueBytes = [
+ dataView.getUint8(byteIndex),
+ dataView.getUint8(byteIndex + 1),
+ dataView.getUint8(byteIndex + 2),
+ dataView.getUint8(byteIndex + 3)
+ ];
+ var expectedBytesBE = resultBytesLE[i].copy();
+ expectedBytesBE.reverse(); // big endian is little endian reversed
+ Assert.equals(4, expectedBytesBE.length);
+ Assert.equals(expectedBytesBE[0], valueBytes[0], 'Uint32 big endian: expected byte 0 to be ${StringTools.hex(expectedBytesBE[0])} but got ${StringTools.hex(valueBytes[0])} at index $i');
+ Assert.equals(expectedBytesBE[1], valueBytes[1], 'Uint32 big endian: expected byte 1 to be ${StringTools.hex(expectedBytesBE[1])} but got ${StringTools.hex(valueBytes[1])} at index $i');
+ Assert.equals(expectedBytesBE[2], valueBytes[2], 'Uint32 big endian: expected byte 2 to be ${StringTools.hex(expectedBytesBE[2])} but got ${StringTools.hex(valueBytes[2])} at index $i');
+ Assert.equals(expectedBytesBE[3], valueBytes[3], 'Uint32 big endian: expected byte 3 to be ${StringTools.hex(expectedBytesBE[3])} but got ${StringTools.hex(valueBytes[3])} at index $i');
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/unit/src/utils/UInt16ArrayTest.hx b/tests/unit/src/utils/UInt16ArrayTest.hx
new file mode 100644
index 0000000000..84200f99f4
--- /dev/null
+++ b/tests/unit/src/utils/UInt16ArrayTest.hx
@@ -0,0 +1,295 @@
+package utils;
+
+import lime.utils.UInt16Array;
+import lime.utils.UInt32Array;
+import lime.utils.UInt8Array;
+import lime.utils.ArrayBuffer;
+import utest.Assert;
+import utest.Test;
+
+class UInt16ArrayTest extends Test {
+ public function new() {
+ super();
+ }
+
+ public function testByteLength():Void {
+ var buffer = new ArrayBuffer(8);
+ var array = new UInt16Array(buffer);
+ Assert.equals(4, array.length);
+ Assert.equals(8, array.byteLength);
+ }
+
+ public function testValues():Void {
+ var buffer = new ArrayBuffer(8);
+ var array = new UInt16Array(buffer);
+ Assert.equals(0x0, array[0]);
+ Assert.equals(0x0, array[1]);
+ Assert.equals(0x0, array[2]);
+ Assert.equals(0x0, array[3]);
+ array[0] = 0xcafe;
+ array[1] = 0xbabe;
+ array[2] = 0xdeca;
+ array[3] = 0xfbad;
+ Assert.equals(0xcafe, array[0]);
+ Assert.equals(0xbabe, array[1]);
+ Assert.equals(0xdeca, array[2]);
+ Assert.equals(0xfbad, array[3]);
+ }
+
+ public function testSubarray():Void {
+ var buffer = new ArrayBuffer(8);
+ var array = new UInt16Array(buffer);
+ array[0] = 0xcafe;
+ array[1] = 0xbabe;
+ array[2] = 0xdeca;
+ array[3] = 0xfbad;
+
+ var four = array.subarray(0, 4);
+ Assert.equals(4, four.length);
+ Assert.equals(8, four.byteLength);
+ Assert.equals(0xcafe, four[0]);
+ Assert.equals(0xbabe, four[1]);
+ Assert.equals(0xdeca, four[2]);
+ Assert.equals(0xfbad, four[3]);
+
+ var twoStart = array.subarray(0, 2);
+ Assert.equals(2, twoStart.length);
+ Assert.equals(4, twoStart.byteLength);
+ Assert.equals(0xcafe, twoStart[0]);
+ Assert.equals(0xbabe, twoStart[1]);
+
+ var twoEnd = array.subarray(2, 4);
+ Assert.equals(2, twoEnd.length);
+ Assert.equals(4, twoEnd.byteLength);
+ Assert.equals(0xdeca, twoEnd[0]);
+ Assert.equals(0xfbad, twoEnd[1]);
+
+ var endBeforeStart = array.subarray(2, 1);
+ Assert.equals(0, endBeforeStart.length);
+ Assert.equals(0, endBeforeStart.byteLength);
+
+ var endEqualsStart = array.subarray(2, 2);
+ Assert.equals(0, endEqualsStart.length);
+ Assert.equals(0, endEqualsStart.byteLength);
+
+ var beyondLength = array.subarray(0, 400);
+ Assert.equals(4, beyondLength.length);
+ Assert.equals(8, beyondLength.byteLength);
+ Assert.equals(0xcafe, beyondLength[0]);
+ Assert.equals(0xbabe, beyondLength[1]);
+ Assert.equals(0xdeca, beyondLength[2]);
+ Assert.equals(0xfbad, beyondLength[3]);
+ }
+
+ public function testSetArrayOfInts():Void {
+ var array1:Array = [0xcafe, 0xbabe, 0xdeca, 0xfbad];
+
+ var buffer2 = new ArrayBuffer(16);
+ var array2 = new UInt16Array(buffer2);
+
+ array2.set(array1);
+ Assert.equals(0xcafe, array2[0]);
+ Assert.equals(0xbabe, array2[1]);
+ Assert.equals(0xdeca, array2[2]);
+ Assert.equals(0xfbad, array2[3]);
+ Assert.equals(0x0, array2[4]);
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+
+ for (i in 0...array2.length) {
+ array2[i] = 0x0;
+ }
+
+ array2.set(array1, 1);
+ Assert.equals(0x0, array2[0]);
+ Assert.equals(0xcafe, array2[1]);
+ Assert.equals(0xbabe, array2[2]);
+ Assert.equals(0xdeca, array2[3]);
+ Assert.equals(0xfbad, array2[4]);
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+
+ for (i in 0...array2.length) {
+ array2[i] = 0x0;
+ }
+
+ Assert.raises(function():Void {
+ array2.set(array1, 6);
+ });
+ Assert.equals(0x0, array2[0]);
+ Assert.equals(0x0, array2[1]);
+ Assert.equals(0x0, array2[2]);
+ Assert.equals(0x0, array2[3]);
+ Assert.equals(0x0, array2[4]);
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+ }
+
+ public function testSetUInt8Array():Void {
+ var buffer1 = new ArrayBuffer(4);
+ var array1 = new UInt8Array(buffer1);
+ array1[0] = 0xca;
+ array1[1] = 0xfe;
+ array1[2] = 0xba;
+ array1[3] = 0xbe;
+
+ var buffer2 = new ArrayBuffer(16);
+ var array2 = new UInt16Array(buffer2);
+
+ array2.set(array1);
+ Assert.equals(0xca, array2[0]);
+ Assert.equals(0xfe, array2[1]);
+ Assert.equals(0xba, array2[2]);
+ Assert.equals(0xbe, array2[3]);
+ Assert.equals(0x0, array2[4]);
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+
+ // reset the array to all zeros
+ for (i in 0...array2.length) {
+ array2[i] = 0x0;
+ }
+
+ array2.set(array1, 1);
+ Assert.equals(0x0, array2[0]);
+ Assert.equals(0xca, array2[1]);
+ Assert.equals(0xfe, array2[2]);
+ Assert.equals(0xba, array2[3]);
+ Assert.equals(0xbe, array2[4]);
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+
+ for (i in 0...array2.length) {
+ array2[i] = 0x0;
+ }
+
+ // if the array can't fit, it throws
+ Assert.raises(function():Void {
+ array2.set(array1, 6);
+ });
+ // in that case, none of the values should have been updated
+ Assert.equals(0x0, array2[0]);
+ Assert.equals(0x0, array2[1]);
+ Assert.equals(0x0, array2[2]);
+ Assert.equals(0x0, array2[3]);
+ Assert.equals(0x0, array2[4]);
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+ }
+
+ public function testSetUInt16Array():Void {
+ var buffer1 = new ArrayBuffer(8);
+ var array1 = new UInt16Array(buffer1);
+ array1[0] = 0xcafe;
+ array1[1] = 0xbabe;
+ array1[2] = 0xdeca;
+ array1[3] = 0xfbad;
+
+ var buffer2 = new ArrayBuffer(16);
+ var array2 = new UInt16Array(buffer2);
+
+ array2.set(array1);
+ Assert.equals(0xcafe, array2[0]);
+ Assert.equals(0xbabe, array2[1]);
+ Assert.equals(0xdeca, array2[2]);
+ Assert.equals(0xfbad, array2[3]);
+ Assert.equals(0x0, array2[4]);
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+
+ // reset the array to all zeros
+ for (i in 0...array2.length) {
+ array2[i] = 0x0;
+ }
+
+ array2.set(array1, 1);
+ Assert.equals(0x0, array2[0]);
+ Assert.equals(0xcafe, array2[1]);
+ Assert.equals(0xbabe, array2[2]);
+ Assert.equals(0xdeca, array2[3]);
+ Assert.equals(0xfbad, array2[4]);
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+
+ for (i in 0...array2.length) {
+ array2[i] = 0x0;
+ }
+
+ // if the array can't fit, it throws
+ Assert.raises(function():Void {
+ array2.set(array1, 6);
+ });
+ // in that case, none of the values should have been updated
+ Assert.equals(0x0, array2[0]);
+ Assert.equals(0x0, array2[1]);
+ Assert.equals(0x0, array2[2]);
+ Assert.equals(0x0, array2[3]);
+ Assert.equals(0x0, array2[4]);
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+ }
+
+ public function testSetUInt32Array():Void {
+ var buffer1 = new ArrayBuffer(16);
+ var array1 = new UInt32Array(buffer1);
+ array1[0] = 0xcafebabe;
+ array1[1] = 0xdecafbad;
+ array1[2] = 0xffffffff;
+ array1[3] = 0xdeadbeef;
+
+ var buffer2 = new ArrayBuffer(16);
+ var array2 = new UInt16Array(buffer2);
+
+ array2.set(array1);
+ Assert.equals(0xbabe, array2[0]);
+ Assert.equals(0xfbad, array2[1]);
+ Assert.equals(0xffff, array2[2]);
+ Assert.equals(0xbeef, array2[3]);
+ Assert.equals(0x0, array2[4]);
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+
+ // reset the array to all zeros
+ for (i in 0...array2.length) {
+ array2[i] = 0x0;
+ }
+
+ array2.set(array1, 1);
+ Assert.equals(0x0, array2[0]);
+ Assert.equals(0xbabe, array2[1]);
+ Assert.equals(0xfbad, array2[2]);
+ Assert.equals(0xffff, array2[3]);
+ Assert.equals(0xbeef, array2[4]);
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+
+ for (i in 0...array2.length) {
+ array2[i] = 0x0;
+ }
+
+ // if the array can't fit, it throws
+ Assert.raises(function():Void {
+ array2.set(array1, 6);
+ });
+ // in that case, none of the values should have been updated
+ Assert.equals(0x0, array2[0]);
+ Assert.equals(0x0, array2[1]);
+ Assert.equals(0x0, array2[2]);
+ Assert.equals(0x0, array2[3]);
+ Assert.equals(0x0, array2[4]);
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+ }
+}
\ No newline at end of file
diff --git a/tests/unit/src/utils/UInt32ArrayTest.hx b/tests/unit/src/utils/UInt32ArrayTest.hx
new file mode 100644
index 0000000000..5e3c88a42a
--- /dev/null
+++ b/tests/unit/src/utils/UInt32ArrayTest.hx
@@ -0,0 +1,383 @@
+package utils;
+
+import lime.utils.UInt16Array;
+import lime.utils.UInt32Array;
+import lime.utils.UInt8Array;
+import lime.utils.ArrayBuffer;
+import utest.Assert;
+import utest.Test;
+
+class UInt32ArrayTest extends Test {
+ public function new() {
+ super();
+ }
+
+ public function testByteLength():Void {
+ var buffer = new ArrayBuffer(16);
+ var array = new UInt32Array(buffer);
+ Assert.equals(4, array.length);
+ Assert.equals(16, array.byteLength);
+ }
+
+ public function testValues():Void {
+ var buffer = new ArrayBuffer(16);
+ var array = new UInt32Array(buffer);
+ Assert.equals(0x0, array[0]);
+ Assert.equals(0x0, array[1]);
+ Assert.equals(0x0, array[2]);
+ Assert.equals(0x0, array[3]);
+
+ array[0] = 0xcafebabe;
+ array[1] = 0xdecafbad;
+ array[2] = 0xffffffff;
+ array[3] = 0xdeadbeef;
+ #if js
+ Assert.equals(untyped #if haxe4 js.Syntax.code #else __js__ #end ('0xcafebabe'), array[0]);
+ Assert.equals(untyped #if haxe4 js.Syntax.code #else __js__ #end ('0xdecafbad'), array[1]);
+ Assert.equals(untyped #if haxe4 js.Syntax.code #else __js__ #end ('0xffffffff'), array[2]);
+ Assert.equals(untyped #if haxe4 js.Syntax.code #else __js__ #end ('0xdeadbeef'), array[3]);
+ #else
+ Assert.equals(0xcafebabe, array[0]);
+ Assert.equals(0xdecafbad, array[1]);
+ Assert.equals(0xffffffff, array[2]);
+ Assert.equals(0xdeadbeef, array[3]);
+ #end
+ }
+
+ public function testSubarray():Void {
+ var buffer = new ArrayBuffer(16);
+ var array = new UInt32Array(buffer);
+ array[0] = 0xcafebabe;
+ array[1] = 0xdecafbad;
+ array[2] = 0xffffffff;
+ array[3] = 0xdeadbeef;
+
+ var four = array.subarray(0, 4);
+ Assert.equals(4, four.length);
+ Assert.equals(16, four.byteLength);
+ #if js
+ Assert.equals(untyped #if haxe4 js.Syntax.code #else __js__ #end ('0xcafebabe'), array[0]);
+ Assert.equals(untyped #if haxe4 js.Syntax.code #else __js__ #end ('0xdecafbad'), array[1]);
+ Assert.equals(untyped #if haxe4 js.Syntax.code #else __js__ #end ('0xffffffff'), array[2]);
+ Assert.equals(untyped #if haxe4 js.Syntax.code #else __js__ #end ('0xdeadbeef'), array[3]);
+ #else
+ Assert.equals(0xcafebabe, four[0]);
+ Assert.equals(0xdecafbad, four[1]);
+ Assert.equals(0xffffffff, four[2]);
+ Assert.equals(0xdeadbeef, four[3]);
+ #end
+
+ var twoStart = array.subarray(0, 2);
+ Assert.equals(2, twoStart.length);
+ Assert.equals(8, twoStart.byteLength);
+ #if js
+ Assert.equals(untyped #if haxe4 js.Syntax.code #else __js__ #end ('0xcafebabe'), twoStart[0]);
+ Assert.equals(untyped #if haxe4 js.Syntax.code #else __js__ #end ('0xdecafbad'), twoStart[1]);
+ #else
+ Assert.equals(0xcafebabe, twoStart[0]);
+ Assert.equals(0xdecafbad, twoStart[1]);
+ #end
+
+ var twoEnd = array.subarray(2, 4);
+ Assert.equals(2, twoEnd.length);
+ Assert.equals(8, twoEnd.byteLength);
+ #if js
+ Assert.equals(untyped #if haxe4 js.Syntax.code #else __js__ #end ('0xffffffff'), twoEnd[0]);
+ Assert.equals(untyped #if haxe4 js.Syntax.code #else __js__ #end ('0xdeadbeef'), twoEnd[1]);
+ #else
+ Assert.equals(0xffffffff, twoEnd[0]);
+ Assert.equals(0xdeadbeef, twoEnd[1]);
+ #end
+
+ var endBeforeStart = array.subarray(2, 1);
+ Assert.equals(0, endBeforeStart.length);
+ Assert.equals(0, endBeforeStart.byteLength);
+
+ var endEqualsStart = array.subarray(2, 2);
+ Assert.equals(0, endEqualsStart.length);
+ Assert.equals(0, endEqualsStart.byteLength);
+
+ var beyondLength = array.subarray(0, 400);
+ Assert.equals(4, beyondLength.length);
+ Assert.equals(16, beyondLength.byteLength);
+ #if js
+ Assert.equals(untyped #if haxe4 js.Syntax.code #else __js__ #end ('0xcafebabe'), array[0]);
+ Assert.equals(untyped #if haxe4 js.Syntax.code #else __js__ #end ('0xdecafbad'), array[1]);
+ Assert.equals(untyped #if haxe4 js.Syntax.code #else __js__ #end ('0xffffffff'), array[2]);
+ Assert.equals(untyped #if haxe4 js.Syntax.code #else __js__ #end ('0xdeadbeef'), array[3]);
+ #else
+ Assert.equals(0xcafebabe, beyondLength[0]);
+ Assert.equals(0xdecafbad, beyondLength[1]);
+ Assert.equals(0xffffffff, beyondLength[2]);
+ Assert.equals(0xdeadbeef, beyondLength[3]);
+ #end
+ }
+
+ public function testSetArrayOfInts():Void {
+ var array1:Array = [0xcafebabe, 0xdecafbad, 0xffffffff, 0xdeadbeef];
+
+ var buffer2 = new ArrayBuffer(32);
+ var array2 = new UInt32Array(buffer2);
+
+ array2.set(array1);
+ #if js
+ Assert.equals(untyped #if haxe4 js.Syntax.code #else __js__ #end ('0xcafebabe'), array2[0]);
+ Assert.equals(untyped #if haxe4 js.Syntax.code #else __js__ #end ('0xdecafbad'), array2[1]);
+ Assert.equals(untyped #if haxe4 js.Syntax.code #else __js__ #end ('0xffffffff'), array2[2]);
+ Assert.equals(untyped #if haxe4 js.Syntax.code #else __js__ #end ('0xdeadbeef'), array2[3]);
+ #else
+ Assert.equals(0xcafebabe, array2[0]);
+ Assert.equals(0xdecafbad, array2[1]);
+ Assert.equals(0xffffffff, array2[2]);
+ Assert.equals(0xdeadbeef, array2[3]);
+ #end
+ Assert.equals(0x0, array2[4]);
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+
+ for (i in 0...array2.length) {
+ array2[i] = 0x0;
+ }
+
+ array2.set(array1, 1);
+ Assert.equals(0x0, array2[0]);
+ #if js
+ Assert.equals(untyped #if haxe4 js.Syntax.code #else __js__ #end ('0xcafebabe'), array2[1]);
+ Assert.equals(untyped #if haxe4 js.Syntax.code #else __js__ #end ('0xdecafbad'), array2[2]);
+ Assert.equals(untyped #if haxe4 js.Syntax.code #else __js__ #end ('0xffffffff'), array2[3]);
+ Assert.equals(untyped #if haxe4 js.Syntax.code #else __js__ #end ('0xdeadbeef'), array2[4]);
+ #else
+ Assert.equals(0xcafebabe, array2[1]);
+ Assert.equals(0xdecafbad, array2[2]);
+ Assert.equals(0xffffffff, array2[3]);
+ Assert.equals(0xdeadbeef, array2[4]);
+ #end
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+ }
+
+ private function testSetArrayOfIntsRangeError():Void
+ {
+ var array1:Array = [0xcafebabe, 0xdecafbad, 0xffffffff, 0xdeadbeef];
+
+ var buffer2 = new ArrayBuffer(32);
+ var array2 = new UInt32Array(buffer2);
+
+ Assert.raises(function():Void {
+ array2.set(array1, 6);
+ });
+ Assert.equals(0x0, array2[0]);
+ Assert.equals(0x0, array2[1]);
+ Assert.equals(0x0, array2[2]);
+ Assert.equals(0x0, array2[3]);
+ Assert.equals(0x0, array2[4]);
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+ }
+
+ public function testSetUInt8Array():Void {
+ var buffer1 = new ArrayBuffer(4);
+ var array1 = new UInt8Array(buffer1);
+ array1[0] = 0xca;
+ array1[1] = 0xfe;
+ array1[2] = 0xba;
+ array1[3] = 0xbe;
+
+ var buffer2 = new ArrayBuffer(32);
+ var array2 = new UInt32Array(buffer2);
+
+ array2.set(array1);
+ Assert.equals(0xca, array2[0]);
+ Assert.equals(0xfe, array2[1]);
+ Assert.equals(0xba, array2[2]);
+ Assert.equals(0xbe, array2[3]);
+ Assert.equals(0x0, array2[4]);
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+
+ // reset the array to all zeros
+ for (i in 0...array2.length) {
+ array2[i] = 0x0;
+ }
+
+ array2.set(array1, 1);
+ Assert.equals(0x0, array2[0]);
+ Assert.equals(0xca, array2[1]);
+ Assert.equals(0xfe, array2[2]);
+ Assert.equals(0xba, array2[3]);
+ Assert.equals(0xbe, array2[4]);
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+ }
+
+ public function testSetUInt8ArrayRangeError():Void {
+ var buffer1 = new ArrayBuffer(4);
+ var array1 = new UInt8Array(buffer1);
+ array1[0] = 0xca;
+ array1[1] = 0xfe;
+ array1[2] = 0xba;
+ array1[3] = 0xbe;
+
+ var buffer2 = new ArrayBuffer(32);
+ var array2 = new UInt32Array(buffer2);
+
+ // if the array can't fit, it throws
+ Assert.raises(function():Void {
+ array2.set(array1, 6);
+ });
+ // in that case, none of the values should have been updated
+ Assert.equals(0x0, array2[0]);
+ Assert.equals(0x0, array2[1]);
+ Assert.equals(0x0, array2[2]);
+ Assert.equals(0x0, array2[3]);
+ Assert.equals(0x0, array2[4]);
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+ }
+
+ public function testSetUInt16Array():Void {
+ var buffer1 = new ArrayBuffer(8);
+ var array1 = new UInt16Array(buffer1);
+ array1[0] = 0xcafe;
+ array1[1] = 0xbabe;
+ array1[2] = 0xdeca;
+ array1[3] = 0xfbad;
+
+ var buffer2 = new ArrayBuffer(32);
+ var array2 = new UInt32Array(buffer2);
+
+ array2.set(array1);
+ Assert.equals(0xcafe, array2[0]);
+ Assert.equals(0xbabe, array2[1]);
+ Assert.equals(0xdeca, array2[2]);
+ Assert.equals(0xfbad, array2[3]);
+ Assert.equals(0x0, array2[4]);
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+
+ // reset the array to all zeros
+ for (i in 0...array2.length) {
+ array2[i] = 0x0;
+ }
+
+ array2.set(array1, 1);
+ Assert.equals(0x0, array2[0]);
+ Assert.equals(0xcafe, array2[1]);
+ Assert.equals(0xbabe, array2[2]);
+ Assert.equals(0xdeca, array2[3]);
+ Assert.equals(0xfbad, array2[4]);
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+ }
+
+ public function testSetUInt16ArrayRangeError():Void {
+ var buffer1 = new ArrayBuffer(8);
+ var array1 = new UInt16Array(buffer1);
+ array1[0] = 0xcafe;
+ array1[1] = 0xbabe;
+ array1[2] = 0xdeca;
+ array1[3] = 0xfbad;
+
+ var buffer2 = new ArrayBuffer(32);
+ var array2 = new UInt32Array(buffer2);
+
+ // if the array can't fit, it throws
+ Assert.raises(function():Void {
+ array2.set(array1, 6);
+ });
+ // in that case, none of the values should have been updated
+ Assert.equals(0x0, array2[0]);
+ Assert.equals(0x0, array2[1]);
+ Assert.equals(0x0, array2[2]);
+ Assert.equals(0x0, array2[3]);
+ Assert.equals(0x0, array2[4]);
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+ }
+
+ public function testSetUInt32Array():Void {
+ var buffer1 = new ArrayBuffer(16);
+ var array1 = new UInt32Array(buffer1);
+ array1[0] = 0xcafebabe;
+ array1[1] = 0xdecafbad;
+ array1[2] = 0xffffffff;
+ array1[3] = 0xdeadbeef;
+
+ var buffer2 = new ArrayBuffer(32);
+ var array2 = new UInt32Array(buffer2);
+
+ array2.set(array1);
+ #if js
+ Assert.equals(untyped #if haxe4 js.Syntax.code #else __js__ #end ('0xcafebabe'), array2[0]);
+ Assert.equals(untyped #if haxe4 js.Syntax.code #else __js__ #end ('0xdecafbad'), array2[1]);
+ Assert.equals(untyped #if haxe4 js.Syntax.code #else __js__ #end ('0xffffffff'), array2[2]);
+ Assert.equals(untyped #if haxe4 js.Syntax.code #else __js__ #end ('0xdeadbeef'), array2[3]);
+ #else
+ Assert.equals(0xcafebabe, array2[0]);
+ Assert.equals(0xdecafbad, array2[1]);
+ Assert.equals(0xffffffff, array2[2]);
+ Assert.equals(0xdeadbeef, array2[3]);
+ #end
+ Assert.equals(0x0, array2[4]);
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+
+ // reset the array to all zeros
+ for (i in 0...array2.length) {
+ array2[i] = 0x0;
+ }
+
+ array2.set(array1, 1);
+ Assert.equals(0x0, array2[0]);
+ #if js
+ Assert.equals(untyped #if haxe4 js.Syntax.code #else __js__ #end ('0xcafebabe'), array2[1]);
+ Assert.equals(untyped #if haxe4 js.Syntax.code #else __js__ #end ('0xdecafbad'), array2[2]);
+ Assert.equals(untyped #if haxe4 js.Syntax.code #else __js__ #end ('0xffffffff'), array2[3]);
+ Assert.equals(untyped #if haxe4 js.Syntax.code #else __js__ #end ('0xdeadbeef'), array2[4]);
+ #else
+ Assert.equals(0xcafebabe, array2[1]);
+ Assert.equals(0xdecafbad, array2[2]);
+ Assert.equals(0xffffffff, array2[3]);
+ Assert.equals(0xdeadbeef, array2[4]);
+ #end
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+ }
+
+ public function testSetUInt32ArrayRangeError():Void {
+ var buffer1 = new ArrayBuffer(16);
+ var array1 = new UInt32Array(buffer1);
+ array1[0] = 0xcafebabe;
+ array1[1] = 0xdecafbad;
+ array1[2] = 0xffffffff;
+ array1[3] = 0xdeadbeef;
+
+ var buffer2 = new ArrayBuffer(32);
+ var array2 = new UInt32Array(buffer2);
+
+ // if the array can't fit, it throws
+ Assert.raises(function():Void {
+ array2.set(array1, 6);
+ });
+ // in that case, none of the values should have been updated
+ Assert.equals(0x0, array2[0]);
+ Assert.equals(0x0, array2[1]);
+ Assert.equals(0x0, array2[2]);
+ Assert.equals(0x0, array2[3]);
+ Assert.equals(0x0, array2[4]);
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+ }
+}
\ No newline at end of file
diff --git a/tests/unit/src/utils/UInt8ArrayTest.hx b/tests/unit/src/utils/UInt8ArrayTest.hx
new file mode 100644
index 0000000000..04a87afd8c
--- /dev/null
+++ b/tests/unit/src/utils/UInt8ArrayTest.hx
@@ -0,0 +1,295 @@
+package utils;
+
+import lime.utils.ArrayBuffer;
+import lime.utils.UInt16Array;
+import lime.utils.UInt32Array;
+import lime.utils.UInt8Array;
+import utest.Assert;
+import utest.Test;
+
+class UInt8ArrayTest extends Test {
+ public function new() {
+ super();
+ }
+
+ public function testByteLength():Void {
+ var buffer = new ArrayBuffer(4);
+ var array = new UInt8Array(buffer);
+ Assert.equals(4, array.length);
+ Assert.equals(4, array.byteLength);
+ }
+
+ public function testValues():Void {
+ var buffer = new ArrayBuffer(4);
+ var array = new UInt8Array(buffer);
+ Assert.equals(0x0, array[0]);
+ Assert.equals(0x0, array[1]);
+ Assert.equals(0x0, array[2]);
+ Assert.equals(0x0, array[3]);
+ array[0] = 0xca;
+ array[1] = 0xfe;
+ array[2] = 0xba;
+ array[3] = 0xbe;
+ Assert.equals(0xca, array[0]);
+ Assert.equals(0xfe, array[1]);
+ Assert.equals(0xba, array[2]);
+ Assert.equals(0xbe, array[3]);
+ }
+
+ public function testSubarray():Void {
+ var buffer = new ArrayBuffer(4);
+ var array = new UInt8Array(buffer);
+ array[0] = 0xca;
+ array[1] = 0xfe;
+ array[2] = 0xba;
+ array[3] = 0xbe;
+
+ var four = array.subarray(0, 4);
+ Assert.equals(4, four.length);
+ Assert.equals(4, four.byteLength);
+ Assert.equals(0xca, four[0]);
+ Assert.equals(0xfe, four[1]);
+ Assert.equals(0xba, four[2]);
+ Assert.equals(0xbe, four[3]);
+
+ var twoStart = array.subarray(0, 2);
+ Assert.equals(2, twoStart.length);
+ Assert.equals(2, twoStart.byteLength);
+ Assert.equals(0xca, twoStart[0]);
+ Assert.equals(0xfe, twoStart[1]);
+
+ var twoEnd = array.subarray(2, 4);
+ Assert.equals(2, twoEnd.length);
+ Assert.equals(2, twoEnd.byteLength);
+ Assert.equals(0xba, twoEnd[0]);
+ Assert.equals(0xbe, twoEnd[1]);
+
+ var endBeforeStart = array.subarray(2, 1);
+ Assert.equals(0, endBeforeStart.length);
+ Assert.equals(0, endBeforeStart.byteLength);
+
+ var endEqualsStart = array.subarray(2, 2);
+ Assert.equals(0, endEqualsStart.length);
+ Assert.equals(0, endEqualsStart.byteLength);
+
+ var beyondLength = array.subarray(0, 400);
+ Assert.equals(4, beyondLength.length);
+ Assert.equals(4, beyondLength.byteLength);
+ Assert.equals(0xca, beyondLength[0]);
+ Assert.equals(0xfe, beyondLength[1]);
+ Assert.equals(0xba, beyondLength[2]);
+ Assert.equals(0xbe, beyondLength[3]);
+ }
+
+ public function testSetArrayOfInts():Void {
+ var array1:Array = [0xca, 0xfe, 0xba, 0xbe];
+
+ var buffer2 = new ArrayBuffer(8);
+ var array2 = new UInt8Array(buffer2);
+
+ array2.set(array1);
+ Assert.equals(0xca, array2[0]);
+ Assert.equals(0xfe, array2[1]);
+ Assert.equals(0xba, array2[2]);
+ Assert.equals(0xbe, array2[3]);
+ Assert.equals(0x0, array2[4]);
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+
+ for (i in 0...array2.length) {
+ array2[i] = 0x0;
+ }
+
+ array2.set(array1, 1);
+ Assert.equals(0x0, array2[0]);
+ Assert.equals(0xca, array2[1]);
+ Assert.equals(0xfe, array2[2]);
+ Assert.equals(0xba, array2[3]);
+ Assert.equals(0xbe, array2[4]);
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+
+ for (i in 0...array2.length) {
+ array2[i] = 0x0;
+ }
+
+ Assert.raises(function():Void {
+ array2.set(array1, 6);
+ });
+ Assert.equals(0x0, array2[0]);
+ Assert.equals(0x0, array2[1]);
+ Assert.equals(0x0, array2[2]);
+ Assert.equals(0x0, array2[3]);
+ Assert.equals(0x0, array2[4]);
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+ }
+
+ public function testSetUInt8Array():Void {
+ var buffer1 = new ArrayBuffer(4);
+ var array1 = new UInt8Array(buffer1);
+ array1[0] = 0xca;
+ array1[1] = 0xfe;
+ array1[2] = 0xba;
+ array1[3] = 0xbe;
+
+ var buffer2 = new ArrayBuffer(8);
+ var array2 = new UInt8Array(buffer2);
+
+ array2.set(array1);
+ Assert.equals(0xca, array2[0]);
+ Assert.equals(0xfe, array2[1]);
+ Assert.equals(0xba, array2[2]);
+ Assert.equals(0xbe, array2[3]);
+ Assert.equals(0x0, array2[4]);
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+
+ // reset the array to all zeros
+ for (i in 0...array2.length) {
+ array2[i] = 0x0;
+ }
+
+ array2.set(array1, 1);
+ Assert.equals(0x0, array2[0]);
+ Assert.equals(0xca, array2[1]);
+ Assert.equals(0xfe, array2[2]);
+ Assert.equals(0xba, array2[3]);
+ Assert.equals(0xbe, array2[4]);
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+
+ for (i in 0...array2.length) {
+ array2[i] = 0x0;
+ }
+
+ // if the array can't fit, it throws
+ Assert.raises(function():Void {
+ array2.set(array1, 6);
+ });
+ // in that case, none of the values should have been updated
+ Assert.equals(0x0, array2[0]);
+ Assert.equals(0x0, array2[1]);
+ Assert.equals(0x0, array2[2]);
+ Assert.equals(0x0, array2[3]);
+ Assert.equals(0x0, array2[4]);
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+ }
+
+ public function testSetUInt16Array():Void {
+ var buffer1 = new ArrayBuffer(8);
+ var array1 = new UInt16Array(buffer1);
+ array1[0] = 0xcafe;
+ array1[1] = 0xbabe;
+ array1[2] = 0xdeca;
+ array1[3] = 0xfbad;
+
+ var buffer2 = new ArrayBuffer(8);
+ var array2 = new UInt8Array(buffer2);
+
+ array2.set(array1);
+ Assert.equals(0xfe, array2[0]);
+ Assert.equals(0xbe, array2[1]);
+ Assert.equals(0xca, array2[2]);
+ Assert.equals(0xad, array2[3]);
+ Assert.equals(0x0, array2[4]);
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+
+ // reset the array to all zeros
+ for (i in 0...array2.length) {
+ array2[i] = 0x0;
+ }
+
+ array2.set(array1, 1);
+ Assert.equals(0x0, array2[0]);
+ Assert.equals(0xfe, array2[1]);
+ Assert.equals(0xbe, array2[2]);
+ Assert.equals(0xca, array2[3]);
+ Assert.equals(0xad, array2[4]);
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+
+ for (i in 0...array2.length) {
+ array2[i] = 0x0;
+ }
+
+ // if the array can't fit, it throws
+ Assert.raises(function():Void {
+ array2.set(array1, 6);
+ });
+ // in that case, none of the values should have been updated
+ Assert.equals(0x0, array2[0]);
+ Assert.equals(0x0, array2[1]);
+ Assert.equals(0x0, array2[2]);
+ Assert.equals(0x0, array2[3]);
+ Assert.equals(0x0, array2[4]);
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+ }
+
+ public function testSetUInt32Array():Void {
+ var buffer1 = new ArrayBuffer(16);
+ var array1 = new UInt32Array(buffer1);
+ array1[0] = 0xcafebabe;
+ array1[1] = 0xdecafbad;
+ array1[2] = 0xffffffff;
+ array1[3] = 0xdeadbeef;
+
+ var buffer2 = new ArrayBuffer(8);
+ var array2 = new UInt8Array(buffer2);
+
+ array2.set(array1);
+ Assert.equals(0xbe, array2[0]);
+ Assert.equals(0xad, array2[1]);
+ Assert.equals(0xff, array2[2]);
+ Assert.equals(0xef, array2[3]);
+ Assert.equals(0x0, array2[4]);
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+
+ // reset the array to all zeros
+ for (i in 0...array2.length) {
+ array2[i] = 0x0;
+ }
+
+ array2.set(array1, 1);
+ Assert.equals(0x0, array2[0]);
+ Assert.equals(0xbe, array2[1]);
+ Assert.equals(0xad, array2[2]);
+ Assert.equals(0xff, array2[3]);
+ Assert.equals(0xef, array2[4]);
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+
+ for (i in 0...array2.length) {
+ array2[i] = 0x0;
+ }
+
+ // if the array can't fit, it throws
+ Assert.raises(function():Void {
+ array2.set(array1, 6);
+ });
+ // in that case, none of the values should have been updated
+ Assert.equals(0x0, array2[0]);
+ Assert.equals(0x0, array2[1]);
+ Assert.equals(0x0, array2[2]);
+ Assert.equals(0x0, array2[3]);
+ Assert.equals(0x0, array2[4]);
+ Assert.equals(0x0, array2[5]);
+ Assert.equals(0x0, array2[6]);
+ Assert.equals(0x0, array2[7]);
+ }
+}
\ No newline at end of file
diff --git a/tests/unit/templates/html5/template/index.html b/tests/unit/templates/html5/template/index.html
new file mode 100644
index 0000000000..005c530a34
--- /dev/null
+++ b/tests/unit/templates/html5/template/index.html
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+ ::APP_TITLE::
+
+
+
+
+ ::if favicons::::foreach (favicons)::
+ ::end::::end::
+
+ ::if linkedLibraries::::foreach (linkedLibraries)::
+ ::end::::end::
+
+
+
+
+
+
+
+
+ ::foreach assets::::if (type == "font")::
+ ::end::::end::
+
+
+
+
+
+
+