diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
new file mode 100644
index 0000000000..45995eb1b0
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -0,0 +1,138 @@
+name: Bug report
+description: Report a focused, reproducible Lime bug
+title: "[Bug]: "
+labels: []
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Please report one specific problem per issue. Reports without enough information to reproduce may be closed until the missing details are provided.
+
+ - type: checkboxes
+ id: checks
+ attributes:
+ label: Preflight Checklist
+ options:
+ - label: I searched existing open and closed issues for duplicates.
+ required: true
+ - label: I tested the latest stable Lime release or the current development branch where possible.
+ required: true
+ - label: I reduced this to the smallest project or code sample that still reproduces the issue.
+ required: true
+ - label: This issue describes one specific behavior, not several unrelated observations.
+ required: true
+
+ - type: textarea
+ id: summary
+ attributes:
+ label: Problem Description
+ description: Describe the specific behavior that appears to be wrong.
+ validations:
+ required: true
+
+ - type: textarea
+ id: versions
+ attributes:
+ label: Version Information
+ description: Include exact versions. Do not write "latest" by itself.
+ value: |
+ Lime version:
+ OpenFL version, if applicable:
+ Haxe version:
+ Target/runtime:
+ validations:
+ required: true
+
+ - type: textarea
+ id: environment
+ attributes:
+ label: Environment
+ description: Include relevant OS, architecture, hardware and driver details.
+ value: |
+ OS:
+ Architecture:
+ GPU/driver, if relevant:
+ Display refresh rate, if relevant:
+ validations:
+ required: true
+
+ - type: textarea
+ id: repro
+ attributes:
+ label: Minimal Reproduction
+ description: Attach or link a minimal project, or paste the smallest code sample that reproduces the problem. Include project.xml or project.hxp.
+ placeholder: |
+ Link to minimal project:
+
+ project.xml / project.hxp:
+
+ Relevant source:
+ validations:
+ required: true
+
+ - type: textarea
+ id: steps
+ attributes:
+ label: Steps to Reproduce
+ description: List exact steps needed to reproduce the issue from a clean checkout/project.
+ placeholder: |
+ 1.
+ 2.
+ 3.
+ validations:
+ required: true
+
+ - type: textarea
+ id: expected
+ attributes:
+ label: Expected Behavior
+ description: What should happen?
+ validations:
+ required: true
+
+ - type: textarea
+ id: actual
+ attributes:
+ label: Actual Behavior
+ description: What happens instead?
+ validations:
+ required: true
+
+ - type: textarea
+ id: logs
+ attributes:
+ label: Logs and Output
+ description: Paste relevant console output, stack traces or build logs.
+ render: text
+ validations:
+ required: false
+
+ - type: textarea
+ id: media
+ attributes:
+ label: Screenshots or Videos
+ description: Attach screenshots or videos only if they help demonstrate the reproduced behavior. They do not replace a minimal reproduction.
+ validations:
+ required: false
+
+ - type: textarea
+ id: timing
+ attributes:
+ label: Performance, Timing or Rendering Details
+ description: If this is about frame pacing, timing or rendering, explain how you measured it and list frame rate, vsync, window/fullscreen and display settings.
+ placeholder: |
+ Frame rate:
+ Vsync setting:
+ Window/fullscreen mode:
+ Measurement method:
+ Reproduces on other targets/machines/drivers:
+ validations:
+ required: false
+
+ - type: textarea
+ id: additional
+ attributes:
+ label: Additional Context
+ description: Add any other focused context that may help reproduce or diagnose this issue.
+ validations:
+ required: false
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 0000000000..3ba13e0cec
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1 @@
+blank_issues_enabled: false
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml
new file mode 100644
index 0000000000..143721ab44
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.yml
@@ -0,0 +1,87 @@
+name: Feature request
+description: Propose a focused Lime feature or behavior change
+title: "[Feature]: "
+labels: []
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Please use this form for focused feature proposals. If you are reporting broken behavior, use the bug report form instead.
+
+ - type: checkboxes
+ id: checks
+ attributes:
+ label: Preflight Checklist
+ options:
+ - label: I searched existing open and closed issues for similar proposals.
+ required: true
+ - label: This request describes one focused feature or behavior change.
+ required: true
+ - label: This is not a bug report or a request for help debugging project-specific code.
+ required: true
+
+ - type: textarea
+ id: problem
+ attributes:
+ label: Problem or Use Case
+ description: What problem would this feature solve? Who needs it, and when?
+ validations:
+ required: true
+
+ - type: textarea
+ id: proposal
+ attributes:
+ label: Proposed Behavior
+ description: Describe the exact behavior, API, project setting or workflow change you are proposing.
+ validations:
+ required: true
+
+ - type: textarea
+ id: targets
+ attributes:
+ label: Affected Targets or Backends
+ description: List the targets, runtimes or backends this proposal affects.
+ placeholder: |
+ Native SDL:
+ HTML5:
+ HashLink:
+ HXCPP:
+ Other:
+ validations:
+ required: true
+
+ - type: textarea
+ id: compatibility
+ attributes:
+ label: Compatibility and Defaults
+ description: Explain whether this should be default behavior, opt-in behavior or a breaking change. Include any compatibility concerns.
+ validations:
+ required: true
+
+ - type: textarea
+ id: alternatives
+ attributes:
+ label: Alternatives Considered
+ description: What existing options, workarounds or alternative designs have you considered?
+ validations:
+ required: false
+
+ - type: textarea
+ id: examples
+ attributes:
+ label: Example Usage
+ description: Show how a project would use this feature, if applicable.
+ placeholder: |
+ project.xml / project.hxp:
+
+ Haxe code:
+ validations:
+ required: false
+
+ - type: textarea
+ id: additional
+ attributes:
+ label: Additional Context
+ description: Add any focused context, links or prior discussion that may help evaluate the proposal.
+ validations:
+ required: false
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 857907b35e..b18bf094f7 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -18,7 +18,9 @@ jobs:
- name: Install system dependencies
run: |
sudo apt-get update
- sudo apt-get install -y libgl1-mesa-dev libglu1-mesa-dev g++-multilib gcc-multilib libasound2-dev libx11-dev libxext-dev libxi-dev libxrandr-dev libxinerama-dev libpulse-dev libmbedtls-dev libpng-dev libturbojpeg-dev libuv1-dev libvorbis-dev
+ sudo apt-get install -y libgl1-mesa-dev libglu1-mesa-dev g++-multilib gcc-multilib libasound2-dev libx11-dev libxext-dev libxi-dev libxrandr-dev libxinerama-dev libpulse-dev libmbedtls-dev libpng-dev libturbojpeg-dev libuv1-dev libvorbis-dev libvulkan-dev
+ # GStreamer decodes video in the unit tests
+ sudo apt-get install -y gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-libav xvfb
- uses: krdlab/setup-haxe@v2
with:
@@ -30,9 +32,9 @@ jobs:
- name: Install Haxe dependencies
run: |
- curl --output ../hxcpp-4.3.45.zip --location https://github.com/HaxeFoundation/hxcpp/releases/download/v4.3.45/hxcpp-4.3.45.zip
+ curl --output ../hxcpp-4.3.53.zip --location https://github.com/HaxeFoundation/hxcpp/releases/download/v4.3.53/hxcpp-4.3.53.zip
haxelib --global update haxelib --quiet
- haxelib install ../hxcpp-4.3.45.zip --quiet
+ haxelib install ../hxcpp-4.3.53.zip --quiet
haxelib install format --quiet
haxelib install hxp --quiet
haxelib install utest --quiet
@@ -74,11 +76,31 @@ jobs:
- name: Run unit tests
working-directory: tests/unit
+ env:
+ # OpenAL's null output stands in for the sound card runners lack
+ ALSOFT_DRIVERS: "null"
run: |
lime test neko -release -verbose -nocolor
lime test hl -release -verbose -nocolor
lime test linux -release -verbose -nocolor
+ - name: Run unit tests past 24.8 days
+ working-directory: tests/unit
+ # A timer stuck at the Int limit hangs the tests rather than failing them
+ timeout-minutes: 10
+ env:
+ ALSOFT_DRIVERS: "null"
+ run: |
+ # The timer starts 10 s short of 2^31 ms, where an Int millisecond count
+ # runs out, so the tests run on across it
+ lime test linux -release -verbose -nocolor -Dsimulate_uptime=2147473648
+
+ - name: Run video smoke test
+ working-directory: tests/video-smoke
+ run: |
+ lime build linux -release -verbose -nocolor
+ SDL_AUDIODRIVER=dummy xvfb-run -a Export/linux/bin/LimeVideoSmoke
+
- name: Install samples
run: |
haxelib git lime-samples https://github.com/openfl/lime-samples --quiet
@@ -98,6 +120,11 @@ jobs:
lime create SimpleAudio -verbose -nocolor
lime build SimpleAudio linux -release -verbose -nocolor
+ - name: Build SimpleVideo sample
+ run: |
+ lime create SimpleVideo -verbose -nocolor
+ lime build SimpleVideo linux -release -verbose -nocolor
+
linux-arm64:
runs-on: ubuntu-22.04-arm
steps:
@@ -110,7 +137,9 @@ jobs:
run: |
sudo add-apt-repository ppa:haxe/releases -y
sudo apt-get update
- sudo apt-get install -y libgl1-mesa-dev libglu1-mesa-dev libasound2-dev libx11-dev libxext-dev libxi-dev libxrandr-dev libxinerama-dev libpulse-dev libmbedtls-dev libpng-dev libturbojpeg-dev libuv1-dev libvorbis-dev
+ sudo apt-get install -y libgl1-mesa-dev libglu1-mesa-dev libasound2-dev libx11-dev libxext-dev libxi-dev libxrandr-dev libxinerama-dev libpulse-dev libmbedtls-dev libpng-dev libturbojpeg-dev libuv1-dev libvorbis-dev libvulkan-dev
+ # GStreamer decodes video in the unit tests
+ sudo apt-get install -y gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-libav
# krdlab/setup-haxe doesn't support arm64 linux
# so this is our workaround for now
@@ -128,17 +157,13 @@ jobs:
- name: Install Haxe dependencies
run: |
- curl --output ../hxcpp-4.3.45.zip --location https://github.com/HaxeFoundation/hxcpp/releases/download/v4.3.45/hxcpp-4.3.45.zip
+ curl --output ../hxcpp-4.3.53.zip --location https://github.com/HaxeFoundation/hxcpp/releases/download/v4.3.53/hxcpp-4.3.53.zip
haxelib --global update haxelib --quiet
- haxelib install ../hxcpp-4.3.45.zip --quiet
+ haxelib install ../hxcpp-4.3.53.zip --quiet
haxelib install format --quiet
haxelib install hxp --quiet
haxelib install utest --quiet
- - name: Enable HXCPP compile cache
- run: |
- echo "HXCPP_COMPILE_CACHE=~/.hxcpp" >> $GITHUB_ENV
-
- name: Rebuild Lime tools
run: |
haxelib dev lime ${{ github.workspace }}
@@ -159,6 +184,9 @@ jobs:
- name: Run unit tests
working-directory: tests/unit
+ env:
+ # OpenAL's null output stands in for the sound card runners lack
+ ALSOFT_DRIVERS: "null"
run: |
lime test neko -release -verbose -nocolor
lime test linux -release -verbose -nocolor
@@ -182,14 +210,24 @@ jobs:
lime create SimpleAudio -verbose -nocolor
lime build SimpleAudio linux -release -verbose -nocolor
- macos:
- runs-on: macos-14
+ - name: Build SimpleVideo sample
+ run: |
+ lime create SimpleVideo -verbose -nocolor
+ lime build SimpleVideo linux -release -verbose -nocolor
+
+ vulkan-smoke:
+ runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v6
with:
submodules: true
+ - name: Install system dependencies
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y libgl1-mesa-dev libglu1-mesa-dev libasound2-dev libx11-dev libx11-xcb1 libxext-dev libxi-dev libxrandr-dev libxinerama-dev libpulse-dev libmbedtls-dev libpng-dev libturbojpeg-dev libuv1-dev libvorbis-dev libvulkan-dev mesa-vulkan-drivers xvfb
+
- uses: krdlab/setup-haxe@v2
with:
haxe-version: ${{ env.HAXE_VERSION }}
@@ -198,23 +236,58 @@ jobs:
run: |
echo "HAXEPATH=$HAXE_STD_PATH/.." >> $GITHUB_ENV
- - name: Install HashLink dependencies
+ - name: Install Haxe dependencies
+ run: |
+ curl --output ../hxcpp-4.3.53.zip --location https://github.com/HaxeFoundation/hxcpp/releases/download/v4.3.53/hxcpp-4.3.53.zip
+ haxelib --global update haxelib --quiet
+ haxelib install ../hxcpp-4.3.53.zip --quiet
+ haxelib install format --quiet
+ haxelib install hxp --quiet
+ 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
+
+ - name: Rebuild Lime (Linux default Vulkan)
+ run: |
+ lime rebuild linux -64 -release -nocolor -verbose -nocffi
+
+ - name: Build Vulkan smoke test app
+ working-directory: tests/vulkan-smoke
+ run: |
+ lime build linux -release -verbose -nocolor
+
+ - name: Run Vulkan smoke test app
+ working-directory: tests/vulkan-smoke
+ run: |
+ if [ -f /usr/share/vulkan/icd.d/lvp_icd.x86_64.json ]; then
+ export VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/lvp_icd.x86_64.json
+ fi
+ SDL_AUDIODRIVER=dummy xvfb-run -a Export/linux/bin/LimeVulkanSmoke
+
+ macos:
+ runs-on: macos-14
+ steps:
+
+ - uses: actions/checkout@v6
+ with:
+ submodules: true
+
+ - uses: krdlab/setup-haxe@v2
+ with:
+ haxe-version: 4.3.7
+
+ - name: Set HAXEPATH
run: |
- arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
- pushd project/lib/hashlink
- arch -x86_64 /usr/local/bin/brew update
- rm /usr/local/bin/2to3*
- rm /usr/local/bin/idle3*
- rm /usr/local/bin/pydoc3*
- rm /usr/local/bin/python3*
- rm /usr/local/bin/pip3*
- arch -x86_64 /usr/local/bin/brew bundle
- popd
+ echo "HAXEPATH=$HAXE_STD_PATH/.." >> $GITHUB_ENV
- name: Install Haxe dependencies
run: |
- curl --output ../hxcpp-4.3.45.zip --location https://github.com/HaxeFoundation/hxcpp/releases/download/v4.3.45/hxcpp-4.3.45.zip
- haxelib install ../hxcpp-4.3.45.zip --quiet
+ curl --output ../hxcpp-4.3.53.zip --location https://github.com/HaxeFoundation/hxcpp/releases/download/v4.3.53/hxcpp-4.3.53.zip
+ haxelib install ../hxcpp-4.3.53.zip --quiet
haxelib install format --quiet
haxelib install hxp --quiet
haxelib install utest --quiet
@@ -227,23 +300,125 @@ jobs:
- name: Rebuild Lime (macOS)
run: |
- lime rebuild macos -clean -release -64 -nocolor -verbose -nocffi
lime rebuild macos -clean -release -arm64 -nocolor -verbose -nocffi
- lime rebuild hl -clean -release -nocolor -verbose -nocffi
- uses: actions/upload-artifact@v7
with:
- name: Mac64-NDLL
+ name: MacArm64-NDLL
path: |
- ndll/Mac64/
+ ndll/MacArm64/
!**/.gitignore
if-no-files-found: error
+ - name: Run unit tests
+ working-directory: tests/unit
+ env:
+ # OpenAL's null output stands in for the sound card runners lack
+ ALSOFT_DRIVERS: "null"
+ run: |
+ lime test neko -release -verbose -nocolor
+ lime test mac -arm64 -release -verbose -nocolor
+
+ - name: Run video smoke test
+ working-directory: tests/video-smoke
+ run: |
+ lime test mac -arm64 -release -verbose -nocolor
+
+ - name: Install samples
+ run: |
+ haxelib git lime-samples https://github.com/openfl/lime-samples --quiet
+
+ # - name: Build HelloWorld sample
+ # run: |
+ # lime create HelloWorld -verbose -nocolor
+ # lime build HelloWorld macos -release -verbose -nocolor
+
+ - name: Build SimpleImage sample
+ run: |
+ lime create SimpleImage -verbose -nocolor
+ lime build SimpleImage macos -arm64 -release -verbose -nocolor
+
+ - name: Build SimpleAudio sample
+ run: |
+ lime create SimpleAudio -verbose -nocolor
+ lime build SimpleAudio macos -arm64 -release -verbose -nocolor
+
+ - name: Build SimpleVideo sample
+ run: |
+ lime create SimpleVideo -verbose -nocolor
+ lime build SimpleVideo macos -arm64 -release -verbose -nocolor
+
+ macos-intel:
+ runs-on: macos-15-intel
+ steps:
+
+ - uses: actions/checkout@v6
+ with:
+ submodules: true
+
+ - uses: krdlab/setup-haxe@v2
+ with:
+ haxe-version: ${{ env.HAXE_VERSION }}
+
+ - name: Set HAXEPATH
+ run: |
+ echo "HAXEPATH=$HAXE_STD_PATH/.." >> $GITHUB_ENV
+
+ - name: Install HashLink dependencies
+ env:
+ # Homebrew no longer builds bottles for Intel macOS, so updating it and
+ # upgrading what the runner already has rebuilds cmake, OpenSSL and
+ # Python from source, which takes an hour. Only what is missing is
+ # installed, from the formulae the runner image came with.
+ HOMEBREW_NO_AUTO_UPDATE: 1
+ HOMEBREW_NO_INSTALL_UPGRADE: 1
+ HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: 1
+ run: |
+ set -euxo pipefail
+
+ rm -f /usr/local/bin/2to3*
+ rm -f /usr/local/bin/idle3*
+ rm -f /usr/local/bin/pydoc3*
+ rm -f /usr/local/bin/python3*
+ rm -f /usr/local/bin/pip3*
+
+ for attempt in 1 2 3; do
+ if /usr/local/bin/brew install jpeg-turbo libpng libuv libvorbis; then
+ break
+ fi
+ if [ "$attempt" -eq 3 ]; then
+ exit 1
+ fi
+ sleep $((attempt * 30))
+ done
+
+ - name: Install Haxe dependencies
+ run: |
+ curl --output ../hxcpp-4.3.53.zip --location https://github.com/HaxeFoundation/hxcpp/releases/download/v4.3.53/hxcpp-4.3.53.zip
+ haxelib install ../hxcpp-4.3.53.zip --quiet
+ haxelib install format --quiet
+ haxelib install hxp --quiet
+ 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
+
+ - name: Rebuild Lime (macOS)
+ run: |
+ lime rebuild macos -clean -release -x86_64 -nocolor -verbose -nocffi
+
+ - name: Rebuild Lime (HashLink macOS)
+ run: |
+ lime rebuild hl -clean -release -nocolor -verbose -nocffi
+
- uses: actions/upload-artifact@v7
with:
- name: MacArm64-NDLL
+ name: Mac64-NDLL
path: |
- ndll/MacArm64/
+ ndll/Mac64/
!**/.gitignore
if-no-files-found: error
@@ -256,10 +431,13 @@ jobs:
- name: Run unit tests
working-directory: tests/unit
+ env:
+ # OpenAL's null output stands in for the sound card runners lack
+ ALSOFT_DRIVERS: "null"
run: |
lime test neko -release -verbose -nocolor
lime test hl -release -verbose -nocolor
- lime test mac -release -verbose -nocolor
+ lime test mac -x86_64 -release -verbose -nocolor
- name: Install samples
run: |
@@ -273,12 +451,17 @@ jobs:
- name: Build SimpleImage sample
run: |
lime create SimpleImage -verbose -nocolor
- lime build SimpleImage macos -release -verbose -nocolor
+ lime build SimpleImage macos -x86_64 -release -verbose -nocolor
- name: Build SimpleAudio sample
run: |
lime create SimpleAudio -verbose -nocolor
- lime build SimpleAudio macos -release -verbose -nocolor
+ lime build SimpleAudio macos -x86_64 -release -verbose -nocolor
+
+ - name: Build SimpleVideo sample
+ run: |
+ lime create SimpleVideo -verbose -nocolor
+ lime build SimpleVideo macos -x86_64 -release -verbose -nocolor
windows:
runs-on: windows-latest
@@ -303,8 +486,8 @@ jobs:
- name: Install Haxe dependencies
run: |
- curl --output ../hxcpp-4.3.45.zip --location https://github.com/HaxeFoundation/hxcpp/releases/download/v4.3.45/hxcpp-4.3.45.zip
- haxelib install ../hxcpp-4.3.45.zip --quiet
+ curl --output ../hxcpp-4.3.53.zip --location https://github.com/HaxeFoundation/hxcpp/releases/download/v4.3.53/hxcpp-4.3.53.zip
+ haxelib install ../hxcpp-4.3.53.zip --quiet
haxelib install format --quiet
haxelib install hxp --quiet
haxelib install utest --quiet
@@ -353,12 +536,26 @@ jobs:
- name: Run unit tests
working-directory: tests/unit
+ env:
+ # OpenAL's null output stands in for the sound card runners lack
+ ALSOFT_DRIVERS: "null"
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: Run unit tests past 24.8 days
+ working-directory: tests/unit
+ # A timer stuck at the Int limit hangs the tests rather than failing them
+ timeout-minutes: 10
+ env:
+ ALSOFT_DRIVERS: "null"
+ run: |
+ # The timer starts 10 s short of 2^31 ms, where an Int millisecond count
+ # runs out, so the tests run on across it
+ lime test windows -release -verbose -nocolor -Dsimulate_uptime=2147473648
+
- name: Install samples
run: |
haxelib git lime-samples https://github.com/openfl/lime-samples --quiet
@@ -378,6 +575,11 @@ jobs:
lime create SimpleAudio -verbose -nocolor
lime build SimpleAudio windows -release -verbose -nocolor
+ - name: Build SimpleVideo sample
+ run: |
+ lime create SimpleVideo -verbose -nocolor
+ lime build SimpleVideo windows -release -verbose -nocolor
+
- name: Rebuild Lime (Windows, Mingw)
run: |
rm ndll/Windows64/*
@@ -391,6 +593,73 @@ jobs:
!**/.gitignore
if-no-files-found: error
+ webassembly:
+ runs-on: ubuntu-22.04
+ steps:
+
+ - uses: actions/checkout@v6
+ with:
+ submodules: true
+
+ - name: Install Emscripten NDK
+ uses: emscripten-core/setup-emsdk@v16
+
+ - uses: krdlab/setup-haxe@v2
+ with:
+ haxe-version: ${{ env.HAXE_VERSION }}
+
+ - name: Set HAXEPATH
+ run: |
+ echo "HAXEPATH=$HAXE_STD_PATH/.." >> $GITHUB_ENV
+
+ - name: Install Haxe dependencies
+ run: |
+ curl --output ../hxcpp-4.3.168.zip --location https://github.com/HaxeFoundation/hxcpp/releases/download/v4.3.168/hxcpp-4.3.168.zip
+ haxelib install ../hxcpp-4.3.168.zip --quiet
+ haxelib install format --quiet
+ haxelib install hxp --quiet
+
+ - name: Prepare Lime
+ run: |
+ haxelib dev lime ${{ github.workspace }}
+ haxelib run lime setup -alias -y -nocffi -eval
+
+ - name: Configure Emscripten support
+ run: |
+ lime config EMSCRIPTEN_SDK $EMSDK/upstream/emscripten -eval
+ lime config -eval
+
+ - name: Rebuild Lime (WebAssembly)
+ run: |
+ lime rebuild webassembly -release -nocolor -verbose -nocffi -eval
+
+ - uses: actions/upload-artifact@v7
+ with:
+ name: Emscripten-NDLL
+ path: |
+ ndll/Emscripten/
+ !**/.gitignore
+ if-no-files-found: error
+
+ - name: Install samples
+ run: |
+ haxelib git lime-samples https://github.com/openfl/lime-samples --quiet
+
+ - name: Build SimpleImage sample
+ run: |
+ lime create SimpleImage -verbose -nocolor -eval
+ lime build SimpleImage webassembly -release -verbose -nocolor -eval
+
+ - name: Build SimpleAudio sample
+ run: |
+ lime create SimpleAudio -verbose -nocolor -eval
+ lime build SimpleAudio webassembly -release -verbose -nocolor -eval
+
+ - name: Build SimpleVideo sample
+ run: |
+ lime create SimpleVideo -verbose -nocolor -eval
+ lime build SimpleVideo webassembly -release -verbose -nocolor -eval
+
android:
runs-on: ubuntu-22.04
strategy:
@@ -425,8 +694,8 @@ jobs:
- name: Install Haxe dependencies
run: |
- curl --output ../hxcpp-4.3.45.zip --location https://github.com/HaxeFoundation/hxcpp/releases/download/v4.3.45/hxcpp-4.3.45.zip
- haxelib install ../hxcpp-4.3.45.zip --quiet
+ curl --output ../hxcpp-4.3.53.zip --location https://github.com/HaxeFoundation/hxcpp/releases/download/v4.3.53/hxcpp-4.3.53.zip
+ haxelib install ../hxcpp-4.3.53.zip --quiet
haxelib install format --quiet
haxelib install hxp --quiet
@@ -476,6 +745,17 @@ jobs:
run: |
lime create SimpleAudio -verbose -nocolor -eval
lime build SimpleAudio android -release -verbose -nocolor -eval
+
+ - name: Build SimpleVideo sample
+ run: |
+ lime create SimpleVideo -verbose -nocolor -eval
+ lime build SimpleVideo android -release -verbose -nocolor -eval
+
+ - name: Build Vulkan smoke test app
+ working-directory: tests/vulkan-smoke
+ run: |
+ lime build android -release -verbose -nocolor -eval
+
ios:
runs-on: macos-14
steps:
@@ -494,8 +774,8 @@ jobs:
- name: Install Haxe dependencies
run: |
- curl --output ../hxcpp-4.3.45.zip --location https://github.com/HaxeFoundation/hxcpp/releases/download/v4.3.45/hxcpp-4.3.45.zip
- haxelib install ../hxcpp-4.3.45.zip --quiet
+ curl --output ../hxcpp-4.3.53.zip --location https://github.com/HaxeFoundation/hxcpp/releases/download/v4.3.53/hxcpp-4.3.53.zip
+ haxelib install ../hxcpp-4.3.53.zip --quiet
haxelib install format --quiet
haxelib install hxp --quiet
@@ -535,8 +815,13 @@ jobs:
lime create SimpleAudio -verbose -nocolor -eval
lime build SimpleAudio ios -release -nosign -verbose -nocolor -eval
+ - name: Build SimpleVideo sample (Device)
+ run: |
+ lime create SimpleVideo -verbose -nocolor -eval
+ lime build SimpleVideo ios -release -nosign -verbose -nocolor -eval
+
package-haxelib:
- needs: [linux, macos, windows, android, ios]
+ needs: [linux, macos, macos-intel, windows, android, ios]
runs-on: ubuntu-22.04
steps:
@@ -554,8 +839,8 @@ jobs:
- name: Install Haxe dependencies
run: |
- curl --output ../hxcpp-4.3.45.zip --location https://github.com/HaxeFoundation/hxcpp/releases/download/v4.3.45/hxcpp-4.3.45.zip
- haxelib install ../hxcpp-4.3.45.zip --quiet
+ curl --output ../hxcpp-4.3.53.zip --location https://github.com/HaxeFoundation/hxcpp/releases/download/v4.3.53/hxcpp-4.3.53.zip
+ haxelib install ../hxcpp-4.3.53.zip --quiet
haxelib install format --quiet
haxelib install hxp --quiet
haxelib install svg --quiet
@@ -724,11 +1009,16 @@ jobs:
lime create SimpleAudio -verbose -nocolor -eval
lime build SimpleAudio flash -release -verbose -nocolor -eval
+ - name: Build SimpleVideo sample
+ run: |
+ lime create SimpleVideo -verbose -nocolor -eval
+ lime build SimpleVideo flash -release -verbose -nocolor -eval
+
air-samples:
runs-on: windows-latest
strategy:
matrix:
- haxe-version: [4.0.5, 4.1.5, 4.2.5, 4.3.6]
+ haxe-version: [4.0.5, 4.1.5, 4.2.5, 4.3.7]
steps:
- uses: actions/checkout@v6
@@ -750,8 +1040,8 @@ jobs:
- name: Install Haxe dependencies
run: |
- curl --output ../hxcpp-4.3.45.zip --location https://github.com/HaxeFoundation/hxcpp/releases/download/v4.3.45/hxcpp-4.3.45.zip
- haxelib install ../hxcpp-4.3.45.zip --quiet
+ curl --output ../hxcpp-4.3.53.zip --location https://github.com/HaxeFoundation/hxcpp/releases/download/v4.3.53/hxcpp-4.3.53.zip
+ haxelib install ../hxcpp-4.3.53.zip --quiet
haxelib install format --quiet
haxelib install hxp --quiet
haxelib git lime-samples https://github.com/openfl/lime-samples --quiet
@@ -777,6 +1067,11 @@ jobs:
lime create SimpleAudio -verbose -nocolor -eval
lime build SimpleAudio air -release -verbose -nocolor -eval
+ - name: Build SimpleVideo sample
+ run: |
+ lime create SimpleVideo -verbose -nocolor -eval
+ lime build SimpleVideo air -release -verbose -nocolor -eval
+
hashlink-samples:
needs: package-haxelib
strategy:
@@ -827,6 +1122,11 @@ jobs:
lime create SimpleAudio -verbose -nocolor
lime build SimpleAudio hl -release -verbose -nocolor
+ - name: Build SimpleVideo sample
+ run: |
+ lime create SimpleVideo -verbose -nocolor
+ lime build SimpleVideo hl -release -verbose -nocolor
+
hashlinkc-samples:
needs: package-haxelib
strategy:
@@ -877,12 +1177,17 @@ jobs:
lime create SimpleAudio -verbose -nocolor
lime build SimpleAudio hlc -release -verbose -nocolor
+ - name: Build SimpleVideo sample
+ run: |
+ lime create SimpleVideo -verbose -nocolor
+ lime build SimpleVideo hlc -release -verbose -nocolor
+
html5-samples:
needs: package-haxelib
runs-on: ubuntu-22.04
strategy:
matrix:
- haxe-version: [3.4.7, 4.0.5, 4.1.5, 4.2.5, 4.3.6]
+ haxe-version: [3.4.7, 4.0.5, 4.1.5, 4.2.5, 4.3.7]
steps:
- uses: actions/checkout@v6
@@ -937,12 +1242,23 @@ jobs:
lime create SimpleAudio -verbose -nocolor
lime build SimpleAudio html5 -release -verbose -nocolor
+ - name: Build SimpleVideo sample
+ run: |
+ lime create SimpleVideo -verbose -nocolor
+ lime build SimpleVideo html5 -release -verbose -nocolor
+
- name: Build SimpleAudio variants
if: ${{ matrix.haxe-version != '3.4.7' }}
run: |
lime build SimpleAudio html5 -clean -release -verbose -nocolor --haxelib=genes
lime build SimpleAudio html5 -clean -release -verbose -nocolor -minify -terser
+ - name: Build SimpleVideo variants
+ if: ${{ matrix.haxe-version != '3.4.7' }}
+ run: |
+ lime build SimpleVideo html5 -clean -release -verbose -nocolor --haxelib=genes
+ lime build SimpleVideo html5 -clean -release -verbose -nocolor -minify -terser
+
neko-samples:
needs: package-haxelib
strategy:
@@ -994,13 +1310,45 @@ jobs:
lime create SimpleAudio -verbose -nocolor
lime build SimpleAudio neko -release -verbose -nocolor
+ - name: Build SimpleVideo sample
+ run: |
+ lime create SimpleVideo -verbose -nocolor
+ lime build SimpleVideo neko -release -verbose -nocolor
+
notify:
runs-on: ubuntu-22.04
- needs: [package-haxelib, docs, android, flash-samples, air-samples, hashlink-samples, hashlinkc-samples, html5-samples, ios, linux, macos, neko-samples, windows]
- if: ${{ github.repository == 'openfl/lime' && github.event_name != 'pull_request' }}
+ needs: [package-haxelib, docs, android, flash-samples, air-samples, hashlink-samples, hashlinkc-samples, html5-samples, ios, linux, linux-arm64, vulkan-smoke, macos, macos-intel, neko-samples, webassembly, windows]
+ # Reports failures too, which is when it matters most
+ if: ${{ always() && github.repository == 'openfl/lime' && github.event_name != 'pull_request' }}
steps:
- name: Notify Discord
- uses: nobrayner/discord-webhook@v1
- with:
- github-token: ${{ secrets.github_token }}
- discord-webhook: ${{ secrets.DISCORD_WEBHOOK }}
+ env:
+ DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
+ GH_TOKEN: ${{ github.token }}
+ ACTOR: ${{ github.actor }}
+ COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
+ RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
+ TITLE: "[${{ github.repository }}] ${{ github.workflow }}"
+ run: |
+ # One message for the run, naming the jobs that did not pass. Discord
+ # takes at most 25 fields in a message, fewer than the jobs here, so
+ # they go in its description, and a message it turns down fails this.
+ jobs=$(gh api "repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/jobs?per_page=100" --jq '[.jobs[] | select(.name != "notify")]')
+ failed=$(echo "$jobs" | jq -r '[.[] | select(.conclusion == "failure" or .conclusion == "cancelled" or .conclusion == "timed_out")] | map("[\(.name)](\(.html_url)): \(.conclusion)") | join("\n")')
+
+ if [ -z "$failed" ]; then status=Success; color=1560392; else status=Failure; color=15148839; fi
+
+ commit="${{ github.sha }}"
+ description="\`${commit:0:8}\` $(printf '%s' "$COMMIT_MESSAGE" | head -n 1)"
+ [ -n "$failed" ] && description="$description"$'\n\n'"$failed"
+
+ payload=$(jq -n --arg title "$TITLE: $status" --arg url "$RUN_URL" --arg actor "$ACTOR" --arg description "$description" --argjson color "$color" '{
+ username: "GitHub Actions",
+ avatar_url: "https://avatars0.githubusercontent.com/u/44036562?s=200&v=4",
+ embeds: [{
+ author: {name: $actor, url: ("https://github.com/" + $actor), icon_url: ("https://github.com/" + $actor + ".png")},
+ title: $title, url: $url, description: $description, color: $color
+ }]
+ }')
+
+ curl --fail-with-body --silent --show-error -H "Content-Type: application/json" -d "$payload" "$DISCORD_WEBHOOK"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 38d456a168..67464dcddf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,63 @@
Changelog
=========
+8.4.0 (06/18/2026)
+------------------
+
+- Added an experimental Vulkan renderer for native Windows, Linux, and Android targets.
+- Added `VulkanRenderContext` and Haxe Vulkan bindings for instance, device, swapchain, command, descriptor, memory, and pipeline helpers.
+- Added Vulkan bootstrap logging, error details, MSAA resolve support, mapped memory helpers, and descriptor helpers.
+- Added configurable application frame timing with `FrameProfile`, `FrameOptions`, `VSyncMode`, busy-wait, time precision, and uncap controls.
+- Added `AudioInput` and audio input device APIs with native OpenAL, HTML5, and Flash backends.
+- Added SDL_sound decoding and streaming, including inline stream playback, streams with unknown length, and loop counts.
+- Added `Window.alwaysOnTop` and transparent window support.
+- Added input event timestamps without changing listener signatures.
+- Added `Promise.completeAsync()`.
+- Added explicit font rendering flags, DPI-aware glyph rendering, unhinted font decomposition, and HarfBuzz FT font change notifications.
+- Added `Font.isBold` and `Font.isItalic`.
+- Added project.xml support for Android manifest tags and Gradle plugin entries.
+- Added AIR options for Android App Bundles, Android Studio output, and shared runtime deployment.
+- Added VAO support on macOS.
+- Added `VideoSource` and `VideoDecoder` for native video playback, with Media Foundation, AVFoundation, MediaCodec, and GStreamer backends.
+- Added `Window.flash()`, `Window.mouseRect`, and `Window.keyboardGrab`.
+- Added `Window.preciseMouseWheel` for smooth scrolling on touchpads and smooth wheels.
+- Added `Display.onConnect`, `Display.onDisconnect`, and `Display.onMove`.
+- Added `Gamepad.type`, motion sensors, touchpad events, trigger rumble, and light color.
+- Added `Locale.preferredLocales`.
+- Added `ThreadPool.idleTimeout`, so idle threads wait for more work before they exit.
+- Added `CURL.versionInfo()` values for the library's age, version number, and features.
+- Changed asset copying and embedding to behave consistently across targets.
+- Changed OpenAL Soft HRTF to be disabled by default.
+- Changed `allowHighDPI` on Windows to draw at each display's own resolution, rather than stretched from 96 DPI.
+- Changed `Window.alert()` to also request attention on macOS and Linux.
+- Changed Windows to show input methods' own composition and candidate windows.
+- Changed `FrameProfile.Uncapped` to uncap the frame loop.
+- Changed native HTTP requests to look up names on a thread of their own on every platform.
+- Updated pixman and platform config for LLVM assembly fixes, ARM NEON, Android NDKs, and Apple platforms.
+- Updated MojoAL and gamepad mappings.
+- Updated SDL submodule to version 2.32.10.
+- Updated HashLink to 1.16.
+- Fixed an asset embedding regression.
+- Fixed Windows cpp icon resource handling when no icon is generated.
+- Fixed GL cleanup and desktop GL object collection.
+- Fixed native and HashLink `AudioBuffer` layout mismatches.
+- Fixed `AudioBuffer.fromBytes()` and `AudioBuffer.fromBase64()` on HTML5 to avoid forcing HTML5 audio buffers.
+- Fixed OpenAL output device recovery.
+- Fixed perspective camera matrix calculation.
+- Fixed Tizen `appinfo.json` templating.
+- Fixed Android architecture parsing for `x86_64` and `x86_32`.
+- Fixed SDL_sound ARM64 Linux detection outside Raspberry Pi OS.
+- Fixed HTML5 transparent docs generation.
+- Fixed native HTTP requests freezing the application during slow name lookups (#1769).
+- Fixed HashLink collections waiting on threads blocked in native calls.
+- Fixed `Future.ready()` and `Future.result()` never seeing threaded work complete.
+- Fixed `Promise.completeAsync()` on C++.
+- Fixed single-threaded `ThreadPool` work running past its share of a frame while waiting.
+- Fixed `Font.renderGlyphs()` reading glyphs in an outdated layout, and on HashLink.
+- Fixed `getVertexAttribOffset()` and `getBufferPointerv()` writing through a null pointer.
+- Fixed video pan reaching sound that was already queued.
+- Fixed compositions longer than 31 bytes being cut short in input methods.
+
8.3.2 (05/13/2026)
------------------
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index c483f354e6..ae8c283921 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -5,6 +5,38 @@ We welcome your feedback and input in how to make Lime better!
If you are interested in discussing new features, the direction the project or how to integrate some change, please open an issue so we can talk about.
+## Issue Reporting Guidelines
+
+Please keep bug reports focused, reproducible and actionable. A good issue should describe one specific problem and include enough information for maintainers to reproduce it without guessing.
+
+Before opening an issue:
+
+ 1. Search existing open and closed issues to avoid duplicates.
+
+ 2. Test with the latest stable release and, when possible, the current development branch.
+
+ 3. Reduce the problem to the smallest project or code sample that still reproduces it.
+
+Bug reports should include:
+
+ 1. The exact Lime version, OpenFL version if applicable, Haxe version and target/runtime.
+
+ 2. The operating system, architecture and relevant hardware or driver details.
+
+ 3. A minimal project or code sample, including `project.xml` or `project.hxp`.
+
+ 4. Exact steps to reproduce the problem.
+
+ 5. The expected behavior and the actual behavior.
+
+ 6. Any relevant logs, console output, screenshots or videos.
+
+Please do not combine multiple unrelated problems in one issue. Open one issue per behavior so each report can be reproduced, discussed and fixed independently.
+
+Performance, timing and rendering reports need especially clear reproduction material. Include a minimal project, the exact frame rate/vsync/window settings, how the result was measured and whether the behavior reproduces across targets, machines or drivers.
+
+Issues based only on broad observations, speculation, generated code that has not been verified, or project-specific behavior without a minimal reproduction may be closed until enough information is provided.
+
1. Fork the repository
2. Make the desired change
diff --git a/README.md b/README.md
index c6803fb1a5..167628b285 100644
--- a/README.md
+++ b/README.md
@@ -22,8 +22,13 @@ Lime does not include a renderer, but exposes the current context:
* DOM
* Flash
* GL
+ * Vulkan
The GL context is based upon the WebGL standard, implemented for both OpenGL and OpenGL ES as needed.
+Native Vulkan support exposes an explicit Vulkan API layer for renderer backends, including native window/swapchain integration and resource/command primitives.
+Native Vulkan support is included in standard Windows and Linux C++ Lime builds, including the matching Haxe API define. Apple targets still require an explicit Vulkan-enabled build and MoltenVK packaging.
+To request a Vulkan window, use the standard `RenderContextType.VULKAN` context selection or set `` in project XML.
+The in-repo `tests/vulkan-smoke` project is used as the current Vulkan CI smoke app.
Lime provides a unified audio API, but also provides access to OpenAL for advanced audio on native targets.
diff --git a/docs/ImportAll.hx b/docs/ImportAll.hx
index e0039724f6..d1fbcc89cf 100644
--- a/docs/ImportAll.hx
+++ b/docs/ImportAll.hx
@@ -58,6 +58,41 @@ import lime.graphics.PixelFormat;
import lime.graphics.RenderContext;
import lime.graphics.RenderContextAttributes;
import lime.graphics.RenderContextType;
+import lime.graphics.VulkanRenderContext;
+import lime.graphics.vulkan.VK;
+import lime.graphics.vulkan.VKAcquireResult;
+import lime.graphics.vulkan.VKBuffer;
+import lime.graphics.vulkan.VKCommandBuffer;
+import lime.graphics.vulkan.VKCommandPool;
+import lime.graphics.vulkan.VKDescriptorPool;
+import lime.graphics.vulkan.VKDescriptorPoolSize;
+import lime.graphics.vulkan.VKDescriptorSet;
+import lime.graphics.vulkan.VKDescriptorSetLayout;
+import lime.graphics.vulkan.VKDescriptorSetLayoutBinding;
+import lime.graphics.vulkan.VKDevice;
+import lime.graphics.vulkan.VKDeviceMemory;
+import lime.graphics.vulkan.VKFence;
+import lime.graphics.vulkan.VKFramebuffer;
+import lime.graphics.vulkan.VKGraphicsPipelineInfo;
+import lime.graphics.vulkan.VKImage;
+import lime.graphics.vulkan.VKImageView;
+import lime.graphics.vulkan.VKInstance;
+import lime.graphics.vulkan.VKMemoryRequirements;
+import lime.graphics.vulkan.VKPhysicalDevice;
+import lime.graphics.vulkan.VKPipeline;
+import lime.graphics.vulkan.VKPipelineCache;
+import lime.graphics.vulkan.VKPipelineLayout;
+import lime.graphics.vulkan.VKQueue;
+import lime.graphics.vulkan.VKQueueFamilyInfo;
+import lime.graphics.vulkan.VKRenderPass;
+import lime.graphics.vulkan.VKRenderer;
+import lime.graphics.vulkan.VKSampler;
+import lime.graphics.vulkan.VKSemaphore;
+import lime.graphics.vulkan.VKShaderModule;
+import lime.graphics.vulkan.VKSurface;
+import lime.graphics.vulkan.VKSwapchain;
+import lime.graphics.vulkan.VKVertexAttribute;
+import lime.graphics.vulkan.VKVertexBinding;
import lime.graphics.WebGL2RenderContext;
import lime.graphics.WebGLRenderContext;
import lime.math.ARGB;
@@ -87,6 +122,8 @@ import lime.media.vorbis.VorbisInfo;
import lime.media.AudioBuffer;
import lime.media.AudioContext;
import lime.media.AudioContextType;
+import lime.media.AudioInput;
+import lime.media.AudioInputDevice;
import lime.media.AudioManager;
import lime.media.AudioSource;
import lime.media.FlashAudioContext;
diff --git a/externs/air/flash/data/SQLCollationType.hx b/externs/air/flash/data/SQLCollationType.hx
index fecbfc8382..0f93c36c1f 100644
--- a/externs/air/flash/data/SQLCollationType.hx
+++ b/externs/air/flash/data/SQLCollationType.hx
@@ -1,7 +1,6 @@
package flash.data;
-@:native("flash.data.SQLCollationType")
-#if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract SQLCollationType(String)
+@:native("flash.data.SQLCollationType") #if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract SQLCollationType(String)
{
var BINARY = "binary";
var NO_CASE = "noCase";
diff --git a/externs/air/flash/data/SQLColumnNameStyle.hx b/externs/air/flash/data/SQLColumnNameStyle.hx
index 03cb7a5adf..c25b13fc07 100644
--- a/externs/air/flash/data/SQLColumnNameStyle.hx
+++ b/externs/air/flash/data/SQLColumnNameStyle.hx
@@ -1,7 +1,6 @@
package flash.data;
-@:native("flash.data.SQLColumnNameStyle")
-#if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract SQLColumnNameStyle(String)
+@:native("flash.data.SQLColumnNameStyle") #if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract SQLColumnNameStyle(String)
{
var DEFAULT = "default";
var LONG = "long";
diff --git a/externs/air/flash/data/SQLMode.hx b/externs/air/flash/data/SQLMode.hx
index ebddf4c8c9..4b876d2d02 100644
--- a/externs/air/flash/data/SQLMode.hx
+++ b/externs/air/flash/data/SQLMode.hx
@@ -1,7 +1,6 @@
package flash.data;
-@:native("flash.data.SQLMode")
-#if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract SQLMode(String)
+@:native("flash.data.SQLMode") #if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract SQLMode(String)
{
var CREATE = "create";
var READ = "read";
diff --git a/externs/air/flash/data/SQLTransactionLockType.hx b/externs/air/flash/data/SQLTransactionLockType.hx
index 36c24bc1a7..47a06a7a79 100644
--- a/externs/air/flash/data/SQLTransactionLockType.hx
+++ b/externs/air/flash/data/SQLTransactionLockType.hx
@@ -1,7 +1,6 @@
package flash.data;
-@:native("flash.data.SQLTransactionLockType")
-#if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract SQLTransactionLockType(String)
+@:native("flash.data.SQLTransactionLockType") #if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract SQLTransactionLockType(String)
{
var DEFERRED = "deferred";
var EXCLUSIVE = "exclusive";
diff --git a/externs/air/flash/desktop/InvokeEventReason.hx b/externs/air/flash/desktop/InvokeEventReason.hx
index d06e591c1b..1c053ad26c 100644
--- a/externs/air/flash/desktop/InvokeEventReason.hx
+++ b/externs/air/flash/desktop/InvokeEventReason.hx
@@ -1,7 +1,6 @@
package flash.desktop;
-@:native("flash.desktop.InvokeEventReason")
-#if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract InvokeEventReason(String)
+@:native("flash.desktop.InvokeEventReason") #if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract InvokeEventReason(String)
{
var LOGIN = "login";
var NOTIFICATION = "notification";
diff --git a/externs/air/flash/desktop/NativeDragActions.hx b/externs/air/flash/desktop/NativeDragActions.hx
index fe67ff9db7..544ad2f1bf 100644
--- a/externs/air/flash/desktop/NativeDragActions.hx
+++ b/externs/air/flash/desktop/NativeDragActions.hx
@@ -1,7 +1,6 @@
package flash.desktop;
-@:native("flash.desktop.NativeDragActions")
-#if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract NativeDragActions(String)
+@:native("flash.desktop.NativeDragActions") #if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract NativeDragActions(String)
{
var COPY = "copy";
var LINK = "link";
diff --git a/externs/air/flash/desktop/NotificationType.hx b/externs/air/flash/desktop/NotificationType.hx
index b2b3dcfb09..c9461c33cf 100644
--- a/externs/air/flash/desktop/NotificationType.hx
+++ b/externs/air/flash/desktop/NotificationType.hx
@@ -1,7 +1,6 @@
package flash.desktop;
-@:native("flash.desktop.NotificationType")
-#if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract NotificationType(String)
+@:native("flash.desktop.NotificationType") #if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract NotificationType(String)
{
var CRITICAL = "critical";
var INFORMATIONAL = "informational";
diff --git a/externs/air/flash/desktop/SystemIdleMode.hx b/externs/air/flash/desktop/SystemIdleMode.hx
index 7fda8df044..c129940766 100644
--- a/externs/air/flash/desktop/SystemIdleMode.hx
+++ b/externs/air/flash/desktop/SystemIdleMode.hx
@@ -1,7 +1,6 @@
package flash.desktop;
-@:native("flash.desktop.SystemIdleMode")
-#if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract SystemIdleMode(String)
+@:native("flash.desktop.SystemIdleMode") #if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract SystemIdleMode(String)
{
var KEEP_AWAKE = "keepAwake";
var NORMAL = "normal";
diff --git a/externs/air/flash/display/NativeWindowDisplayState.hx b/externs/air/flash/display/NativeWindowDisplayState.hx
index 4fb63f10d7..56a073a2e0 100644
--- a/externs/air/flash/display/NativeWindowDisplayState.hx
+++ b/externs/air/flash/display/NativeWindowDisplayState.hx
@@ -1,7 +1,6 @@
package flash.display;
-@:native("flash.display.NativeWindowDisplayState")
-#if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract NativeWindowDisplayState(String)
+@:native("flash.display.NativeWindowDisplayState") #if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract NativeWindowDisplayState(String)
{
var MAXIMIZED = "maximized";
var MINIMIZED = "minimized";
diff --git a/externs/air/flash/display/NativeWindowRenderMode.hx b/externs/air/flash/display/NativeWindowRenderMode.hx
index e2d182c5bd..51a135f715 100644
--- a/externs/air/flash/display/NativeWindowRenderMode.hx
+++ b/externs/air/flash/display/NativeWindowRenderMode.hx
@@ -1,7 +1,6 @@
package flash.display;
-@:native("flash.display.NativeWindowRenderMode")
-#if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract NativeWindowRenderMode(String)
+@:native("flash.display.NativeWindowRenderMode") #if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract NativeWindowRenderMode(String)
{
var AUTO = "auto";
var CPU = "cpu";
diff --git a/externs/air/flash/display/NativeWindowResize.hx b/externs/air/flash/display/NativeWindowResize.hx
index b3cd1a1f9f..5974784f0f 100644
--- a/externs/air/flash/display/NativeWindowResize.hx
+++ b/externs/air/flash/display/NativeWindowResize.hx
@@ -1,7 +1,6 @@
package flash.display;
-@:native("flash.display.NativeWindowResize")
-#if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract NativeWindowResize(String)
+@:native("flash.display.NativeWindowResize") #if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract NativeWindowResize(String)
{
var BOTTOM = "bottom";
var BOTTOM_LEFT = "bottomLeft";
diff --git a/externs/air/flash/display/NativeWindowSystemChrome.hx b/externs/air/flash/display/NativeWindowSystemChrome.hx
index e271969831..367e6d9c22 100644
--- a/externs/air/flash/display/NativeWindowSystemChrome.hx
+++ b/externs/air/flash/display/NativeWindowSystemChrome.hx
@@ -1,7 +1,6 @@
package flash.display;
-@:native("flash.display.NativeWindowSystemChrome")
-#if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract NativeWindowSystemChrome(String)
+@:native("flash.display.NativeWindowSystemChrome") #if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract NativeWindowSystemChrome(String)
{
var ALTERNATE = "alternate";
var NONE = "none";
diff --git a/externs/air/flash/display/NativeWindowType.hx b/externs/air/flash/display/NativeWindowType.hx
index 90ff5bb41f..0ffd8af4bc 100644
--- a/externs/air/flash/display/NativeWindowType.hx
+++ b/externs/air/flash/display/NativeWindowType.hx
@@ -1,7 +1,6 @@
package flash.display;
-@:native("flash.display.NativeWindowType")
-#if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract NativeWindowType(String)
+@:native("flash.display.NativeWindowType") #if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract NativeWindowType(String)
{
var LIGHTWEIGHT = "lightweight";
var NORMAL = "normal";
diff --git a/externs/air/flash/display/StageAspectRatio.hx b/externs/air/flash/display/StageAspectRatio.hx
index 70ede16512..8a308b07bf 100644
--- a/externs/air/flash/display/StageAspectRatio.hx
+++ b/externs/air/flash/display/StageAspectRatio.hx
@@ -1,7 +1,6 @@
package flash.display;
-@:native("flash.display.StageAspectRatio")
-#if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract StageAspectRatio(String)
+@:native("flash.display.StageAspectRatio") #if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract StageAspectRatio(String)
{
var ANY = "any";
var LANDSCAPE = "landscape";
diff --git a/externs/air/flash/display/StageOrientation.hx b/externs/air/flash/display/StageOrientation.hx
index d55da84778..2f2a9b34a8 100644
--- a/externs/air/flash/display/StageOrientation.hx
+++ b/externs/air/flash/display/StageOrientation.hx
@@ -1,7 +1,6 @@
package flash.display;
-@:native("flash.display.StageOrientation")
-#if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract StageOrientation(String)
+@:native("flash.display.StageOrientation") #if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract StageOrientation(String)
{
var DEFAULT = "default";
var ROTATED_LEFT = "rotatedLeft";
diff --git a/externs/air/flash/display3D/Context3DProfile.hx b/externs/air/flash/display3D/Context3DProfile.hx
index 2c29eea679..a7e697bc09 100644
--- a/externs/air/flash/display3D/Context3DProfile.hx
+++ b/externs/air/flash/display3D/Context3DProfile.hx
@@ -1,7 +1,6 @@
package flash.display3D;
-@:native("flash.display3D.Context3DProfile")
-#if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract Context3DProfile(String)
+@:native("flash.display3D.Context3DProfile") #if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract Context3DProfile(String)
{
var BASELINE = "baseline";
var BASELINE_CONSTRAINED = "baselineConstrained";
diff --git a/externs/air/flash/errors/SQLErrorOperation.hx b/externs/air/flash/errors/SQLErrorOperation.hx
index 15e7a651c0..396ba8c237 100644
--- a/externs/air/flash/errors/SQLErrorOperation.hx
+++ b/externs/air/flash/errors/SQLErrorOperation.hx
@@ -1,7 +1,6 @@
package flash.errors;
-@:native("flash.errors.SQLErrorOperation")
-#if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract SQLErrorOperation(String)
+@:native("flash.errors.SQLErrorOperation") #if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract SQLErrorOperation(String)
{
var ANALYZE = "analyze";
var ATTACH = "attach";
diff --git a/externs/air/flash/events/TouchEventIntent.hx b/externs/air/flash/events/TouchEventIntent.hx
index 19a3c6a0e6..0af83e0428 100644
--- a/externs/air/flash/events/TouchEventIntent.hx
+++ b/externs/air/flash/events/TouchEventIntent.hx
@@ -1,7 +1,6 @@
package flash.events;
-@:native("flash.events.TouchEventIntent")
-#if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract TouchEventIntent(String)
+@:native("flash.events.TouchEventIntent") #if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract TouchEventIntent(String)
{
var ERASER = "eraser";
var PEN = "pen";
diff --git a/externs/air/flash/filesystem/FileMode.hx b/externs/air/flash/filesystem/FileMode.hx
index 3041db9b92..6644c1627b 100644
--- a/externs/air/flash/filesystem/FileMode.hx
+++ b/externs/air/flash/filesystem/FileMode.hx
@@ -1,7 +1,6 @@
package flash.filesystem;
-@:native("flash.filesystem.FileMode")
-#if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract FileMode(String)
+@:native("flash.filesystem.FileMode") #if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract FileMode(String)
{
var APPEND = "append";
var READ = "read";
diff --git a/externs/air/flash/media/AudioPlaybackMode.hx b/externs/air/flash/media/AudioPlaybackMode.hx
index fdc31990c4..9757dadbe0 100644
--- a/externs/air/flash/media/AudioPlaybackMode.hx
+++ b/externs/air/flash/media/AudioPlaybackMode.hx
@@ -1,7 +1,6 @@
package flash.media;
-@:native("flash.media.AudioPlaybackMode")
-#if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract AudioPlaybackMode(String)
+@:native("flash.media.AudioPlaybackMode") #if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract AudioPlaybackMode(String)
{
var AMBIENT = "ambient";
var MEDIA = "media";
diff --git a/externs/air/flash/media/CameraPosition.hx b/externs/air/flash/media/CameraPosition.hx
index 06184cc9ed..754d0051f9 100644
--- a/externs/air/flash/media/CameraPosition.hx
+++ b/externs/air/flash/media/CameraPosition.hx
@@ -1,7 +1,6 @@
package flash.media;
-@:native("flash.media.CameraPosition")
-#if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract CameraPosition(String)
+@:native("flash.media.CameraPosition") #if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract CameraPosition(String)
{
var BACK = "back";
var FRONT = "front";
diff --git a/externs/air/flash/media/MediaType.hx b/externs/air/flash/media/MediaType.hx
index 41a10306fb..e925b08397 100644
--- a/externs/air/flash/media/MediaType.hx
+++ b/externs/air/flash/media/MediaType.hx
@@ -1,7 +1,6 @@
package flash.media;
-@:native("flash.media.MediaType")
-#if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract MediaType(String)
+@:native("flash.media.MediaType") #if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract MediaType(String)
{
var IMAGE = "image";
var VIDEO = "video";
diff --git a/externs/air/flash/net/IPVersion.hx b/externs/air/flash/net/IPVersion.hx
index ef4a44fcf2..c9d8200955 100644
--- a/externs/air/flash/net/IPVersion.hx
+++ b/externs/air/flash/net/IPVersion.hx
@@ -1,7 +1,6 @@
package flash.net;
-@:native("flash.net.IPVersion")
-#if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract IPVersion(String)
+@:native("flash.net.IPVersion") #if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract IPVersion(String)
{
var IPV4 = "ipv4";
var IPV6 = "ipv6";
diff --git a/externs/air/flash/notifications/NotificationStyle.hx b/externs/air/flash/notifications/NotificationStyle.hx
index a2a9f3fdd2..715052bf6d 100644
--- a/externs/air/flash/notifications/NotificationStyle.hx
+++ b/externs/air/flash/notifications/NotificationStyle.hx
@@ -1,7 +1,6 @@
package flash.notifications;
-@:native("flash.notifications.NotificationStyle")
-#if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract NotificationStyle(String)
+@:native("flash.notifications.NotificationStyle") #if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract NotificationStyle(String)
{
var ALERT = "alert";
var BADGE = "badge";
diff --git a/externs/air/flash/printing/PaperSize.hx b/externs/air/flash/printing/PaperSize.hx
index fe607d1e2a..65e60bdbfa 100644
--- a/externs/air/flash/printing/PaperSize.hx
+++ b/externs/air/flash/printing/PaperSize.hx
@@ -1,7 +1,6 @@
package flash.printing;
-@:native("flash.printing.PaperSize")
-#if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract PaperSize(String)
+@:native("flash.printing.PaperSize") #if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract PaperSize(String)
{
var A4 = "a4";
var A5 = "a5";
diff --git a/externs/air/flash/printing/PrintMethod.hx b/externs/air/flash/printing/PrintMethod.hx
index 070fcfcf1c..a6f7ac873a 100644
--- a/externs/air/flash/printing/PrintMethod.hx
+++ b/externs/air/flash/printing/PrintMethod.hx
@@ -1,7 +1,6 @@
package flash.printing;
-@:native("flash.printing.PrintMethod")
-#if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract PrintMethod(String)
+@:native("flash.printing.PrintMethod") #if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract PrintMethod(String)
{
var AUTO = "auto";
var BITMAP = "bitmap";
diff --git a/externs/air/flash/security/ReferencesValidationSetting.hx b/externs/air/flash/security/ReferencesValidationSetting.hx
index 08fda5c8ca..b357c649d1 100644
--- a/externs/air/flash/security/ReferencesValidationSetting.hx
+++ b/externs/air/flash/security/ReferencesValidationSetting.hx
@@ -1,7 +1,6 @@
package flash.security;
-@:native("flash.security.ReferencesValidationSetting")
-#if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract ReferencesValidationSetting(String)
+@:native("flash.security.ReferencesValidationSetting") #if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract ReferencesValidationSetting(String)
{
var NEVER = "never";
var VALID_IDENTITY = "validIdentity";
diff --git a/externs/air/flash/security/RevocationCheckSettings.hx b/externs/air/flash/security/RevocationCheckSettings.hx
index 09725cea85..11365b4a09 100644
--- a/externs/air/flash/security/RevocationCheckSettings.hx
+++ b/externs/air/flash/security/RevocationCheckSettings.hx
@@ -1,7 +1,6 @@
package flash.security;
-@:native("flash.security.RevocationCheckSettings")
-#if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract RevocationCheckSettings(String)
+@:native("flash.security.RevocationCheckSettings") #if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract RevocationCheckSettings(String)
{
var ALWAYS_REQUIRED = "alwaysRequired";
var BEST_EFFORT = "bestEffort";
diff --git a/externs/air/flash/security/SignatureStatus.hx b/externs/air/flash/security/SignatureStatus.hx
index f8c632599e..68e03bcaf9 100644
--- a/externs/air/flash/security/SignatureStatus.hx
+++ b/externs/air/flash/security/SignatureStatus.hx
@@ -1,7 +1,6 @@
package flash.security;
-@:native("flash.security.SignatureStatus")
-#if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract SignatureStatus(String)
+@:native("flash.security.SignatureStatus") #if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract SignatureStatus(String)
{
var INVALID = "invalid";
var UNKNOWN = "unknown";
diff --git a/externs/air/flash/security/SignerTrustSettings.hx b/externs/air/flash/security/SignerTrustSettings.hx
index 0164a3a253..0edf890a94 100644
--- a/externs/air/flash/security/SignerTrustSettings.hx
+++ b/externs/air/flash/security/SignerTrustSettings.hx
@@ -1,7 +1,6 @@
package flash.security;
-@:native("flash.security.SignerTrustSettings")
-#if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract SignerTrustSettings(String)
+@:native("flash.security.SignerTrustSettings") #if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract SignerTrustSettings(String)
{
var CODE_SIGNING = "codeSigning";
var PLAYLIST_SIGNING = "playlistSigning";
diff --git a/externs/air/flash/text/AutoCapitalize.hx b/externs/air/flash/text/AutoCapitalize.hx
index e0bb0169df..472737f7cd 100644
--- a/externs/air/flash/text/AutoCapitalize.hx
+++ b/externs/air/flash/text/AutoCapitalize.hx
@@ -1,7 +1,6 @@
package flash.text;
-@:native("flash.text.AutoCapitalize")
-#if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract AutoCapitalize(String)
+@:native("flash.text.AutoCapitalize") #if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract AutoCapitalize(String)
{
var ALL = "all";
var NONE = "none";
diff --git a/externs/air/flash/text/ReturnKeyLabel.hx b/externs/air/flash/text/ReturnKeyLabel.hx
index 3936c1722e..573d048ee3 100644
--- a/externs/air/flash/text/ReturnKeyLabel.hx
+++ b/externs/air/flash/text/ReturnKeyLabel.hx
@@ -1,7 +1,6 @@
package flash.text;
-@:native("flash.text.ReturnKeyLabel")
-#if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract ReturnKeyLabel(String)
+@:native("flash.text.ReturnKeyLabel") #if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract ReturnKeyLabel(String)
{
var DEFAULT = "default";
var DONE = "done";
diff --git a/externs/air/flash/text/SoftKeyboardType.hx b/externs/air/flash/text/SoftKeyboardType.hx
index 3a9f747dc4..a6ff23fddb 100644
--- a/externs/air/flash/text/SoftKeyboardType.hx
+++ b/externs/air/flash/text/SoftKeyboardType.hx
@@ -1,7 +1,6 @@
package flash.text;
-@:native("flash.text.SoftKeyboardType")
-#if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract SoftKeyboardType(String)
+@:native("flash.text.SoftKeyboardType") #if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract SoftKeyboardType(String)
{
var CONTACT = "contact";
var DEFAULT = "default";
diff --git a/externs/air/flash/text/StageTextClearButtonMode.hx b/externs/air/flash/text/StageTextClearButtonMode.hx
index 21f09ecb2b..ade3888cb0 100644
--- a/externs/air/flash/text/StageTextClearButtonMode.hx
+++ b/externs/air/flash/text/StageTextClearButtonMode.hx
@@ -1,7 +1,6 @@
package flash.text;
-@:native("flash.text.StageTextClearButtonMode")
-#if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract StageTextClearButtonMode(String)
+@:native("flash.text.StageTextClearButtonMode") #if (haxe_ver >= 4.0) extern enum #else @:extern @:enum #end abstract StageTextClearButtonMode(String)
{
var ALWAYS = "always";
var NEVER = "never";
diff --git a/externs/air/sys/io/FileInput.hx b/externs/air/sys/io/FileInput.hx
index 93e2f3b19d..7e3558ed28 100644
--- a/externs/air/sys/io/FileInput.hx
+++ b/externs/air/sys/io/FileInput.hx
@@ -34,9 +34,9 @@ class FileInput extends haxe.io.Input
switch (pos)
{
case SeekBegin:
- // this.pos = p;
+ // this.pos = p;
case SeekEnd:
- // this.pos = cast Fs.fstatSync(fd).size + p;
+ // this.pos = cast Fs.fstatSync(fd).size + p;
case SeekCur:
// this.pos += p;
}
diff --git a/externs/air/sys/io/FileOutput.hx b/externs/air/sys/io/FileOutput.hx
index cdd3ba2414..e0e96e9d57 100644
--- a/externs/air/sys/io/FileOutput.hx
+++ b/externs/air/sys/io/FileOutput.hx
@@ -31,9 +31,9 @@ class FileOutput extends haxe.io.Output
switch (pos)
{
case SeekBegin:
- // this.pos = p;
+ // this.pos = p;
case SeekEnd:
- // this.pos = cast Fs.fstatSync(fd).size + p;
+ // this.pos = cast Fs.fstatSync(fd).size + p;
case SeekCur:
// this.pos += p;
}
diff --git a/include.xml b/include.xml
index 04f641e3c6..4f210d3678 100644
--- a/include.xml
+++ b/include.xml
@@ -24,6 +24,8 @@
+
+
@@ -108,6 +110,8 @@
+
+
diff --git a/project/Build.xml b/project/Build.xml
index ef9bc7458d..86e0c1ba51 100755
--- a/project/Build.xml
+++ b/project/Build.xml
@@ -35,10 +35,13 @@
+
+
+
@@ -59,6 +62,10 @@
+
+
+
+
@@ -236,6 +243,7 @@
+
@@ -267,9 +275,15 @@
+
+
+
+
+
+
@@ -328,6 +342,12 @@
+
+
+
+
+
+
@@ -347,9 +367,11 @@
+
+
@@ -448,6 +470,7 @@
+
@@ -472,6 +495,7 @@
+
@@ -498,9 +522,11 @@
+
+
diff --git a/project/BuildHashlink.xml b/project/BuildHashlink.xml
index 7123640ee1..caa5c9f9f1 100644
--- a/project/BuildHashlink.xml
+++ b/project/BuildHashlink.xml
@@ -1,5 +1,7 @@
-
+
@@ -114,7 +116,14 @@
-
+
@@ -127,10 +136,21 @@
-
-
-
-
+
+
@@ -257,21 +277,37 @@
-
+
+
+
+
+
+
+
+
+
+
@@ -284,13 +320,10 @@
-
-
-
@@ -318,6 +351,7 @@
@@ -332,11 +366,13 @@
-
-
-
-
+
@@ -352,8 +388,11 @@
-
-
+
+
@@ -363,10 +402,20 @@
-
-
-
-
+
@@ -408,7 +457,14 @@
-
+
@@ -416,11 +472,15 @@
diff --git a/project/include/app/Application.h b/project/include/app/Application.h
index e7e5e7114a..59a6200d43 100644
--- a/project/include/app/Application.h
+++ b/project/include/app/Application.h
@@ -22,6 +22,7 @@ namespace lime {
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 bool SetMenu (const unsigned char* data, int length) { return false; }
virtual void SetVSyncMode (int vsyncMode) {}
virtual bool Update () = 0;
@@ -31,6 +32,9 @@ namespace lime {
Application* CreateApplication ();
+ // Called before CreateApplication where the windows allow high DPI
+ void AllowHighDPI ();
+
}
diff --git a/project/include/graphics/vulkan/VKRenderer.h b/project/include/graphics/vulkan/VKRenderer.h
new file mode 100644
index 0000000000..ae2b0b8f69
--- /dev/null
+++ b/project/include/graphics/vulkan/VKRenderer.h
@@ -0,0 +1,160 @@
+#ifndef LIME_GRAPHICS_VULKAN_VKRENDERER_H
+#define LIME_GRAPHICS_VULKAN_VKRENDERER_H
+
+#include
+#include
+#include
+#include
+#include
+
+
+namespace lime {
+
+
+ class VulkanRenderer {
+
+ public:
+
+ explicit VulkanRenderer (Window* window);
+ ~VulkanRenderer ();
+
+ bool ClearOverlay ();
+ bool Create (const char* applicationName);
+ void Destroy ();
+ bool Render (float red, float green, float blue, float alpha);
+ bool Resize ();
+ bool SetOverlay (const unsigned char* data, int width, int height, int x, int y);
+
+ inline const std::string& GetInfo () const { return info; }
+ inline const std::string& GetLastError () const { return lastError; }
+
+ private:
+
+ bool CreateCommandBuffers ();
+ bool CreateCommandPool ();
+ bool CreateDevice ();
+ bool CreateFramebuffers ();
+ bool CreateImageViews ();
+ bool CreateInstance (const char* applicationName);
+ bool CreateOverlayBuffer (size_t requiredSize);
+ bool CreateRenderPass ();
+ bool CreateSurface ();
+ bool CreateSwapchain ();
+ bool CreateSwapchainResources ();
+ bool CreateSyncObjects ();
+ void DestroyOverlayResources ();
+ void DestroySwapchainResources ();
+ uint32_t FindMemoryType (uint32_t typeFilter, VkMemoryPropertyFlags properties);
+ bool LoadDeviceProcs ();
+ bool LoadGlobalProcs ();
+ bool LoadInstanceProcs ();
+ bool PickPhysicalDevice ();
+ bool RecordCommandBuffer (uint32_t imageIndex, float red, float green, float blue, float alpha);
+ bool RecreateSwapchain ();
+ void SetError (const std::string& value);
+
+ Window* window;
+ std::string info;
+ std::string lastError;
+
+ PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
+ PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr;
+ PFN_vkAllocateMemory vkAllocateMemory;
+ PFN_vkBindBufferMemory vkBindBufferMemory;
+ PFN_vkCmdCopyBufferToImage vkCmdCopyBufferToImage;
+ PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier;
+ PFN_vkCreateBuffer vkCreateBuffer;
+ PFN_vkCreateDevice vkCreateDevice;
+ PFN_vkCreateFence vkCreateFence;
+ PFN_vkCreateFramebuffer vkCreateFramebuffer;
+ PFN_vkCreateImageView vkCreateImageView;
+ PFN_vkCreateInstance vkCreateInstance;
+ PFN_vkCreateRenderPass vkCreateRenderPass;
+ PFN_vkCreateSemaphore vkCreateSemaphore;
+ PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR;
+ PFN_vkCreateCommandPool vkCreateCommandPool;
+ PFN_vkAllocateCommandBuffers vkAllocateCommandBuffers;
+ PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR;
+ PFN_vkBeginCommandBuffer vkBeginCommandBuffer;
+ PFN_vkCmdBeginRenderPass vkCmdBeginRenderPass;
+ PFN_vkCmdEndRenderPass vkCmdEndRenderPass;
+ PFN_vkDestroyCommandPool vkDestroyCommandPool;
+ PFN_vkDestroyBuffer vkDestroyBuffer;
+ PFN_vkDestroyDevice vkDestroyDevice;
+ PFN_vkDestroyFence vkDestroyFence;
+ PFN_vkDestroyFramebuffer vkDestroyFramebuffer;
+ PFN_vkDestroyImageView vkDestroyImageView;
+ PFN_vkDestroyInstance vkDestroyInstance;
+ PFN_vkDestroyRenderPass vkDestroyRenderPass;
+ PFN_vkDestroySemaphore vkDestroySemaphore;
+ PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR;
+ PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR;
+ PFN_vkDeviceWaitIdle vkDeviceWaitIdle;
+ PFN_vkEndCommandBuffer vkEndCommandBuffer;
+ PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties;
+ PFN_vkFreeMemory vkFreeMemory;
+ PFN_vkGetBufferMemoryRequirements vkGetBufferMemoryRequirements;
+ PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties;
+ PFN_vkEnumerateInstanceVersion vkEnumerateInstanceVersion;
+ PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices;
+ PFN_vkGetDeviceQueue vkGetDeviceQueue;
+ PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties;
+ PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties;
+ PFN_vkGetPhysicalDeviceQueueFamilyProperties vkGetPhysicalDeviceQueueFamilyProperties;
+ PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR;
+ PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR;
+ PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR;
+ PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR;
+ PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR;
+ PFN_vkMapMemory vkMapMemory;
+ PFN_vkQueuePresentKHR vkQueuePresentKHR;
+ PFN_vkQueueSubmit vkQueueSubmit;
+ PFN_vkResetCommandPool vkResetCommandPool;
+ PFN_vkResetFences vkResetFences;
+ PFN_vkUnmapMemory vkUnmapMemory;
+ PFN_vkWaitForFences vkWaitForFences;
+
+ VkInstance instance;
+ VkSurfaceKHR surface;
+ VkPhysicalDevice physicalDevice;
+ VkPhysicalDeviceProperties physicalDeviceProperties;
+ VkDevice device;
+ VkQueue queue;
+ uint32_t queueFamilyIndex;
+ VkSwapchainKHR swapchain;
+ VkFormat swapchainFormat;
+ VkPresentModeKHR swapchainPresentMode;
+ int requestedVSyncMode;
+ VkExtent2D swapchainExtent;
+ VkRenderPass renderPass;
+ VkCommandPool commandPool;
+ VkSemaphore imageAvailableSemaphore;
+ VkSemaphore renderFinishedSemaphore;
+ VkFence inFlightFence;
+ VkBuffer overlayBuffer;
+ VkDeviceMemory overlayBufferMemory;
+ bool portabilityEnumerationSupported;
+ bool portabilitySubsetSupported;
+ bool swapchainDirty;
+ size_t overlayBufferCapacity;
+ unsigned char* overlayMappedData;
+ uint32_t overlayWidth;
+ uint32_t overlayHeight;
+ int overlayX;
+ int overlayY;
+ bool overlayEnabled;
+
+ std::vector instanceExtensions;
+ std::vector deviceExtensions;
+ std::vector swapchainImages;
+ std::vector swapchainImageViews;
+ std::vector framebuffers;
+ std::vector commandBuffers;
+
+ };
+
+
+}
+
+
+#endif
diff --git a/project/include/media/AudioBuffer.h b/project/include/media/AudioBuffer.h
index 5f9a8130e0..5cd3e476d9 100644
--- a/project/include/media/AudioBuffer.h
+++ b/project/include/media/AudioBuffer.h
@@ -40,6 +40,7 @@ namespace lime {
vdynamic* __srcAudio;
vdynamic* __srcBuffer;
+ int __srcBufferContext;
vdynamic* __srcCustom;
vdynamic* __srcHowl;
bool __isDisposed;
@@ -63,4 +64,4 @@ namespace lime {
}
-#endif
\ No newline at end of file
+#endif
diff --git a/project/include/media/VideoDecoder.h b/project/include/media/VideoDecoder.h
new file mode 100644
index 0000000000..27a667bd9b
--- /dev/null
+++ b/project/include/media/VideoDecoder.h
@@ -0,0 +1,412 @@
+#ifndef LIME_MEDIA_VIDEO_DECODER_H
+#define LIME_MEDIA_VIDEO_DECODER_H
+
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#if defined (HX_WINDOWS) && !defined (HX_WINRT)
+#define LIME_VIDEO_MEDIA_FOUNDATION
+#elif defined (HX_MACOS) || (defined (IPHONE) && !defined (APPLETV))
+#define LIME_VIDEO_AVFOUNDATION
+#elif defined (HX_ANDROID)
+#define LIME_VIDEO_MEDIACODEC
+#elif defined (HX_LINUX) && !defined (EMSCRIPTEN)
+#define LIME_VIDEO_GSTREAMER
+#endif
+
+
+namespace lime {
+
+
+ enum VideoColorMatrix {
+
+ VIDEO_COLOR_MATRIX_BT601 = 0,
+ VIDEO_COLOR_MATRIX_BT709 = 1,
+ VIDEO_COLOR_MATRIX_BT2020 = 2
+
+ };
+
+
+ // How a frame's values are turned into light
+ enum VideoColorTransfer {
+
+ // Standard range, as BT.709 and BT.601 video are
+ VIDEO_COLOR_TRANSFER_SDR = 0,
+
+ // SMPTE ST 2084, which HDR10 video uses
+ VIDEO_COLOR_TRANSFER_PQ = 1,
+
+ // Hybrid log-gamma, ARIB STD-B67, which phones record HDR video in
+ VIDEO_COLOR_TRANSFER_HLG = 2
+
+ };
+
+
+ enum VideoDecodeResult {
+
+ // Nothing was decoded, as a seek is waiting, so the call is made again
+ VIDEO_DECODE_AGAIN = 2,
+ VIDEO_DECODE_OK = 1,
+ VIDEO_DECODE_END = 0,
+ VIDEO_DECODE_ERROR = -1
+
+ };
+
+
+ enum VideoFrameFormat {
+
+ VIDEO_FRAME_FORMAT_NV12 = 0,
+ VIDEO_FRAME_FORMAT_RGBA = 1,
+ VIDEO_FRAME_FORMAT_TEXTURE = 2,
+ VIDEO_FRAME_FORMAT_BGRA = 3,
+ VIDEO_FRAME_FORMAT_ARGB = 4
+
+ };
+
+
+ enum VideoReadResult {
+
+ VIDEO_READ_NOT_READY = 0,
+ VIDEO_READ_END = -1,
+ VIDEO_READ_ERROR = -2,
+ VIDEO_READ_BUFFER_TOO_SMALL = -3
+
+ };
+
+
+ // A decoded picture in system memory. NV12 sets u to the interleaved UV
+ // plane, v to u + 1 and uvPixelStride to 2. I420 uses separate U and V
+ // planes with a uvPixelStride of 1.
+ struct VideoPlanes {
+
+ VideoColorMatrix colorMatrix;
+ bool fullRange;
+ int height;
+
+ // VideoDecoder tone maps frames with an HDR transfer, and BT.2020
+ // primaries, to standard range, unless the backend already has
+ VideoColorTransfer transfer;
+
+ const unsigned char* u;
+ int uvPixelStride;
+ int uvStride;
+ const unsigned char* v;
+ int width;
+ const unsigned char* y;
+ int yStride;
+
+ };
+
+
+ // Shows HDR frames in standard range, writing them as BT.709 video range
+ // NV12 through a table of what each luma and chroma become, which is built
+ // once for each kind of frame and kept
+ class VideoToneMapper {
+
+
+ public:
+
+ // Points planes at a tone mapped copy, which stays valid until the next
+ // call
+ void Map (VideoPlanes* planes);
+
+
+ private:
+
+ std::vector buffer;
+
+
+ };
+
+
+ // A decoded frame kept on the GPU by a backend that supports texture output
+ class VideoTextureFrame {
+
+
+ public:
+
+ virtual ~VideoTextureFrame () {};
+
+ int height;
+ int width;
+
+
+ };
+
+
+ // Where resampling has reached, carried from one packet of audio to the next
+ struct VideoAudioConverter {
+
+ VideoAudioConverter () : position (0), previousChannels (0) { previous[0] = previous[1] = 0; }
+
+ void Reset () { position = 0; previousChannels = 0; }
+
+ double position;
+ short previous[2];
+ int previousChannels;
+
+ };
+
+
+ struct VideoStreamInfo {
+
+ int audioChannels;
+ int audioSampleRate;
+
+ // Set when the file has a stream of that kind that cannot be decoded, such
+ // as one in a codec the platform lacks, so the video plays without it
+ bool audioUnsupported;
+
+ double duration;
+ double frameRate;
+ bool hasAudio;
+ bool hasVideo;
+ int height;
+
+ // The width of a pixel relative to its height, or 0 when unknown
+ double pixelAspectRatio;
+
+ // The clockwise rotation in degrees that shows frames upright, as phones
+ // record portrait video sideways with a rotation to apply
+ int rotation;
+
+ bool videoUnsupported;
+ int width;
+
+ };
+
+
+ // Platform decoding. VideoDecoder calls DecodeAudio and DecodeVideo from
+ // two threads at once, so the streams must not share decoder state. Open,
+ // Close and Seek are only called while neither stream is decoding.
+ class VideoBackend {
+
+
+ public:
+
+ virtual ~VideoBackend () {};
+
+ virtual void Close () = 0;
+
+ // Appends the next packet of interleaved signed 16-bit PCM with
+ // info->audioChannels channels to pcm, and sets time to the time of
+ // its first sample in seconds.
+ virtual VideoDecodeResult DecodeAudio (std::vector* pcm, double* time) = 0;
+
+ // Decodes the next frame. The planes stay valid until the next call to
+ // DecodeVideo, Seek or Close.
+ virtual VideoDecodeResult DecodeVideo (VideoPlanes* planes, double* time, double* duration) = 0;
+
+ // Called from another thread before Close, so a stream waiting on a
+ // stalled network source returns from DecodeAudio or DecodeVideo soon.
+ virtual void Interrupt () {}
+
+ virtual bool Open (const char* path, bool hardwareDecoding, VideoStreamInfo* info) = 0;
+
+ // Called from another thread when a seek is waiting for the streams, so
+ // a stream waiting on a stalled network source returns
+ // VIDEO_DECODE_AGAIN from DecodeAudio or DecodeVideo soon, rather than
+ // holding up the seek. Seek ends it, whether it succeeds or not.
+ virtual void PrepareSeek () {}
+
+ // Seeks both streams to the keyframe at or before time.
+ virtual bool Seek (double time) = 0;
+
+ // Texture output keeps frames on the GPU, which backends support by
+ // returning true from SupportsTextures once open. DecodeVideoTexture
+ // decodes the next frame like DecodeVideo, on the video thread. It
+ // returns VIDEO_DECODE_OK without a frame when it stops supporting
+ // textures, and the next frame is read with DecodeVideo.
+ virtual VideoDecodeResult DecodeVideoTexture (VideoTextureFrame** frame, double* time, double* duration) { return VIDEO_DECODE_ERROR; }
+ virtual bool SupportsTextures () { return false; }
+
+ // With the application's GL context current, makes a frame available
+ // as an RGBA GL_TEXTURE_2D until UnlockTexture, and returns its name,
+ // or 0 when this context cannot share the backend's textures.
+ virtual unsigned int LockTexture (VideoTextureFrame* frame) { return 0; }
+ virtual void UnlockTexture (VideoTextureFrame* frame) {}
+
+ // Gives a frame back to the backend, from any thread.
+ virtual void ReleaseTextureFrame (VideoTextureFrame* frame) {}
+
+ // Called before Open with whether frames will be read as textures, for
+ // backends that decode differently for texture output. When the
+ // application's context cannot use the backend's textures, it is
+ // called with false, followed by a Seek to where reading continues.
+ virtual void SetTextureOutput (bool enabled) {}
+
+ // Deletes the backend's GL objects, with the GL context current.
+ virtual void ReleaseTextures () {}
+
+ // Deletes the GL objects that backends of this kind left when they closed
+ // away from the GL thread, where their context is current. Called on the
+ // GL thread before each texture frame is read.
+ virtual void ReleaseOrphans () {}
+
+ static VideoBackend* Create ();
+ static bool IsSupported ();
+
+ // Appends interleaved signed 16-bit PCM with channels channels at rate to
+ // pcm, mixed to outChannels, 1 or 2, and resampled to outRate, for a
+ // stream whose format changes after opening
+ static void ConvertAudio (const short* in, int frames, int channels, int rate, int outChannels, int outRate, VideoAudioConverter* converter, std::vector* pcm);
+
+ static void DownmixToStereo (const short* in, int frames, int channels, std::vector* pcm);
+
+ // The GL context current on this thread, so backends can tell when the
+ // application's context is replaced, as Android does after losing it,
+ // or 0 when it is not known
+ static void* GetCurrentGLContext ();
+
+ static VideoColorMatrix GetDefaultColorMatrix (int width, int height);
+
+ // Turns a rotation in degrees into 0, 90, 180 or 270
+ static int NormalizeRotation (int degrees);
+
+
+ };
+
+
+ // Decodes a video on two background threads, one per stream, and queues
+ // a few frames and a fraction of a second of audio ahead of the reader.
+ class VideoDecoder {
+
+
+ public:
+
+ VideoDecoder (VideoBackend* backend);
+ ~VideoDecoder ();
+
+ void Close ();
+ bool Open (const char* path, bool hardwareDecoding, VideoFrameFormat format);
+
+ // Returns the number of bytes written, VIDEO_READ_NOT_READY when no
+ // audio is buffered yet, VIDEO_READ_END or VIDEO_READ_ERROR. Audio is
+ // interleaved signed 16-bit PCM.
+ int ReadAudio (unsigned char* data, int length);
+
+ // Copies the next frame in the open format and returns the number of
+ // bytes written. When time is not negative, frames that ended by time
+ // are dropped and a frame is only returned once it starts by time.
+ // Returns VIDEO_READ_NOT_READY when no frame is due, VIDEO_READ_END,
+ // VIDEO_READ_ERROR, or VIDEO_READ_BUFFER_TOO_SMALL when the frame needs
+ // frameLength bytes. The frame then stays queued.
+ //
+ // With VIDEO_FRAME_FORMAT_TEXTURE, call it with the GL context current.
+ // It returns 1 for a new frame, which frameTexture shows until the next
+ // call. Close the decoder on that thread too, so it can delete textures.
+ int ReadFrame (unsigned char* data, int length, double time);
+
+ // Seeks both streams. An accurate seek drops the frames and audio
+ // before time, otherwise reading resumes from the preceding keyframe.
+ // Seeking to the end or past it ends both streams. Returns false when
+ // the backend cannot seek, such as on a live stream, and decoding then
+ // carries on from where it was.
+ bool Seek (double time, bool accurate);
+
+ static int GetFrameLength (VideoFrameFormat format, int width, int height);
+ static int WriteFrame (const VideoPlanes* planes, VideoFrameFormat format, unsigned char* data, int length);
+
+ std::atomic audioTime;
+ std::atomic dropLateFrames;
+ std::atomic droppedFrames;
+ VideoFrameFormat format;
+ VideoColorMatrix frameColorMatrix;
+ double frameDuration;
+ bool frameFullRange;
+ int frameHeight;
+ int frameLength;
+ unsigned int frameTexture;
+ double frameTime;
+ int frameWidth;
+ VideoStreamInfo info;
+
+ private:
+
+ struct AudioChunk {
+
+ std::vector data;
+ size_t offset;
+ double time;
+
+ };
+
+ struct Frame {
+
+ VideoColorMatrix colorMatrix;
+ std::vector data;
+ double duration;
+ bool fullRange;
+ int height;
+ int length;
+ VideoTextureFrame* texture;
+ double time;
+ int width;
+
+ };
+
+ void AudioThread ();
+ void Flush ();
+ bool IsTextureThread ();
+ int ReadTexture (double time);
+ void ReleaseFrame (Frame* frame);
+ void ReleaseTextures ();
+ bool SeekStreams (double time, bool accurate, bool keepAudio);
+ void StartThreads ();
+ void StopThreads ();
+ void ThreadStopped ();
+ unsigned int UploadTexture (Frame* frame);
+ void VideoThread ();
+
+ std::deque audioChunks;
+ std::condition_variable audioCondition;
+ std::mutex audioDecodeMutex;
+ bool audioEnded;
+ bool audioError;
+ size_t audioQueued;
+ double audioQueueEnd;
+ double audioSeekTime;
+ std::thread audioThread;
+ VideoBackend* backend;
+ Frame* currentFrame;
+ std::vector freeChunks;
+ std::vector freeFrames;
+ std::deque frames;
+ std::chrono::steady_clock::time_point lastQueued;
+ std::mutex mutex;
+ bool open;
+ double presentationTime;
+ bool quit;
+ int runningThreads;
+ bool seekAccurate;
+ bool seekPending;
+ std::condition_variable stoppedCondition;
+ unsigned int texture;
+ void* textureContext;
+ int textureHeight;
+ std::atomic texturesFailed;
+ std::thread::id textureThread;
+ bool textureThreadKnown;
+ int textureWidth;
+ VideoToneMapper toneMapper;
+ std::condition_variable videoCondition;
+ std::mutex videoDecodeMutex;
+ bool videoEnded;
+ bool videoError;
+ double videoSeekTime;
+ std::thread videoThread;
+
+
+ };
+
+
+}
+
+
+#endif
diff --git a/project/include/system/CFFI.h b/project/include/system/CFFI.h
index ef22f49b9e..3442ea4a54 100644
--- a/project/include/system/CFFI.h
+++ b/project/include/system/CFFI.h
@@ -4,6 +4,8 @@
#define HL_NAME(n) lime_##n
#include
+// avoid conflicts with windows.h use of _GUID
+#undef _GUID
#undef DEFINE_PRIM
#define DEFINE_HL_PRIM(t, name, args) DEFINE_PRIM_WITH_NAME(t, name, args, name)
diff --git a/project/include/system/Locale.h b/project/include/system/Locale.h
index 21e0f7a6f5..702e18035e 100644
--- a/project/include/system/Locale.h
+++ b/project/include/system/Locale.h
@@ -13,6 +13,7 @@ namespace lime {
public:
static std::string* GetSystemLocale ();
+ static std::string* GetPreferredLocales ();
};
diff --git a/project/include/system/OrientationEvent.h b/project/include/system/OrientationEvent.h
index 09b078159a..399ef68b9a 100644
--- a/project/include/system/OrientationEvent.h
+++ b/project/include/system/OrientationEvent.h
@@ -12,7 +12,10 @@ namespace lime {
enum OrientationEventType {
DISPLAY_ORIENTATION_CHANGE,
- DEVICE_ORIENTATION_CHANGE
+ DEVICE_ORIENTATION_CHANGE,
+ DISPLAY_CONNECT,
+ DISPLAY_DISCONNECT,
+ DISPLAY_MOVE
};
diff --git a/project/include/text/Font.h b/project/include/text/Font.h
index 931f453a4b..b760f536fe 100644
--- a/project/include/text/Font.h
+++ b/project/include/text/Font.h
@@ -59,10 +59,16 @@ namespace lime {
int GetStrikethroughPosition ();
int GetStrikethroughThickness ();
int GetUnitsPerEM ();
+ bool IsBold ();
+ bool IsItalic ();
int RenderGlyph (int index, Bytes *bytes, int offset = 0);
int RenderGlyphWithFlags (int index, int loadFlags, Bytes *bytes, int offset = 0);
int RenderGlyphs (value indices, Bytes *bytes);
+ int RenderGlyphs (hl_varray* indices, Bytes *bytes);
+ int RenderGlyphs (const int* indices, int count, Bytes *bytes);
void SetSize (size_t size, size_t dpi);
+ void SetStemDarkening (bool enable);
+ void SetStemDarkeningParameters (int params[]);
void* library;
void* face;
diff --git a/project/include/ui/DockIcon.h b/project/include/ui/DockIcon.h
new file mode 100644
index 0000000000..3d0de0dce6
--- /dev/null
+++ b/project/include/ui/DockIcon.h
@@ -0,0 +1,28 @@
+#ifndef LIME_UI_DOCK_ICON_H
+#define LIME_UI_DOCK_ICON_H
+
+
+#include
+
+
+namespace lime {
+
+
+ class DockIcon {
+
+
+ public:
+
+ static void Bounce (bool critical);
+ static bool IsSupported ();
+ static void SetIcon (ImageBuffer* imageBuffer);
+ static bool SetMenu (const unsigned char* data, int length);
+
+
+ };
+
+
+}
+
+
+#endif
diff --git a/project/include/ui/FileDialog.h b/project/include/ui/FileDialog.h
index 4a310b3198..1adf918f7b 100644
--- a/project/include/ui/FileDialog.h
+++ b/project/include/ui/FileDialog.h
@@ -9,14 +9,36 @@
namespace lime {
+ // Functions in this class return pointers to externally owned memory, which will be reused automatically
+ // for future dialogs and should not be freed.
class FileDialog {
public:
- static std::wstring* OpenDirectory (std::wstring* title = 0, std::wstring* filter = 0, std::wstring* defaultPath = 0);
- static std::wstring* OpenFile (std::wstring* title = 0, std::wstring* filter = 0, std::wstring* defaultPath = 0);
- static void OpenFiles (std::vector* files, std::wstring* title = 0, std::wstring* filter = 0, std::wstring* defaultPath = 0);
- static std::wstring* SaveFile (std::wstring* title = 0, std::wstring* filter = 0, std::wstring* defaultPath = 0);
+#ifdef HX_WINDOWS
+ using char_t = wchar_t;
+#else
+ using char_t = char;
+#endif
+
+ static const char_t* OpenDirectory(const char_t* title = nullptr, const char_t* filter = nullptr, const char_t* defaultPath = nullptr);
+ static const char_t* OpenFile(const char_t* title = nullptr, const char_t* filter = nullptr, const char_t* defaultPath = nullptr);
+
+ // Use actual string view once we can use c++17
+ class string_view {
+ public:
+ string_view(const char_t* c_str, size_t length) : c_str(c_str), length(length) {}
+
+ const char_t* data() const { return c_str; }
+ size_t size() const { return length; }
+
+ private:
+ const char_t* c_str;
+ size_t length;
+ };
+
+ static std::vector OpenFiles(const char_t* title = nullptr, const char_t* filter = nullptr, const char_t* defaultPath = nullptr);
+ static const char_t* SaveFile(const char_t* title = nullptr, const char_t* filter = nullptr, const char_t* defaultPath = nullptr);
};
@@ -24,4 +46,4 @@ namespace lime {
}
-#endif
\ No newline at end of file
+#endif
diff --git a/project/include/ui/Gamepad.h b/project/include/ui/Gamepad.h
index 3396ca5e3e..3164ae73f4 100644
--- a/project/include/ui/Gamepad.h
+++ b/project/include/ui/Gamepad.h
@@ -13,6 +13,18 @@ namespace lime {
static const char* GetDeviceGUID (int id);
static const char* GetDeviceName (int id);
static void Rumble (int id, double lowFrequencyRumble, double highFrequencyRumble, int duration);
+ static int GetType (int id);
+ static bool HasLED (int id);
+ static bool HasRumbleTriggers (int id);
+ static bool HasSensor (int id, int sensor);
+ static bool RumbleTriggers (int id, double leftRumble, double rightRumble, int duration);
+ static bool SetLED (int id, int red, int green, int blue);
+ static bool SetSensorEnabled (int id, int sensor, bool enabled);
+
+ // A virtual gamepad for Lime's tests, which keeps what it is told to do
+ static int AttachVirtual ();
+ static void DetachVirtual (int id);
+ static bool GetVirtualOutput (int id, int* led, int* lowRumble, int* highRumble, int* leftRumble, int* rightRumble);
};
diff --git a/project/include/ui/GamepadEvent.h b/project/include/ui/GamepadEvent.h
index 607ef9cfc8..0223869c83 100644
--- a/project/include/ui/GamepadEvent.h
+++ b/project/include/ui/GamepadEvent.h
@@ -15,7 +15,11 @@ namespace lime {
GAMEPAD_BUTTON_DOWN,
GAMEPAD_BUTTON_UP,
GAMEPAD_CONNECT,
- GAMEPAD_DISCONNECT
+ GAMEPAD_DISCONNECT,
+ GAMEPAD_SENSOR_UPDATE,
+ GAMEPAD_TOUCHPAD_DOWN,
+ GAMEPAD_TOUCHPAD_MOVE,
+ GAMEPAD_TOUCHPAD_UP
};
@@ -28,6 +32,10 @@ namespace lime {
int id;
GamepadEventType type;
double axisValue;
+ int timestamp;
+ double x;
+ double y;
+ double z;
static ValuePointer* callback;
static ValuePointer* eventObject;
@@ -42,4 +50,4 @@ namespace lime {
}
-#endif
\ No newline at end of file
+#endif
diff --git a/project/include/ui/KeyEvent.h b/project/include/ui/KeyEvent.h
index 28e6fcc6fd..8d5ac047c0 100644
--- a/project/include/ui/KeyEvent.h
+++ b/project/include/ui/KeyEvent.h
@@ -25,6 +25,7 @@ namespace lime {
int modifier;
KeyEventType type;
int windowID;
+ int timestamp;
static ValuePointer* callback;
static ValuePointer* eventObject;
@@ -39,4 +40,4 @@ namespace lime {
}
-#endif
\ No newline at end of file
+#endif
diff --git a/project/include/ui/Menu.h b/project/include/ui/Menu.h
new file mode 100644
index 0000000000..93ab6cd49f
--- /dev/null
+++ b/project/include/ui/Menu.h
@@ -0,0 +1,29 @@
+#ifndef LIME_UI_MENU_H
+#define LIME_UI_MENU_H
+
+
+namespace lime {
+
+
+ enum MenuSupport {
+
+ MENU_SUPPORT_POPUP = 0x01,
+ MENU_SUPPORT_WINDOW = 0x02,
+ MENU_SUPPORT_APPLICATION = 0x04
+
+ };
+
+
+ class Menu {
+
+ public:
+
+ static int GetSupport ();
+
+ };
+
+
+}
+
+
+#endif
diff --git a/project/include/ui/MenuEvent.h b/project/include/ui/MenuEvent.h
new file mode 100644
index 0000000000..1dde1b3daf
--- /dev/null
+++ b/project/include/ui/MenuEvent.h
@@ -0,0 +1,40 @@
+#ifndef LIME_UI_MENU_EVENT_H
+#define LIME_UI_MENU_EVENT_H
+
+
+#include
+#include
+
+
+namespace lime {
+
+
+ enum MenuEventType {
+
+ MENU_SELECT,
+ MENU_DOCK_SELECT
+
+ };
+
+
+ struct MenuEvent {
+
+ hl_type* t;
+ int id;
+ MenuEventType type;
+ int windowID;
+
+ static ValuePointer* callback;
+ static ValuePointer* eventObject;
+
+ MenuEvent ();
+
+ static void Dispatch (MenuEvent* event);
+
+ };
+
+
+}
+
+
+#endif
diff --git a/project/include/ui/TrayIcon.h b/project/include/ui/TrayIcon.h
new file mode 100644
index 0000000000..94751e16f6
--- /dev/null
+++ b/project/include/ui/TrayIcon.h
@@ -0,0 +1,37 @@
+#ifndef LIME_UI_TRAY_ICON_H
+#define LIME_UI_TRAY_ICON_H
+
+
+#include
+
+
+namespace lime {
+
+
+ class TrayIcon {
+
+
+ public:
+
+ virtual ~TrayIcon () {};
+
+ virtual void Close () = 0;
+ virtual int GetID () = 0;
+ virtual int PopupMenu (const unsigned char* data, int length) = 0;
+ virtual void SetIcon (ImageBuffer* imageBuffer) = 0;
+ virtual bool SetMenu (const unsigned char* data, int length) = 0;
+ virtual void SetTooltip (const char* tooltip) = 0;
+
+ static bool IsSupported ();
+
+
+ };
+
+
+ TrayIcon* CreateTrayIcon ();
+
+
+}
+
+
+#endif
diff --git a/project/include/ui/TrayIconEvent.h b/project/include/ui/TrayIconEvent.h
new file mode 100644
index 0000000000..adcbf481c0
--- /dev/null
+++ b/project/include/ui/TrayIconEvent.h
@@ -0,0 +1,41 @@
+#ifndef LIME_UI_TRAY_ICON_EVENT_H
+#define LIME_UI_TRAY_ICON_EVENT_H
+
+
+#include
+#include
+
+
+namespace lime {
+
+
+ enum TrayIconEventType {
+
+ TRAY_ICON_CLICK,
+ TRAY_ICON_MENU_SELECT,
+ TRAY_ICON_RIGHT_CLICK
+
+ };
+
+
+ struct TrayIconEvent {
+
+ hl_type* t;
+ int id;
+ int itemID;
+ TrayIconEventType type;
+
+ static ValuePointer* callback;
+ static ValuePointer* eventObject;
+
+ TrayIconEvent ();
+
+ static void Dispatch (TrayIconEvent* event);
+
+ };
+
+
+}
+
+
+#endif
diff --git a/project/include/ui/Window.h b/project/include/ui/Window.h
index 04321be0b2..7c2c67fa78 100644
--- a/project/include/ui/Window.h
+++ b/project/include/ui/Window.h
@@ -11,8 +11,13 @@
#include