diff --git a/.gitignore b/.gitignore
index 212d66b59..d22e46efb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -83,20 +83,20 @@ xcschememanagement.plist
xcuserdata/
DerivedData/
-# external libraries DLLs
-!src/external/glfw3/lib/win32/glfw3.dll
-!src/external/openal_soft/lib/win32/OpenAL32.dll
-
# Visual Studio project
project/vs2015/*.db
project/vs2015/*.opendb
+project/vs2015.UWP/packages
+project/vs2015.UWP/*.db
!project/vs2015/raylib.sln
!project/vs2015/raylib/*.vcxproj
!project/vs2015/examples/*.vcxproj
-!project/vs2015/external/glfw3/lib/win32/glfw3.dll
-!project/vs2015/external/openal_soft/lib/win32/OpenAL32.dll
-!project/vs2015/external/openal_soft/lib/win64/OpenAL32.dll
-!project/vs2015/external/lua/lib/win32/lua53.dll
+!project/vs2017/raylib.sln
+!project/vs2017/raylib/*.vcxproj
+!project/vs2017/examples/*.vcxproj
+!project/vs2015.UWP/raylib/*.vcxproj
+!project/vs2015.UWP/*.sln
+!project/vs2015.UWP/raylib.App.UWP/*.vcxproj
# Web examples
docs/examples/web/*.html
@@ -111,15 +111,11 @@ docs/examples/web/*/*.html
!docs/examples/web/shaders/loader.html
!docs/examples/web/models/loader.html
-# Meson build system
-builddir/
-
# CMake stuff
CMakeCache.txt
CMakeFiles
CMakeScripts
Testing
-Makefile
cmake_install.cmake
install_manifest.txt
compile_commands.json
@@ -133,3 +129,8 @@ build
# Ignore Android generated files and folders
templates/android_project/output
+
+# Ignore GNU global tags
+GPATH
+GRTAGS
+GTAGS
diff --git a/.travis.yml b/.travis.yml
index 703206e2d..5037a717d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,50 +1,62 @@
language: c
-sudo: required
dist: trusty
git:
depth: 3
-os:
- - osx
- - linux
+# TODO we could use a 32 bit Docker container for running true 32-bit tests
+# services: - docker
-env:
- global:
- - VERBOSE=1
- matrix:
- - CFLAGS=-m64
- - CFLAGS=-m32
+matrix:
+ include:
+ - os: linux
+ env: ARCH=i386
+ sudo: required
+ - os: linux
+ env: ARCH=amd64
+ sudo: required
+ - os: osx
+ env: ARCH=universal
before_script:
- - export CFLAGS="-std=gnu99 $CFLAGS"
before_install:
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then
sudo apt-get install -y gcc-multilib
- libopenal-dev
- libxcursor-dev libxinerama-dev
- mesa-common-dev libx11-dev libxrandr-dev libxi-dev xorg-dev libgl1-mesa-dev libglu1-mesa-dev libglew-dev;
- wget 'https://github.com/a3f/GLFW-3.2.1-Debian-binary-package/releases/download/v3.2.1/GLFW-3.2.1-Linux.deb' && sudo dpkg -i GLFW-3.2.1-Linux.deb;
+ libasound2-dev:$ARCH
+ libxcursor-dev:$ARCH libxinerama-dev:$ARCH mesa-common-dev:$ARCH
+ libx11-dev:$ARCH libxrandr-dev:$ARCH libxi-dev:$ARCH
+ libgl1-mesa-dev:$ARCH libglu1-mesa-dev:$ARCH;
+ export RAYLIB_PACKAGE_SUFFIX="-Linux-$ARCH";
+ if [ "$ARCH" == "i386" ]; then export CFLAGS="-m32"; fi;
+ if [ "$ARCH" == "amd64" ]; then export CFLAGS="-m64"; fi;
+ if [ "$GLFW" == "SYSTEM" ]; then
+ wget 'http://ftp.de.debian.org/debian/pool/main/g/glfw3/libglfw3_3.2.1-1_amd64.deb';
+ wget 'http://ftp.de.debian.org/debian/pool/main/g/glfw3/libglfw3-dev_3.2.1-1_amd64.deb';
+ sudo dpkg -i libglfw3_3.2.1-1_amd64.deb libglfw3-dev_3.2.1-1_amd64.deb;
+ fi;
+ fi
+ - if [ "$TRAVIS_OS_NAME" == "osx" ]; then
+ export RAYLIB_PACKAGE_SUFFIX="-macOS";
+ if [ "$GLFW" == "SYSTEM" ]; then brew update; brew install glfw; fi;
fi
- - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew update; brew install glfw; fi
- "$CC --version"
script:
- mkdir build
- cd build
- - cmake -DBUILD_EXAMPLES=OFF -DBUILD_GAMES=OFF ..
- - make
-# - make package
-# - sudo make install
-#
-#deploy:
-# provider: releases
-# api_key:
-# secure: XXX
-# file_glob: true
-# file: raylib-*.tar.gz
-# skip_cleanup: true
-# on:
-# branch: master
-# tags: true
+ - cmake -DMACOS_FATLIB=ON -DSTATIC=ON -DSHARED=ON -DBUILD_EXAMPLES=ON -DBUILD_GAMES=ON -DUSE_EXTERNAL_GLFW=IF_POSSIBLE ..
+ - make VERBOSE=1
+ - make package
+
+deploy:
+ provider: releases
+ api_key:
+ secure: LvqUIAN/3dJul+Ra2iK3tSaNG5IwsNMmGIwVMy0DK5IBCxiQPBc9pWGiE30RTBPt6Z+N4BhMEE8DtUl+vnISlMoHWNIIhF2zwC66hs/F7zY7qEITMRSmfiLcqxQysknFOnJB06CATgXcFqlEo9j+t4abrG/f3qcb92J4O2uNz336Au2myTx93Q5MxbyA7KiUuEutFnb2dWiPCY4d+sGeXEfsiD2R7aj/8MaWOkoGdZVrTkI9juMgvpImkjQBArvqdjUMeT3MsRrwgOIq5v2GFV9dOl8k1WzPeT8B2JHh00ed/o1/wuFq/cLLOxtYo2+Pv3+xatOrlexoX0WkDm7C9/L1W5U4rLexU3CQ9mMBmHPnp6k/WXZ5QXEE4uUF0+LpN3XlIXzFpdZmZiVV8VLxg2WvyncMmivYiu7/MTkyfZxyKkzwl7sZZslzHA9kOGedGaN7b7/2B77OFHoQK8lKfdFml7jJnarh+89nenNZYMab0E8qkOJOyb2bYlDTa0/2nyxGiyymYgq6YHLNrDbhqB/1LzdgzjMliQ8ri5q9Ux2vjfcqOzhfAmcwFwnY/D6yXJWYi0DWpHZdpKl3du6dYDrypW91/yDWbwiJ/YhrE7ZunzrcB6GH/QkbuzWxdCth39rQAHih8DG01co/K3Gvi4yGjvIH5tFUpyEolMnpMiA=
+ file_glob: true
+ file: raylib-*.tar.gz
+ skip_cleanup: true
+ on:
+ repo: raysan5/raylib
+ branch: master
+ tags: true
diff --git a/CMakeLists.txt b/CMakeLists.txt
old mode 100644
new mode 100755
index 0dfa0857f..6d5994f4f
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,8 +1,54 @@
cmake_minimum_required(VERSION 3.0)
# Config options
-set(BUILD_EXAMPLES ON CACHE BOOL "Build the examples.")
-set(BUILD_GAMES ON CACHE BOOL "Build the example games.")
+option(BUILD_EXAMPLES "Build the examples." ON)
+option(BUILD_GAMES "Build the example games." ON)
+option(ENABLE_ASAN "Enable AddressSanitizer (ASAN) for debugging (degrades performance)" OFF)
+option(ENABLE_UBSAN "Enable UndefinedBehaviorSanitizer (UBSan) for debugging" OFF)
+option(ENABLE_MSAN "Enable MemorySanitizer (MSan) for debugging (not recommended for run with ASAN)" OFF)
+
+if(CMAKE_VERSION VERSION_LESS "3.1")
+ if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
+ set(CMAKE_C_FLAGS "-std=gnu99 ${CMAKE_C_FLAGS}")
+ endif()
+else()
+ set (CMAKE_C_STANDARD 99)
+endif()
+
+include(CheckCCompilerFlag)
+function(add_if_flag_works flag)
+ CHECK_C_COMPILER_FLAG("${flag}" COMPILER_HAS_THOSE_TOGGLES)
+ set(outcome "Failed")
+ if(COMPILER_HAS_THOSE_TOGGLES)
+ foreach(var ${ARGN})
+ set(${var} "${flag} ${${var}}" PARENT_SCOPE)
+ endforeach()
+ set(outcome "works")
+ endif()
+ message(STATUS "Testing if ${flag} can be used -- ${outcome}")
+endfunction()
+
+add_if_flag_works(-Werror=pointer-arith CMAKE_C_FLAGS)
+add_if_flag_works(-Werror=implicit-function-declaration CMAKE_C_FLAGS)
+# src/external/jar_xm.h does shady stuff
+add_if_flag_works(-fno-strict-aliasing CMAKE_C_FLAGS)
+
+if (ENABLE_ASAN)
+ add_if_flag_works(-fno-omit-frame-pointer CMAKE_C_FLAGS CMAKE_LINKER_FLAGS)
+ add_if_flag_works(-fsanitize=address CMAKE_C_FLAGS CMAKE_LINKER_FLAGS)
+endif()
+if (ENABLE_UBSAN)
+ add_if_flag_works(-fno-omit-frame-pointer CMAKE_C_FLAGS CMAKE_LINKER_FLAGS)
+ add_if_flag_works(-fsanitize=undefined CMAKE_C_FLAGS CMAKE_LINKER_FLAGS)
+endif()
+if (ENABLE_MSAN)
+ add_if_flag_works(-fno-omit-frame-pointer CMAKE_C_FLAGS CMAKE_LINKER_FLAGS)
+ add_if_flag_works(-fsanitize=memory CMAKE_C_FLAGS CMAKE_LINKER_FLAGS)
+endif()
+
+if (ENABLE_MSAN AND ENABLE_ASAN)
+ MESSAGE(WARNING "Compiling with both AddressSanitizer and MemorySanitizer is not recommended")
+endif()
add_subdirectory(src release)
@@ -13,4 +59,3 @@ endif()
if (${BUILD_GAMES})
add_subdirectory(games)
endif()
-
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 000000000..28a853a96
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,128 @@
+## Contributing to raylib
+
+Hello contributors! Welcome to raylib!
+
+This document contains a set of guidelines to contribute to the project. These are mostly guidelines, not rules.
+Use your best judgement, and feel free to propose changes to this document in a pull-request.
+
+### raylib philosophy
+
+ - raylib is a tool to LEARN videogames programming, every single function in raylib should be a tutorial on itself.
+ - raylib is SIMPLE and EASY-TO-USE, I tried to keep it compact with a small set of functions, if a function is too complex or is not clearly useful, better not to include it.
+ - raylib is open source and free; educators and institutions can use this tool to TEACH videogames programming completely by free.
+ - raylib is collaborative; contribution of tutorials / code-examples / bugs-solving / code-comments are highly appreciated.
+ - raylib's license (and its external libs respective licenses) allow using it for commercial products.
+
+### Some interesting reads to start with
+
+ - [raylib history](HISTORY.md)
+ - [raylib architecture](https://github.com/raysan5/raylib/wiki/raylib-architecture)
+ - [raylib license](LICENSE.md)
+ - [raylib roadmap](ROADMAP.md)
+
+[raylib Wiki](https://github.com/raysan5/raylib/wiki) contains some information about the library and is open to anyone for edit.
+Feel free to review it if required, just take care not to break anything.
+
+### raylib C coding conventions
+
+Despite being written in C, raylib does not follow the standard Hungarian notation for C,
+it [follows Pascal-case/camel-case notation](https://github.com/raysan5/raylib/wiki/raylib-coding-conventions),
+more common on C# language. All code formatting decisions have been carefully taken
+to make it easier for students to read, write and understand code.
+
+Source code is extensively commented for that purpose, raylib primary learning method is:
+
+ > learn by reading code and examples
+
+For detailed information on building raylib and examples, please check [raylib Wiki](https://github.com/raysan5/raylib/wiki).
+
+### Opening new Issues
+
+To open new issue for raylib (bug, enhancement, discussion...), just try to follow these rules:
+
+ - Make sure the issue has not already been reported before by searching on GitHub under Issues.
+ - If you're unable to find an open issue addressing the problem, open a new one. Be sure to include a
+ title and clear description, as much relevant information as possible, and a code sample demonstrating the unexpected behavior.
+ - If applies, attach some screenshot of the issue and a .zip file with the code sample and required resources.
+ - On issue description, add a brackets tag about the raylib module that relates to this issue.
+ If don't know the module, just report the issue, I will review it.
+ - You can check other issues to see how is being done!
+
+### Sending a Pull-Request
+
+ - Make sure the PR description clearly describes the problem and solution. Include the relevant issue number if applicable.
+ - Don't send big pull-requests (lots of changelists), they are difficult to review. It's better to send small pull-request, one at a time.
+ - Verify that changes don't break the build (at least on Windows platform). As many platforms where you can test it, the better, but don't worry
+ if you cannot test all the platforms.
+
+### raylib bindings
+
+Some people ported raylib to other languages in form of bindings or wrappers to the library, here is a list with the ones I'm aware of:
+
+ - [raylib C/C++ version (default)](https://github.com/raysan5/raylib)
+ - [raylib Lua binding](https://github.com/raysan5/raylib-lua)
+ - [raylib Go binding](https://github.com/gen2brain/raylib-go)
+ - [raylib Nim binding](https://gitlab.com/define-private-public/raylib-Nim)
+ - [raylib Crystal binding](https://gitlab.com/Zatherz/cray)
+ - [raylib Perl wrapper](https://metacpan.org/pod/Graphics::Raylib)
+ - raylib Pascal binding with custom IDE (closed-source)
+
+Usually, raylib bindings follow the convention: `raylib-{language}`
+
+Let me know if you're writing a new binding for raylib, I will list it here and I usually
+provide the icon/logo for that new language binding.
+
+### Contact information
+
+If you have any doubt, don't hesitate to [contact me](mailto:ray@raylib.com)!.
+You can write me a direct mail but you can also contact me on the following networks:
+
+ - [raylib forum](http://forum.raylib.com/) - A good place for discussions or to ask for help.
+ - [raylib gitter](https://gitter.im/raylib) - A direct communication channel for project discussions.
+ - [raylib twitter](https://twitter.com/raysan5) - My personal twitter account, I usually post about raylib, you can send me PMs.
+ - [raylib web](http://www.raylib.com/) - On top-right corner there is a bunch of networks where you can find me.
+
+Thank you very much for your time! :)
+
+----
+
+Here is a list of raylib contributors, these people have invested part of their time
+contributing (in some way or another) to make the raylib project better. Huge thanks to all of them!
+
+ - [Zopokx](https://github.com/Zopokx) for testing the web.
+ - [Elendow](http://www.elendow.com) for testing and helping on web development.
+ - Victor Dual for implementing and testing 3D shapes functions.
+ - Marc Palau for implementing and testing 3D shapes functions and contribute on camera and gestures modules.
+ - Kevin Gato for improving texture internal formats support and helping on raygui development.
+ - Daniel Nicolas for improving texture internal formats support and helping on raygui development.
+ - Marc Agüera for testing and using raylib on a real product ([Koala Seasons](http://www.koalaseasons.com))
+ - Daniel Moreno for testing and using raylib on a real product ([Koala Seasons](http://www.koalaseasons.com))
+ - Daniel Gomez for testing and using raylib on a real product ([Koala Seasons](http://www.koalaseasons.com))
+ - [Sergio Martinez](https://github.com/anidealgift) for helping on raygui development and tools development (raygui_styler).
+ - [Victor Fisac](https://github.com/victorfisac) for developing physics raylib module (physac) and implementing PBR materials and lighting systems... among multiple other improvements and multiple tools and games.
+ - Albert Martos for helping on raygui and porting examples and game-templates to Android and HTML5.
+ - Ian Eito for helping on raygui and porting examples and game-templates to Android and HTML5.
+ - [procedural](https://github.com/procedural) for testing raylib on Linux, correcting some bugs and adding several mouse functions.
+ - [Chris Hemingway](https://github.com/cHemingway) for improving raylib on OSX build system.
+ - [Emanuele Petriglia](https://github.com/LelixSuper) for working on multiple GNU/Linux improvements and developing [TicTacToe](https://github.com/LelixSuper/TicTacToe) raylib game.
+ - [Joshua Reisenauer](https://github.com/kd7tck) for adding audio modules support (XM, MOD) and reviewing audio system.
+ - [Marcelo Paez](https://github.com/paezao) for his help on OSX to solve High DPI display issue. Thanks Marcelo!
+ - [Ghassan Al-Mashareqa](https://github.com/ghassanpl) for his amazing contribution with raylib Lua module, I just work over his code to implement [rlua](https://github.com/raysan5/raylib/blob/master/src/rlua.h)
+ - [Teodor Stoenescu](https://github.com/teodor-stoenescu) for his improvements on OBJ object loading.
+ - [RDR8](https://github.com/RDR8) for helping with Linux build improvements
+ - [Saggi Mizrahi](https://github.com/ficoos) for multiple fixes on Linux and audio system
+ - [Daniel Lemos](https://github.com/xspager) for fixing issues on Linux games building
+ - [Joel Davis](https://github.com/joeld42) for adding raycast picking utilities and a [great example](https://github.com/raysan5/raylib/blob/master/examples/models/models_mesh_picking.c)
+ - [Richard Goodwin](https://github.com/AudioMorphology) for adding RPI touchscreen support
+ - [Milan Nikolic](https://github.com/gen2brain) for adding Android build support with custom standalone toolchain
+ - [Michael Vetter](https://github.com/jubalh) for improvements on build system and adding meson support for Linux
+ - [Wilhem Barbier](https://github.com/nounoursheureux) for adding Image generation functions and some fixes
+ - [Benjamin Summerton](https://github.com/define-private-public) for improving OSX building and his amazing work on CMake build sytem
+ - [MartinFX](https://github.com/Martinfx) for adding compilation support for FreeBSD OS
+ - [Wilhem Barbier](https://github.com/nounoursheureux) for supporting default shaders on shader loading, if shader not provided
+ - [Ahmad Fatoum](https://github.com/a3f) for implementing continuus integration support for raylib (Travis and AppVeyor) and greatly improving build system.
+ - [SamNChiet](https://github.com/SamNChiet) for his work on UWP inputs implementation.
+ - [David Reid](https://github.com/mackron) for a complete review of audio module to support his amazing mini_al audio library.
+ - [Kai](https://github.com/questor) for multiple code reviews and improvements.
+
+Please, if I forget someone in this list, excuse me and write me an email to remind me to add you!
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
deleted file mode 100644
index a31f0e1f5..000000000
--- a/CONTRIBUTORS.md
+++ /dev/null
@@ -1,35 +0,0 @@
-
-I believe that time is the most valuable resource and the following people have invested part of their time
-contributing (in some way or another) to make raylib project better. Huge thanks!
-
- - [Zopokx](https://github.com/Zopokx) for testing the web.
- - [Elendow](http://www.elendow.com) for testing and helping on web development.
- - Victor Dual for implementing and testing 3D shapes functions.
- - Marc Palau for implementing and testing 3D shapes functions and contribute on camera and gestures modules.
- - Kevin Gato for improving texture internal formats support and helping on raygui development.
- - Daniel Nicolas for improving texture internal formats support and helping on raygui development.
- - Marc Agüera for testing and using raylib on a real product ([Koala Seasons](http://www.koalaseasons.com))
- - Daniel Moreno for testing and using raylib on a real product ([Koala Seasons](http://www.koalaseasons.com))
- - Daniel Gomez for testing and using raylib on a real product ([Koala Seasons](http://www.koalaseasons.com))
- - [Sergio Martinez](https://github.com/anidealgift) for helping on raygui development and tools development (raygui_styler).
- - [Victor Fisac](https://github.com/victorfisac) for developing physics raylib module (physac) and implementing PBR materials and lighting systems... among multiple other improvements and multiple tools and games.
- - Albert Martos for helping on raygui and porting examples and game-templates to Android and HTML5.
- - Ian Eito for helping on raygui and porting examples and game-templates to Android and HTML5.
- - [procedural](https://github.com/procedural) for testing raylib on Linux, correcting some bugs and adding several mouse functions.
- - [Chris Hemingway](https://github.com/cHemingway) for improving raylib on OSX build system.
- - [Emanuele Petriglia](https://github.com/LelixSuper) for working on multiple GNU/Linux improvements and developing [TicTacToe](https://github.com/LelixSuper/TicTacToe) raylib game.
- - [Joshua Reisenauer](https://github.com/kd7tck) for adding audio modules support (XM, MOD) and reviewing audio system.
- - [Marcelo Paez](https://github.com/paezao) for his help on OSX to solve High DPI display issue. Thanks Marcelo!
- - [Ghassan Al-Mashareqa](https://github.com/ghassanpl) for his amazing contribution with raylib Lua module, I just work over his code to implement [rlua](https://github.com/raysan5/raylib/blob/master/src/rlua.h)
- - [Teodor Stoenescu](https://github.com/teodor-stoenescu) for his improvements on OBJ object loading.
- - [RDR8](https://github.com/RDR8) for helping with Linux build improvements
- - [Saggi Mizrahi](https://github.com/ficoos) for multiple fixes on Linux and audio system
- - [Daniel Lemos](https://github.com/xspager) for fixing issues on Linux games building
- - [Joel Davis](https://github.com/joeld42) for adding raycast picking utilities and a [great example](https://github.com/raysan5/raylib/blob/master/examples/models/models_mesh_picking.c)
- - [Richard Goodwin](https://github.com/AudioMorphology) for adding RPI touchscreen support
- - [Milan Nikolic](https://github.com/gen2brain) for adding Android build support with custom standalone toolchain
- - [Michael Vetter](https://github.com/jubalh) for improvements on build system and adding meson support for Linux
- - [Wilhem Barbier](https://github.com/nounoursheureux) for adding Image generation functions and some fixes
- - [Benjamin Summerton](https://github.com/define-private-public) for improving OSX building and his amazing work on CMake build sytem
-
-Please, if I forget someone in this list, excuse me and write me an email to remind me to add you!
diff --git a/HISTORY.md b/HISTORY.md
index caff6a3d1..c72014a9b 100644
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -73,12 +73,12 @@ attached to 3d models or used as fullscreen postrocessing effects. A bunch of po
in this release, check raylib/shaders folder.
Textures module has grown to support most of the internal texture formats available in OpenGL (RGB565, RGB888, RGBA5551, RGBA4444, etc.), including compressed texture formats (DXT, ETC1, ETC2, ASTC, PVRT); raylib 1.3 can load .dds, .pkm, .ktx, .astc and .pvr files.
-A brand new [camera](https://github.com/raysan5/raylib/blob/develop/src/camera.c) module offers to the user multiple preconfigured ready-to-use camera systems (free camera, 1st person, 3rd person).
-Camera modes are very easy to use, just check examples: [core_3d_camera_free.c](https://github.com/raysan5/raylib/blob/develop/examples/core_3d_camera_free.c) and [core_3d_camera_first_person.c](https://github.com/raysan5/raylib/blob/develop/examples/core_3d_camera_first_person.c).
+A brand new [camera](https://github.com/raysan5/raylib/blob/master/src/camera.c) module offers to the user multiple preconfigured ready-to-use camera systems (free camera, 1st person, 3rd person).
+Camera modes are very easy to use, just check examples: [core_3d_camera_free.c](https://github.com/raysan5/raylib/blob/master/examples/core_3d_camera_free.c) and [core_3d_camera_first_person.c](https://github.com/raysan5/raylib/blob/master/examples/core_3d_camera_first_person.c).
-New [gestures](https://github.com/raysan5/raylib/blob/develop/src/gestures.h) module simplifies gestures detection on Android and HTML5 programs.
+New [gestures](https://github.com/raysan5/raylib/blob/master/src/gestures.h) module simplifies gestures detection on Android and HTML5 programs.
-[raygui](https://github.com/raysan5/raylib/blob/develop/src/raygui.h), the new IMGUI (Immediate Mode GUI) module offers a set of functions to create simple user interfaces,
+[raygui](https://github.com/raysan5/raylib/blob/master/src/raygui.h), the new IMGUI (Immediate Mode GUI) module offers a set of functions to create simple user interfaces,
primary intended for tools development. It's still in experimental state but already fully functional.
Most of the examples have been completely rewritten and +10 new examples have been added to show the new raylib features.
@@ -91,18 +91,18 @@ notes on raylib 1.4
On February 2016, after 4 months of raylib 1.3 release, it comes raylib 1.4. For this new version,
lots of parts of the library have been reviewed, lots of bugs have been solved and some interesting features have been added.
-First big addition is a set of [Image manipulation functions](https://github.com/raysan5/raylib/blob/develop/src/raylib.h#L673) have been added to crop, resize, colorize, flip, dither and even draw image-to-image or text-to-image.
+First big addition is a set of [Image manipulation functions](https://github.com/raysan5/raylib/blob/master/src/raylib.h#L673) have been added to crop, resize, colorize, flip, dither and even draw image-to-image or text-to-image.
Now a basic image processing can be done before converting the image to texture for usage.
SpriteFonts system has been improved, adding support for AngelCode fonts (.fnt) and TrueType Fonts (using [stb_truetype](https://github.com/nothings/stb/blob/master/stb_truetype.h) helper library).
Now raylib can read standard .fnt font data and also generate at loading a SpriteFont from a TTF file.
-New [physac](https://github.com/raysan5/raylib/blob/develop/src/physac.h) physics module for basic 2D physics support. Still in development but already functional.
+New [physac](https://github.com/raysan5/raylib/blob/master/src/physac.h) physics module for basic 2D physics support. Still in development but already functional.
Module comes with some usage examples for basic jump and level interaction and also force-based physic movements.
-[raymath](https://github.com/raysan5/raylib/blob/develop/src/raymath.h) module has been reviewed; some bugs have been solved and the module has been converted to a header-only file for easier portability, optionally, functions can also be used as inline.
+[raymath](https://github.com/raysan5/raylib/blob/master/src/raymath.h) module has been reviewed; some bugs have been solved and the module has been converted to a header-only file for easier portability, optionally, functions can also be used as inline.
-[gestures](https://github.com/raysan5/raylib/blob/develop/src/gestures.c) module has redesigned and simplified, now it can process touch events from any source, including mouse.
+[gestures](https://github.com/raysan5/raylib/blob/master/src/gestures.c) module has redesigned and simplified, now it can process touch events from any source, including mouse.
This way, gestures system can be used on any platform providing an unified way to work with inputs and allowing the user to create multiplatform games with only one source code.
Raspberry Pi input system has been redesigned to better read raw inputs using generic Linux event handlers (keyboard:`stdin`, mouse:`/dev/input/mouse0`, gamepad:`/dev/input/js0`).
@@ -110,7 +110,7 @@ Gamepad support has also been added (experimental).
Other important improvements are the functional raycast system for 3D picking, including some ray collision-detection functions,
and the addition of two simple functions for persistent data storage. Now raylib user can save and load game data in a file (only some platforms supported).
-A simple [easings](https://github.com/raysan5/raylib/blob/develop/src/easings.h) module has also been added for values animation.
+A simple [easings](https://github.com/raysan5/raylib/blob/master/src/easings.h) module has also been added for values animation.
Up to 8 new code examples have been added to show the new raylib features and +10 complete game samples have been provided to learn
how to create some classic games like Arkanoid, Asteroids, Missile Commander, Snake or Tetris.
@@ -122,7 +122,7 @@ notes on raylib 1.5
On July 2016, after 5 months of raylib 1.4 release, arrives raylib 1.5. This new version is the biggest boost of the library until now, lots of parts of the library have been redesigned, lots of bugs have been solved and some **AMAZING** new features have been added.
-VR support: raylib supports **Oculus Rift CV1**, one of the most anticipated VR devices in the market. Additionally, raylib supports simulated VR stereo rendering, independent of the VR device; it means, raylib can generate stereo renders with custom head-mounted-display device parameteres, that way, any VR device in the market can be **simulated in any platform** just configuring device parameters (and consequently, lens distortion). To enable VR is [extremely easy](https://github.com/raysan5/raylib/blob/develop/examples/core_oculus_rift.c).
+VR support: raylib supports **Oculus Rift CV1**, one of the most anticipated VR devices in the market. Additionally, raylib supports simulated VR stereo rendering, independent of the VR device; it means, raylib can generate stereo renders with custom head-mounted-display device parameteres, that way, any VR device in the market can be **simulated in any platform** just configuring device parameters (and consequently, lens distortion). To enable VR is [extremely easy](https://github.com/raysan5/raylib/blob/master/examples/core_oculus_rift.c).
New materials system: now raylib supports standard material properties for 3D models, including diffuse-ambient-specular colors and diffuse-normal-specular textures. Just assign values to standard material and everything is processed internally.
@@ -130,15 +130,15 @@ New lighting system: added support for up to 8 configurable lights and 3 light t
Complete gamepad support on Raspberry Pi: Gamepad system has been completely redesigned. Now multiple gamepads can be easily configured and used; gamepad data is read and processed in raw mode in a second thread.
-Redesigned physics module: [physac](https://github.com/raysan5/raylib/blob/develop/src/physac.h) module has been converted to header only and usage [has been simplified](https://github.com/raysan5/raylib/blob/develop/examples/physics_basic_rigidbody.c). Performance has also been singnificantly improved, now physic objects are managed internally in a second thread.
+Redesigned physics module: [physac](https://github.com/raysan5/raylib/blob/master/src/physac.h) module has been converted to header only and usage [has been simplified](https://github.com/raysan5/raylib/blob/master/examples/physics_basic_rigidbody.c). Performance has also been singnificantly improved, now physic objects are managed internally in a second thread.
Audio chiptunese support and mixing channels: Added support for module audio music (.xm, .mod) loading and playing. Multiple mixing channels are now also supported. All this features thanks to the amazing work of @kd7tck.
-Other additions include a [2D camera system](https://github.com/raysan5/raylib/blob/develop/examples/core_2d_camera.c), render textures for offline render (and most comprehensive [postprocessing](https://github.com/raysan5/raylib/blob/develop/examples/shaders_postprocessing.c)) or support for legacy OpenGL 2.1 on desktop platforms.
+Other additions include a [2D camera system](https://github.com/raysan5/raylib/blob/master/examples/core_2d_camera.c), render textures for offline render (and most comprehensive [postprocessing](https://github.com/raysan5/raylib/blob/master/examples/shaders_postprocessing.c)) or support for legacy OpenGL 2.1 on desktop platforms.
-This new version is so massive that is difficult to list all the improvements, most of raylib modules have been reviewed and [rlgl](https://github.com/raysan5/raylib/blob/develop/src/rlgl.c) module has been completely redesigned to accomodate to new material-lighting systems and stereo rendering. You can check [CHANGELOG](https://github.com/raysan5/raylib/blob/develop/CHANGELOG) file for a more detailed list of changes.
+This new version is so massive that is difficult to list all the improvements, most of raylib modules have been reviewed and [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.c) module has been completely redesigned to accomodate to new material-lighting systems and stereo rendering. You can check [CHANGELOG](https://github.com/raysan5/raylib/blob/master/CHANGELOG) file for a more detailed list of changes.
-Up to 8 new code examples have been added to show the new raylib features and also some samples to show the usage of [rlgl](https://github.com/raysan5/raylib/blob/develop/examples/rlgl_standalone.c) and [audio](https://github.com/raysan5/raylib/blob/develop/examples/audio_standalone.c) raylib modules as standalone libraries.
+Up to 8 new code examples have been added to show the new raylib features and also some samples to show the usage of [rlgl](https://github.com/raysan5/raylib/blob/master/examples/rlgl_standalone.c) and [audio](https://github.com/raysan5/raylib/blob/master/examples/audio_standalone.c) raylib modules as standalone libraries.
Lots of code changes (+400 commits) and lots of hours of hard work have concluded in this amazing new raylib 1.5.
@@ -149,7 +149,7 @@ On November 2016, only 4 months after raylib 1.5, arrives raylib 1.6. This new v
Complete [raylib Lua binding](https://github.com/raysan5/raylib-lua). All raylib functions plus the +60 code examples have been ported to Lua, now Lua users can enjoy coding videogames in Lua while using all the internal power of raylib. This addition also open the doors to Lua scripting support for a future raylib-based engine, being able to move game logic (Init, Update, Draw, De-Init) to Lua scripts while keep using raylib functionality.
-Completely redesigned [audio module](https://github.com/raysan5/raylib/blob/develop/src/audio.c). Based on the new direction taken in raylib 1.5, it has been further improved and more functionality added (+20 new functions) to allow raw audio processing and streaming. [FLAC file format support](https://github.com/raysan5/raylib/blob/develop/src/external/dr_flac.h) has also been added. In the same line, [OpenAL Soft](https://github.com/kcat/openal-soft) backend is now provided as a static library in Windows to allow static linking and get ride of OpenAL32.dll. Now raylib Windows games are completey self-contained, no external libraries required any more!
+Completely redesigned [audio module](https://github.com/raysan5/raylib/blob/master/src/audio.c). Based on the new direction taken in raylib 1.5, it has been further improved and more functionality added (+20 new functions) to allow raw audio processing and streaming. [FLAC file format support](https://github.com/raysan5/raylib/blob/master/src/external/dr_flac.h) has also been added. In the same line, [OpenAL Soft](https://github.com/kcat/openal-soft) backend is now provided as a static library in Windows to allow static linking and get ride of OpenAL32.dll. Now raylib Windows games are completey self-contained, no external libraries required any more!
[Physac](https://github.com/victorfisac/Physac) module has been moved to its own repository and it has been improved A LOT, actually, library has been completely rewritten from scratch by [@victorfisac](https://github.com/victorfisac), multiple samples have been added together with countless new features to match current standard 2D physic libraries. Results are amazing!
@@ -187,17 +187,17 @@ notes on raylib 1.8
October 2017, around 5 months after latest raylib version, another release is published: raylib 1.8. Again, several modules of the library have been reviewed and some new functionality added. Main changes of this new release are:
-[Procedural image generation](https://github.com/raysan5/raylib/blob/develop/examples/textures/textures_image_generation.c) function, a set of new functions have been added to generate gradients, checked, noise and cellular images from scratch. Image generation could be useful for certain textures or learning pourpouses.
+[Procedural image generation](https://github.com/raysan5/raylib/blob/master/examples/textures/textures_image_generation.c) function, a set of new functions have been added to generate gradients, checked, noise and cellular images from scratch. Image generation could be useful for certain textures or learning pourpouses.
-[Parametric mesh generation](https://github.com/raysan5/raylib/blob/develop/examples/models/models_mesh_generation.c) functions, create 3d meshes from scratch just defining a set of parameters, meshes like cube, sphere, cylinder, torus, knot and more can be very useful for prototyping or for lighting and texture testing.
+[Parametric mesh generation](https://github.com/raysan5/raylib/blob/master/examples/models/models_mesh_generation.c) functions, create 3d meshes from scratch just defining a set of parameters, meshes like cube, sphere, cylinder, torus, knot and more can be very useful for prototyping or for lighting and texture testing.
-PBR Materials support, a completely redesigned shaders and material system allows advance materials definition and usage, with fully customizable shaders. Some new functions have been added to generate the environment textures required for PBR shading and a a new complete [PBR material example](https://github.com/raysan5/raylib/blob/develop/examples/models/models_material_pbr.c) is also provided for reference.
+PBR Materials support, a completely redesigned shaders and material system allows advance materials definition and usage, with fully customizable shaders. Some new functions have been added to generate the environment textures required for PBR shading and a a new complete [PBR material example](https://github.com/raysan5/raylib/blob/master/examples/models/models_material_pbr.c) is also provided for reference.
-Custom Android APK build pipeline with [simple Makefile](https://github.com/raysan5/raylib/blob/develop/templates/simple_game/Makefile). Actually, full code building mechanism based on plain Makefile has been completely reviewed and Android building has been added for sources and also for examples and templates building into final APK package. This way, raylib Android building has been greatly simplified and integrated seamlessly into standard build scripts.
+Custom Android APK build pipeline with [simple Makefile](https://github.com/raysan5/raylib/blob/master/templates/simple_game/Makefile). Actually, full code building mechanism based on plain Makefile has been completely reviewed and Android building has been added for sources and also for examples and templates building into final APK package. This way, raylib Android building has been greatly simplified and integrated seamlessly into standard build scripts.
-[rlgl](https://github.com/raysan5/raylib/blob/develop/src/rlgl.c) module has been completely reviewed and most of the functions renamed for consistency. This way, standalone usage of rlgl is promoted, with a [complete example provided](https://github.com/raysan5/raylib/blob/develop/examples/others/rlgl_standalone.c). rlgl offers a pseudo-OpenGL 1.1 immediate-mode programming-style layer, with backends to multiple OpenGL versions.
+[rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.c) module has been completely reviewed and most of the functions renamed for consistency. This way, standalone usage of rlgl is promoted, with a [complete example provided](https://github.com/raysan5/raylib/blob/master/examples/others/rlgl_standalone.c). rlgl offers a pseudo-OpenGL 1.1 immediate-mode programming-style layer, with backends to multiple OpenGL versions.
-[raymath](https://github.com/raysan5/raylib/blob/develop/src/rlgl.c) library has been also reviewed to align with other advance math libraries like [GLM](https://github.com/g-truc/glm). Matrix math has been improved and simplified, some new Quaternion functions have been added and Vector3 functions have been renamed all around the library for consistency with new Vector2 functionality.
+[raymath](https://github.com/raysan5/raylib/blob/master/src/rlgl.c) library has been also reviewed to align with other advance math libraries like [GLM](https://github.com/g-truc/glm). Matrix math has been improved and simplified, some new Quaternion functions have been added and Vector3 functions have been renamed all around the library for consistency with new Vector2 functionality.
Additionally, as always, examples and templates have been reviewed to work with new version (some new examples have been added), all external libraries have been updated to latest stable version and latest Notepad++ and MinGW have been configured to work with new raylib. For a full list of changes, just check [CHANGELOG](CHANGELOG).
diff --git a/LICENSE.md b/LICENSE.md
index dd026c7be..248738ef4 100644
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -27,7 +27,7 @@ applications, and to alter it and redistribute it freely, subject to the followi
fonts
------
-The following fonts [provided with raylib](https://github.com/raysan5/raylib/tree/develop/examples/text/resources/fonts) are free to use (freeware) and have been designed by the following people:
+The following fonts [provided with raylib](https://github.com/raysan5/raylib/tree/master/examples/text/resources/fonts) are free to use (freeware) and have been designed by the following people:
* Alpha Beta - Brian Kent (AEnigma)
* Setback - Brian Kent (AEnigma)
@@ -41,9 +41,9 @@ The following fonts [provided with raylib](https://github.com/raysan5/raylib/tre
2d art
------
-[scarfy spritesheet](https://github.com/raysan5/raylib/blob/develop/examples/textures/resources/scarfy.png) and [fudesumi image](https://github.com/raysan5/raylib/blob/develop/examples/textures/resources/fudesumi.png) have been created by [Eiden Marsal](https://www.artstation.com/artist/marshall_z) and licensed as [Creative Commons Attribution-NonCommercial 3.0](https://creativecommons.org/licenses/by-nc/3.0/legalcode)
+[scarfy spritesheet](https://github.com/raysan5/raylib/blob/master/examples/textures/resources/scarfy.png) and [fudesumi image](https://github.com/raysan5/raylib/blob/master/examples/textures/resources/fudesumi.png) have been created by [Eiden Marsal](https://www.artstation.com/artist/marshall_z) and licensed as [Creative Commons Attribution-NonCommercial 3.0](https://creativecommons.org/licenses/by-nc/3.0/legalcode)
3d models
---------
-[dwarf 3d model and textures](https://github.com/raysan5/raylib/tree/develop/examples/models/resources/model) have been created by David Moreno and licensed as [Creative Commons Attribution-NonCommercial 3.0](https://creativecommons.org/licenses/by-nc/3.0/legalcode)
+[dwarf 3d model and textures](https://github.com/raysan5/raylib/tree/master/examples/models/resources/model) have been created by David Moreno and licensed as [Creative Commons Attribution-NonCommercial 3.0](https://creativecommons.org/licenses/by-nc/3.0/legalcode)
diff --git a/README.md b/README.md
index 6fe325d4c..46b80ada7 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-
+
**raylib is a simple and easy-to-use library to learn videogames programming.**
@@ -11,39 +11,46 @@ no fancy interface, no visual helpers, no auto-debugging... just coding in the m
pure spartan-programmers way. Are you ready to learn? Jump to [code examples!](http://www.raylib.com/examples.html)
[](https://travis-ci.org/raysan5/raylib)
+[](https://ci.appveyor.com/project/raysan5/raylib)
+[](https://gitter.im/raylib/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
+[](https://discord.gg/VkzNHUE)
+[](LICENSE.md)
+[](https://twitter.com/raysan5)
features
--------
-
+
* Written in plain C code (C99) in PascalCase/camelCase notation
- * Hardware accelerated with OpenGL (1.1, 2.1, 3.3 or ES2)
+ * Hardware accelerated with OpenGL (1.1, 2.1, 3.3 or ES2 - choose at compile)
* Unique OpenGL abstraction layer (usable as standalone module): [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.c)
- * Powerful fonts module with SpriteFonts support (XNA bitmap fonts, AngelCode fonts, TTF)
- * Outstanding texture formats support, including compressed formats (DXT, ETC, PVRT, ASTC)
- * Basic 3d support for Geometrics, Models, Billboards, Heightmaps and Cubicmaps
+ * Powerful fonts module with SpriteFonts support (XNA fonts, AngelCode fonts, TTF)
+ * Outstanding texture formats support, including compressed formats (DXT, ETC, ASTC)
+ * Full 3d support for 3d Shapes, Models, Billboards, Heightmaps and more!
* Flexible Materials system, supporting classic maps and PBR maps
* Shaders support, including Model shaders and Postprocessing shaders
* Powerful math module for Vector, Matrix and Quaternion operations: [raymath](https://github.com/raysan5/raylib/blob/master/src/raymath.h)
* Audio loading and playing with streaming support (WAV, OGG, FLAC, XM, MOD)
- * Multiple platforms support: Windows, Linux, Mac, **Android**, **Raspberry Pi** and **HTML5**
- * VR stereo rendering support with configurable HMD device parameters
- * Minimal external dependencies (GLFW3, OpenGL, OpenAL)
+ * Multiple platforms support: Windows, Linux, FreeBSD, MacOS, UWP, Android, Raspberry Pi, HTML5.
+ * VR stereo rendering with configurable HMD device parameters
+ * NO external dependencies, all required libraries included with raylib
* Complete bindings to LUA ([raylib-lua](https://github.com/raysan5/raylib-lua)) and Go ([raylib-go](https://github.com/gen2brain/raylib-go))
-raylib uses on its core module the outstanding [GLFW3](http://www.glfw.org/) library. The best option I found for
-multiplatform (Windows, Linux, Mac) window/context and input management (clean, focused, great license, well documented, modern, maintained, ...).
+raylib uses on its [core](https://github.com/raysan5/raylib/blob/master/src/core.c) module the outstanding [GLFW3](http://www.glfw.org/) library, embedded inside raylib in the form of [rglfw](https://github.com/raysan5/raylib/blob/master/src/rglfw.c) module, avoiding that way external dependencies.
-raylib uses on its [audio](https://github.com/raysan5/raylib/blob/master/src/audio.c) module, [OpenAL Soft](http://kcat.strangesoft.net/openal.html) audio library, in multiple flavours,
-to accomodate to Android, Raspberry Pi and HTML5.
+raylib uses on its [audio](https://github.com/raysan5/raylib/blob/master/src/audio.c) module, the amazing [mini_al](https://github.com/dr-soft/mini_al) audio library, single-file header-only and supporting multiple platforms and multiple audio backends.
+
+raylib uses internally multiple single-file header-only libraries to support multiple fileformats loading and saving, all those libraries are embedded with raylib and available in [src/external](https://github.com/raysan5/raylib/tree/master/src/external) directory.
*On Android, `native_app_glue module` (provided by Android NDK) and native Android libraries are used to manage window/context, inputs and activity life cycle.*
*On Raspberry Pi, Videocore API and EGL libraries are used for window/context management and raw inputs reading.*
-building
---------
+build and installation
+----------------------
-For detailed building instructions, check [raylib Wiki](https://github.com/raysan5/raylib/wiki).
+Binary releases for Windows, Linux and macOS are available at the [Github Releases](https://github.com/raysan5/raylib/releases) page. raylib is also available via multiple package managers on multiple OS distributions. For more info check [raylib Wiki](https://github.com/raysan5/raylib/wiki).
+
+To build raylib yourself, check out also the [raylib Wiki](https://github.com/raysan5/raylib/wiki) for detailed instructions.
raylib has been developed using exclusively two tools:
@@ -61,6 +68,7 @@ contact
* Reddit: [https://www.reddit.com/r/raylib](https://www.reddit.com/r/raylib)
* Twitch: [http://www.twitch.tv/raysan5](http://www.twitch.tv/raysan5)
* Patreon: [https://www.patreon.com/raysan5](https://www.patreon.com/raysan5)
+ * YouTube: [https://www.youtube.com/channel/raylib](https://www.youtube.com/channel/UC8WIBkhYb5sBNqXO1mZ7WSQ)
If you are using raylib and you enjoy it, please, [let me know][raysan5].
diff --git a/ROADMAP.md b/ROADMAP.md
index 66b496ad1..50a11ce60 100644
--- a/ROADMAP.md
+++ b/ROADMAP.md
@@ -4,7 +4,7 @@ roadmap
Current version of raylib is complete and functional but there is still a lot of room for improvement.
Here it is a wish-list with features and ideas to improve the library.
-Note that [raylib source code](https://github.com/raysan5/raylib/tree/develop/src) has some *TODO* marks around code with pending things to review and improve. Check [GitHub Issues](https://github.com/raysan5/raylib/issues) for further details!
+Note that [raylib source code](https://github.com/raysan5/raylib/tree/master/src) has some *TODO* marks around code with pending things to review and improve. Check [GitHub Issues](https://github.com/raysan5/raylib/issues) for further details!
**raylib 1.x**
- [ ] Basic GPU stats sytem (memory, draws, time...)
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 000000000..6452a089f
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,65 @@
+#os: Visual Studio 2015
+
+clone_depth: 5
+
+cache:
+ - C:\ProgramData\chocolatey\bin -> appveyor.yml
+ - C:\ProgramData\chocolatey\lib -> appveyor.yml
+
+init:
+ - cmake -E remove c:\programdata\chocolatey\bin\cpack.exe
+ - set PATH=%PATH:C:\Program Files (x86)\Git\usr\bin;=%
+ - set PATH=%PATH:C:\Program Files\Git\usr\bin;=%
+ - if [%BITS%]==[32] set MINGW=C:\mingw-w64\i686-6.3.0-posix-dwarf-rt_v5-rev1\mingw32
+ - if [%BITS%]==[64] set MINGW=C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64
+ - if [%COMPILER%]==[mingw] set PATH=%MINGW%\bin;%PATH%
+ - set RAYLIB_PACKAGE_SUFFIX=-Win%BITS%-%COMPILER%
+ - set VERBOSE=1
+
+environment:
+ matrix:
+ - compiler: mingw
+ bits: 32
+ examples: ON
+ - compiler: mingw
+ bits: 64
+ examples: ON
+ - compiler: msvc15
+ bits: 32
+ examples: OFF
+ - compiler: msvc15
+ bits: 64
+ examples: OFF
+
+before_build:
+ - if [%compiler%]==[mingw] set CFLAGS=-m%BITS% & set LDFLAGS=-m%BITS% & set GENERATOR="MinGW Makefiles"
+ - if [%COMPILER%]==[msvc15] if [%BITS%]==[32] set GENERATOR="Visual Studio 14 2015"
+ - if [%COMPILER%]==[msvc15] if [%BITS%]==[64] set GENERATOR="Visual Studio 14 2015 Win64"
+ - mkdir build
+ - cd build
+
+build_script:
+ - cmake -G %GENERATOR% -DSTATIC=ON -DSHARED=ON -DBUILD_EXAMPLES=%examples% -DBUILD_GAMES=%examples% ..
+ - cmake --build . --target install
+
+after_build:
+ - cmake --build . --target package
+
+before_test:
+
+test_script:
+
+artifacts:
+ - path: 'build\*.zip'
+
+deploy:
+ - provider: GitHub
+ auth_token:
+ secure: OxKnnT3tlkPl9365cOO84rDWU4UkHIYJc0D3r3Tv7rB3HaR2BBhlhCnl7g3nuOJy
+ artifact: /.*\.zip/
+ draft: false
+ prerelease: false
+ force_update: true
+ on:
+ branch: master
+ appveyor_repo_tag: true # deploy on tag push only
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 354a13735..1f05d529e 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -7,9 +7,20 @@ include("../utils.cmake")
# TODO `build` directory should maybe be something else...
# TODO place somewhere else?
include_directories("../build/release")
+include_directories("../src/external")
+include_directories("../src/external/glfw/include")
# Get the sources together
-set(example_dirs audio core models others physac shaders text texutures)
+set(example_dirs audio core models others shaders shapes text textures)
+set(CMAKE_REQUIRED_DEFINITIONS -D_POSIX_C_SOURCE=199309L)
+ include(CheckSymbolExists)
+ check_symbol_exists(CLOCK_MONOTONIC time.h HAVE_CLOCK_MONOTONIC)
+ check_symbol_exists(QueryPerformanceCounter windows.h HAVE_QPC)
+set(CMAKE_REQUIRED_DEFINITIONS)
+if(HAVE_QPC OR HAVE_CLOCK_MONOTONIC)
+ set(example_dirs ${example_dirs} physac)
+endif()
+
set(example_sources)
set(example_resources)
foreach(example_dir ${example_dirs})
@@ -22,6 +33,14 @@ foreach(example_dir ${example_dirs})
list(APPEND example_resources ${resources})
endforeach()
+include(CheckIncludeFiles)
+check_include_files(OVR_CAPI_GL.h HAVE_OCULUS_CAPI)
+if(NOT HAVE_OCULUS_CAPI)
+ list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/oculus_rift.c)
+endif()
+list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/standard_lighting.c)
+
+
# Do each example
foreach(example_source ${example_sources})
# Create the basename for the example
diff --git a/examples/Makefile b/examples/Makefile
index edcff8072..becb91dc4 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -2,7 +2,7 @@
#
# raylib makefile for Desktop platforms, Raspberry Pi, Android and HTML5
#
-# Copyright (c) 2013-2017 Ramon Santamaria (@raysan5)
+# Copyright (c) 2013-2018 Ramon Santamaria (@raysan5)
#
# This software is provided "as-is", without any express or implied warranty. In no event
# will the authors be held liable for any damages arising from the use of this software.
@@ -24,81 +24,138 @@
.PHONY: all clean
# Define required raylib variables
-# WARNING: To compile to HTML5, code must be redesigned to use emscripten.h and emscripten_set_main_loop()
-PLATFORM ?= PLATFORM_DESKTOP
-RAYLIB_PATH ?= ..
-PROJECT_NAME ?= raylib_example
+PROJECT_NAME ?= raylib_examples
+RAYLIB_VERSION ?= 1.9.7
+RAYLIB_API_VERSION ?= 1
+RAYLIB_PATH ?= ..
-ifeq ($(PLATFORM),PLATFORM_RPI)
- RAYLIB_PATH ?= /home/pi/raylib
-endif
+# Define default options
-# Library type used for raylib and OpenAL Soft: STATIC (.a) or SHARED (.so/.dll)
-# NOTE: Libraries should be provided in the selected form
-RAYLIB_LIBTYPE ?= STATIC
-OPENAL_LIBTYPE ?= STATIC
+# One of PLATFORM_DESKTOP, PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB
+PLATFORM ?= PLATFORM_DESKTOP
-# On PLATFORM_WEB force OpenAL Soft shared library
-ifeq ($(PLATFORM),PLATFORM_WEB)
- OPENAL_LIBTYPE = SHARED
-endif
+# Locations of your newly installed library and associated headers. See ../src/Makefile
+# On Linux, if you have installed raylib but cannot compile the examples, check that
+# the *_INSTALL_PATH values here are the same as those in src/Makefile or point to known locations.
+# To enable system-wide compile-time and runtime linking to libraylib.so, run ../src/$ sudo make install RAYLIB_LIBTYPE_SHARED.
+# To enable compile-time linking to a special version of libraylib.so, change these variables here.
+# To enable runtime linking to a special version of libraylib.so, see EXAMPLE_RUNTIME_PATH below.
+# If there is a libraylib in both EXAMPLE_RUNTIME_PATH and RAYLIB_INSTALL_PATH, at runtime,
+# the library at EXAMPLE_RUNTIME_PATH, if present, will take precedence over the one at RAYLIB_INSTALL_PATH.
+# RAYLIB_INSTALL_PATH should be the desired full path to libraylib. No relative paths.
+DESTDIR ?= /usr/local
+RAYLIB_INSTALL_PATH ?= $(DESTDIR)/lib
+# RAYLIB_H_INSTALL_PATH locates the installed raylib header and associated source files.
+RAYLIB_H_INSTALL_PATH ?= $(DESTDIR)/include
+
+# Library type used for raylib: STATIC (.a) or SHARED (.so/.dll)
+RAYLIB_LIBTYPE ?= STATIC
+
+# Build mode for project: DEBUG or RELEASE
+RAYLIB_BUILD_MODE ?= RELEASE
+
+# Use external GLFW library instead of rglfw module
+# TODO: Review usage on Linux. Target version of choice. Switch on -lglfw or -lglfw3
+USE_EXTERNAL_GLFW ?= FALSE
+
+# Use Wayland display server protocol on Linux desktop
+# by default it uses X11 windowing system
+USE_WAYLAND_DISPLAY ?= FALSE
+
+# NOTE: On PLATFORM_WEB OpenAL Soft backend is used by default (check raylib/src/Makefile)
# Determine PLATFORM_OS in case PLATFORM_DESKTOP selected
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
- # No uname.exe on MinGW!, but OS=Windows_NT on Windows! ifeq ($(UNAME),Msys) -> Windows
+ # No uname.exe on MinGW!, but OS=Windows_NT on Windows!
+ # ifeq ($(UNAME),Msys) -> Windows
ifeq ($(OS),Windows_NT)
PLATFORM_OS=WINDOWS
- LIBPATH=win32
else
UNAMEOS=$(shell uname)
ifeq ($(UNAMEOS),Linux)
PLATFORM_OS=LINUX
- LIBPATH=linux
- else
+ endif
+ ifeq ($(UNAMEOS),FreeBSD)
+ PLATFORM_OS=FREEBSD
+ endif
ifeq ($(UNAMEOS),Darwin)
PLATFORM_OS=OSX
- LIBPATH=osx
- endif
endif
endif
endif
-
ifeq ($(PLATFORM),PLATFORM_RPI)
- # RPI cross-compiler
- RPI_CROSS_COMPILE ?= NO
+ UNAMEOS=$(shell uname)
+ ifeq ($(UNAMEOS),Linux)
+ PLATFORM_OS=LINUX
+ endif
+endif
+
+# RAYLIB_PATH adjustment for different platforms.
+# If using GNU make, we can get the full path to the top of the tree. Windows? BSD?
+# Required for ldconfig or other tools that do not perform path expansion.
+ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ ifeq ($(PLATFORM_OS),LINUX)
+ RAYLIB_PREFIX ?= ..
+ RAYLIB_PATH = $(realpath $(RAYLIB_PREFIX))
+ endif
+endif
+# Default path for raylib on Raspberry Pi, if installed in different path, update it!
+# This is not currently used by src/Makefile. Not sure of its origin or usage. Refer to wiki.
+# TODO: update install: target in src/Makefile for RPI, consider relation to LINUX.
+ifeq ($(PLATFORM),PLATFORM_RPI)
+ RAYLIB_PATH ?= /home/pi/raylib
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
# Emscripten required variables
EMSDK_PATH = C:/emsdk
- EMSCRIPTEN_VERSION = 1.37.21
- CLANG_VERSION=e1.37.21_64bit
+ EMSCRIPTEN_VERSION = 1.37.28
+ CLANG_VERSION=e1.37.28_64bit
PYTHON_VERSION=2.7.5.3_64bit
NODE_VERSION=4.1.1_64bit
export PATH=$(EMSDK_PATH);$(EMSDK_PATH)\clang\$(CLANG_VERSION);$(EMSDK_PATH)\node\$(NODE_VERSION)\bin;$(EMSDK_PATH)\python\$(PYTHON_VERSION);$(EMSDK_PATH)\emscripten\$(EMSCRIPTEN_VERSION);C:\raylib\MinGW\bin:$$(PATH)
EMSCRIPTEN=$(EMSDK_PATH)\emscripten\$(EMSCRIPTEN_VERSION)
endif
-# Define raylib release directory for compiled library
+# Define raylib release directory for compiled library.
+# RAYLIB_RELEASE_PATH points to provided binaries or your freshly built version.
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),WINDOWS)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/win32/mingw32
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/win32/mingw32
endif
ifeq ($(PLATFORM_OS),LINUX)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/linux
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/linux
endif
ifeq ($(PLATFORM_OS),OSX)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/osx
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/osx
+ endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/freebsd
endif
endif
-ifeq ($(PLATFORM),PLATFORM_WEB)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/html5
-endif
ifeq ($(PLATFORM),PLATFORM_RPI)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/rpi
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/rpi
+endif
+ifeq ($(PLATFORM),PLATFORM_WEB)
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/html5
endif
+# EXAMPLE_RUNTIME_PATH embeds a custom runtime location of libraylib.so or other desired libraries
+# into each example binary compiled with RAYLIB_LIBTYPE=SHARED. It defaults to RAYLIB_RELEASE_PATH
+# so that these examples link at runtime with your version of libraylib.so in ../release/libs/linux
+# without formal installation from ../src/Makefile. It aids portability and is useful if you have
+# multiple versions of raylib, have raylib installed to a non-standard location, or want to
+# bundle libraylib.so with your game. Change it to your liking.
+# Note: If, at runtime, there is a libraylib.so at both EXAMPLE_RUNTIME_PATH and RAYLIB_INSTALL_PATH,
+# The library at EXAMPLE_RUNTIME_PATH, if present, will take precedence over RAYLIB_INSTALL_PATH,
+# Implemented for LINUX below with CFLAGS += -Wl,-rpath,$(EXAMPLE_RUNTIME_PATH)
+# To see the result, run readelf -d core/core_basic_window; looking at the RPATH or RUNPATH attribute.
+# To see which libraries a built example is linking to, ldd core/core_basic_window;
+# Look for libraylib.so.1 => $(RAYLIB_INSTALL_PATH)/libraylib.so.1 or similar listing.
+EXAMPLE_RUNTIME_PATH ?= $(RAYLIB_RELEASE_PATH)
+
# Define default C compiler: gcc
+# NOTE: define g++ compiler if using C++
CC = gcc
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
@@ -106,14 +163,20 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
# OSX default compiler
CC = clang
endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ # FreeBSD default compiler
+ CC = clang
+ endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
- ifeq ($(RPI_CROSS_COMPILE),YES)
- # RPI cross-compiler
- CC = armv6j-hardfloat-linux-gnueabi-gcc
+ ifeq ($(USE_RPI_CROSS_COMPILER),TRUE)
+ # Define RPI cross-compiler
+ #CC = armv6j-hardfloat-linux-gnueabi-gcc
+ CC = $(RPI_TOOLCHAIN)/bin/arm-linux-gnueabihf-gcc
endif
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
+ # WARNING: To compile to HTML5, code must be redesigned to use emscripten.h and emscripten_set_main_loop()
# HTML5 emscripten compiler
CC = emcc
endif
@@ -129,15 +192,14 @@ endif
# Define compiler flags:
# -O1 defines optimization level
-# -Og enable debugging
+# -g enable debugging
# -s strip unnecessary data from build
# -Wall turns on most, but not all, compiler warnings
# -std=c99 defines C language mode (standard C from 1999 revision)
# -std=gnu99 defines C language mode (GNU C from 1999 revision)
-# -fgnu89-inline declaring inline functions support (GCC optimized)
# -Wno-missing-braces ignore invalid warning (GCC bug 53119)
# -D_DEFAULT_SOURCE use with -std=c99 on Linux and PLATFORM_WEB, required for timespec
-CFLAGS += -O1 -s -Wall -std=c99 -D_DEFAULT_SOURCE -fgnu89-inline -Wno-missing-braces
+CFLAGS += -O1 -s -Wall -std=c99 -D_DEFAULT_SOURCE -Wno-missing-braces
# Additional flags for compiler (if desired)
#CFLAGS += -Wextra -Wmissing-prototypes -Wstrict-prototypes
@@ -148,7 +210,17 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
CFLAGS += $(RAYLIB_PATH)/src/resources -Wl,--subsystem,windows
endif
ifeq ($(PLATFORM_OS),LINUX)
+ ifeq ($(RAYLIB_BUILD_MODE),DEBUG)
+ CFLAGS += -g
+ #CC = clang
+ endif
+ ifeq ($(RAYLIB_LIBTYPE),STATIC)
CFLAGS += -no-pie -D_DEFAULT_SOURCE
+ endif
+ ifeq ($(RAYLIB_LIBTYPE),SHARED)
+ # Explicitly enable runtime link to libraylib.so
+ CFLAGS += -Wl,-rpath,$(EXAMPLE_RUNTIME_PATH)
+ endif
endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
@@ -160,23 +232,54 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
# -s ALLOW_MEMORY_GROWTH=1 # to allow memory resizing
# -s TOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB)
# -s USE_PTHREADS=1 # multithreading support
- CFLAGS += -s USE_GLFW=3 -s ASSERTIONS=1 --profiling -s TOTAL_MEMORY=16777216 --preload-file resources
+ # -s WASM=1 # support Web Assembly (https://github.com/kripken/emscripten/wiki/WebAssembly)
+ # --preload-file resources # specify a resources folder for data compilation
+ CFLAGS += -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 --profiling --preload-file resources
+
+ # Define a custom shell .html and output extension
+ CFLAGS += --shell-file $(RAYLIB_PATH)\templates\web_shell\shell.html
+ EXT = .html
endif
-# Define include paths for required headers
+# Define include paths for required headers.
+# Precedence: immediately local, raysan5 provided sources
# NOTE: Several external required libraries (stb and others)
INCLUDE_PATHS = -I. -I$(RAYLIB_PATH)/release/include -I$(RAYLIB_PATH)/src -I$(RAYLIB_PATH)/src/external
# Define additional directories containing required header files
ifeq ($(PLATFORM),PLATFORM_RPI)
- # RPI requried libraries
+ # RPI required libraries
INCLUDE_PATHS += -I/opt/vc/include
INCLUDE_PATHS += -I/opt/vc/include/interface/vmcs_host/linux
INCLUDE_PATHS += -I/opt/vc/include/interface/vcos/pthreads
endif
+ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ # Consider -L$(RAYLIB_H_INSTALL_PATH)
+ INCLUDE_PATHS += -I/usr/local/include
+ endif
+ ifeq ($(PLATFORM_OS),LINUX)
+ # Reset everything.
+ # Precedence: immediately local, installed version, raysan5 provided libs -I$(RAYLIB_H_INSTALL_PATH) -I$(RAYLIB_PATH)/release/include
+ INCLUDE_PATHS = -I$(RAYLIB_H_INSTALL_PATH) -isystem. -isystem$(RAYLIB_PATH)/src -isystem$(RAYLIB_PATH)/release/include -isystem$(RAYLIB_PATH)/src/external
+ endif
+endif
-# Define library paths containing required libs
-LDFLAGS = -L. -L$(RAYLIB_RELEASE) -L$(RAYLIB_PATH)/src
+# Define library paths containing required libs.
+# Precedence: immediately local, then raysan5 provided libs
+LDFLAGS = -L. -L$(RAYLIB_RELEASE_PATH) -L$(RAYLIB_PATH)/src
+
+ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ # Consider -L$(RAYLIB_INSTALL_PATH)
+ LDFLAGS += -L. -Lsrc -L/usr/local/lib
+ endif
+ ifeq ($(PLATFORM_OS),LINUX)
+ # Reset everything.
+ # Precedence: immediately local, installed version, raysan5 provided libs
+ LDFLAGS = -L. -L$(RAYLIB_INSTALL_PATH) -L$(RAYLIB_RELEASE_PATH) -L$(RAYLIB_PATH)/src
+ endif
+endif
ifeq ($(PLATFORM),PLATFORM_RPI)
LDFLAGS += -L/opt/vc/lib
@@ -186,50 +289,53 @@ endif
# if you want to link libraries (libname.so or libname.a), use the -lname
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),WINDOWS)
- # Libraries for Windows desktop compiling
- # NOTE: GLFW3 and OpenAL Soft libraries should be installed
- LDLIBS = -lraylib -lglfw3 -lopengl32 -lgdi32
-
- # Define required flags and libs for OpenAL Soft STATIC/SHARED usage
- # NOTE: ALLIBS flag only required for raylib Win32 SHARED library building
- ifeq ($(OPENAL_LIBTYPE),STATIC)
- LDLIBS += -lopenal32 -lwinmm
- CFLAGS += -DAL_LIBTYPE_STATIC -Wl,-allow-multiple-definition
- else
- LDLIBS += -lopenal32dll
- endif
-
+ # Libraries for Windows desktop compilation
+ LDLIBS = -lraylib -lopengl32 -lgdi32
# Required for physac examples
LDLIBS += -static -lpthread
endif
ifeq ($(PLATFORM_OS),LINUX)
# Libraries for Debian GNU/Linux desktop compiling
- # NOTE: Required packages: libglfw3-dev libopenal-dev libegl1-mesa-dev
- LDLIBS = -lraylib -lglfw3 -lGL -lopenal -lm -lpthread -ldl
-
- # On XWindow requires also below libraries
- LDLIBS += -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
+ # NOTE: Required packages: libegl1-mesa-dev
+ LDLIBS = -lraylib -lGL -lm -lpthread -ldl -lrt
+ # On X11 requires also below libraries
+ LDLIBS += -lX11
+ # NOTE: It seems additional libraries are not required any more, latest GLFW just dlopen them
+ #LDLIBS += -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
+ # On Wayland windowing system, additional libraries requires
+ ifeq ($(USE_WAYLAND_DISPLAY),TRUE)
+ LDLIBS += -lwayland-client -lwayland-cursor -lwayland-egl -lxkbcommon
+ endif
+ # Explicit link to libc
+ ifeq ($(RAYLIB_LIBTYPE),SHARED)
+ LDLIBS += -lc
+ endif
endif
ifeq ($(PLATFORM_OS),OSX)
# Libraries for OSX 10.9 desktop compiling
- # NOTE: Required packages: libglfw3-dev libopenal-dev libegl1-mesa-dev
- LDLIBS = -lraylib -lglfw -framework OpenGL -framework OpenAL -framework Cocoa
+ # NOTE: Required packages: libopenal-dev libegl1-mesa-dev
+ LDLIBS = -lraylib -framework OpenGL -framework OpenAL -framework Cocoa
+ endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ # Libraries for FreeBSD desktop compiling
+ # NOTE: Required packages: mesa-libs
+ LDLIBS = -lraylib -lGL -lpthread -lm
+ # On XWindow requires also below libraries
+ LDLIBS += -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
+ endif
+ ifeq ($(USE_EXTERNAL_GLFW),TRUE)
+ # NOTE: It could require additional packages installed: libglfw3-dev
+ LDLIBS += -lglfw
endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
# Libraries for Raspberry Pi compiling
- # NOTE: Required packages: libopenal1
- LDLIBS = -lraylib -lGLESv2 -lEGL -lpthread -lrt -lm -lbcm_host -lopenal
+ # NOTE: Required packages: libasound2-dev (ALSA)
+ LDLIBS = -lraylib -lbrcmGLESv2 -lbrcmEGL -lpthread -lrt -lm -lbcm_host -ldl
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
# Libraries for web (HTML5) compiling
- LDLIBS = $(RAYLIB_RELEASE)/libraylib.bc
-endif
-
-# Define output extension to generate a .html file using provided shell
-ifeq ($(PLATFORM),PLATFORM_WEB)
- EXT = .html
- WEB_SHELL = --shell-file $(RAYLIB_PATH)\templates\web_shell\shell.html
+ LDLIBS = $(RAYLIB_RELEASE_PATH)/libraylib.bc
endif
# Define all object files required
@@ -266,6 +372,7 @@ EXAMPLES = \
textures/textures_image_processing \
textures/textures_image_drawing \
textures/textures_image_generation \
+ textures/textures_image_text \
text/text_sprite_fonts \
text/text_bmfont_ttf \
text/text_raylib_fonts \
@@ -282,9 +389,9 @@ EXAMPLES = \
models/models_cubicmap \
models/models_mesh_picking \
models/models_mesh_generation \
- models/models_yaw_pitch_roll \
models/models_material_pbr \
models/models_skybox \
+ models/models_yaw_pitch_roll \
shaders/shaders_model_shader \
shaders/shaders_shapes_textures \
shaders/shaders_custom_uniform \
@@ -298,7 +405,7 @@ EXAMPLES = \
physac/physics_movement \
physac/physics_restitution \
physac/physics_shatter \
- fix_dylib \
+
CURRENT_MAKEFILE = $(lastword $(MAKEFILE_LIST))
@@ -327,7 +434,7 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
del *.o *.exe /s
endif
ifeq ($(PLATFORM_OS),LINUX)
- find -type f -executable | xargs file -i | grep -E 'x-object|x-archive|x-sharedlib|x-executable' | rev | cut -d ':' -f 2- | rev | xargs rm -f
+ find -type f -executable | xargs file -i | grep -E 'x-object|x-archive|x-sharedlib|x-executable' | rev | cut -d ':' -f 2- | rev | xargs rm -fv
endif
ifeq ($(PLATFORM_OS),OSX)
find . -type f -perm +ugo+x -delete
@@ -336,10 +443,9 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
find . -type f -executable -delete
- rm -f *.o
+ rm -fv *.o
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
del *.o *.html *.js
endif
@echo Cleaning done
-
diff --git a/examples/core/core_3d_camera_first_person.c b/examples/core/core_3d_camera_first_person.c
index 3998af819..775e6c573 100644
--- a/examples/core/core_3d_camera_first_person.c
+++ b/examples/core/core_3d_camera_first_person.c
@@ -23,7 +23,12 @@ int main()
InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d camera first person");
// Define the camera to look into our 3d world (position, target, up vector)
- Camera camera = {{ 4.0f, 2.0f, 4.0f }, { 0.0f, 1.8f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 60.0f };
+ Camera camera = { 0 };
+ camera.position = (Vector3){ 4.0f, 2.0f, 4.0f };
+ camera.target = (Vector3){ 0.0f, 1.8f, 0.0f };
+ camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
+ camera.fovy = 60.0f;
+ camera.type = CAMERA_PERSPECTIVE;
// Generates some random columns
float heights[MAX_COLUMNS];
diff --git a/examples/core/core_3d_picking.c b/examples/core/core_3d_picking.c
index 7658b3939..56e80f2ae 100644
--- a/examples/core/core_3d_picking.c
+++ b/examples/core/core_3d_picking.c
@@ -29,11 +29,11 @@ int main()
Vector3 cubePosition = { 0.0f, 1.0f, 0.0f };
Vector3 cubeSize = { 2.0f, 2.0f, 2.0f };
-
- Ray ray; // Picking line ray
-
+
+ Ray ray = {0.0f, 0.0f, 0.0f}; // Picking line ray
+
bool collision = false;
-
+
SetCameraMode(camera, CAMERA_FREE); // Set a free camera mode
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
@@ -45,11 +45,11 @@ int main()
// Update
//----------------------------------------------------------------------------------
UpdateCamera(&camera); // Update camera
-
+
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
{
ray = GetMouseRay(GetMousePosition(), camera);
-
+
// Check collision between ray and box
collision = CheckCollisionRayBox(ray,
(BoundingBox){(Vector3){ cubePosition.x - cubeSize.x/2, cubePosition.y - cubeSize.y/2, cubePosition.z - cubeSize.z/2 },
@@ -65,7 +65,7 @@ int main()
Begin3dMode(camera);
- if (collision)
+ if (collision)
{
DrawCube(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, RED);
DrawCubeWires(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, MAROON);
@@ -77,15 +77,14 @@ int main()
DrawCube(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, GRAY);
DrawCubeWires(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, DARKGRAY);
}
-
+
DrawRay(ray, MAROON);
-
DrawGrid(10, 1.0f);
End3dMode();
-
+
DrawText("Try selecting the box with mouse!", 240, 10, 20, DARKGRAY);
-
+
if(collision) DrawText("BOX SELECTED", (screenWidth - MeasureText("BOX SELECTED", 30)) / 2, screenHeight * 0.1f, 30, GREEN);
DrawFPS(10, 10);
@@ -100,4 +99,4 @@ int main()
//--------------------------------------------------------------------------------------
return 0;
-}
\ No newline at end of file
+}
diff --git a/examples/core/core_world_screen.c b/examples/core/core_world_screen.c
index f8c53c70d..78ca6eb4e 100644
--- a/examples/core/core_world_screen.c
+++ b/examples/core/core_world_screen.c
@@ -21,7 +21,12 @@ int main()
InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d camera free");
// Define the camera to look into our 3d world
- Camera camera = {{ 10.0f, 10.0f, 10.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f };
+ Camera camera = { 0 };
+ camera.position = (Vector3){ 10.0f, 10.0f, 10.0f };
+ camera.target = (Vector3){ 0.0f, 0.0f, 0.0f };
+ camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
+ camera.fovy = 45.0f;
+ camera.type = CAMERA_PERSPECTIVE;
Vector3 cubePosition = { 0.0f, 0.0f, 0.0f };
diff --git a/examples/models/models_billboard.c b/examples/models/models_billboard.c
index bca9faf8c..3b3efc477 100644
--- a/examples/models/models_billboard.c
+++ b/examples/models/models_billboard.c
@@ -21,7 +21,13 @@ int main()
InitWindow(screenWidth, screenHeight, "raylib [models] example - drawing billboards");
// Define the camera to look into our 3d world
- Camera camera = {{ 5.0f, 4.0f, 5.0f }, { 0.0f, 2.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f };
+ Camera camera = { 0 };
+ camera.position = (Vector3){ 5.0f, 4.0f, 5.0f };
+ camera.target = (Vector3){ 0.0f, 2.0f, 0.0f };
+ camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
+ camera.fovy = 45.0f;
+ camera.type = CAMERA_PERSPECTIVE;
+
Texture2D bill = LoadTexture("resources/billboard.png"); // Our texture billboard
Vector3 billPosition = { 0.0f, 2.0f, 0.0f }; // Position where draw billboard
diff --git a/examples/models/models_box_collisions.c b/examples/models/models_box_collisions.c
index 69cec418b..eb72c54ca 100644
--- a/examples/models/models_box_collisions.c
+++ b/examples/models/models_box_collisions.c
@@ -21,7 +21,7 @@ int main()
InitWindow(screenWidth, screenHeight, "raylib [models] example - box collisions");
// Define the camera to look into our 3d world
- Camera camera = {{ 0.0f, 10.0f, 10.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f };
+ Camera camera = {{ 0.0f, 10.0f, 10.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f, 0 };
Vector3 playerPosition = { 0.0f, 1.0f, 2.0f };
Vector3 playerSize = { 1.0f, 2.0f, 1.0f };
diff --git a/examples/models/models_cubicmap.c b/examples/models/models_cubicmap.c
index d8be9329f..47b887482 100644
--- a/examples/models/models_cubicmap.c
+++ b/examples/models/models_cubicmap.c
@@ -21,7 +21,7 @@ int main()
InitWindow(screenWidth, screenHeight, "raylib [models] example - cubesmap loading and drawing");
// Define the camera to look into our 3d world
- Camera camera = {{ 16.0f, 14.0f, 16.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f };
+ Camera camera = {{ 16.0f, 14.0f, 16.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f, 0 };
Image image = LoadImage("resources/cubicmap.png"); // Load cubicmap image (RAM)
Texture2D cubicmap = LoadTextureFromImage(image); // Convert image to texture to display (VRAM)
diff --git a/examples/models/models_geometric_shapes.c b/examples/models/models_geometric_shapes.c
index a13a1f3bf..7a1e7e48c 100644
--- a/examples/models/models_geometric_shapes.c
+++ b/examples/models/models_geometric_shapes.c
@@ -21,7 +21,12 @@ int main()
InitWindow(screenWidth, screenHeight, "raylib [models] example - geometric shapes");
// Define the camera to look into our 3d world
- Camera camera = {{ 0.0f, 10.0f, 10.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f };
+ Camera camera = { 0 };
+ camera.position = (Vector3){ 0.0f, 10.0f, 10.0f };
+ camera.target = (Vector3){ 0.0f, 0.0f, 0.0f };
+ camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
+ camera.fovy = 45.0f;
+ camera.type = CAMERA_PERSPECTIVE;
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
diff --git a/examples/models/models_heightmap.c b/examples/models/models_heightmap.c
index e476d1b74..55474185f 100644
--- a/examples/models/models_heightmap.c
+++ b/examples/models/models_heightmap.c
@@ -21,7 +21,7 @@ int main()
InitWindow(screenWidth, screenHeight, "raylib [models] example - heightmap loading and drawing");
// Define our custom camera to look into our 3d world
- Camera camera = {{ 18.0f, 16.0f, 18.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f };
+ Camera camera = {{ 18.0f, 16.0f, 18.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f, 0 };
Image image = LoadImage("resources/heightmap.png"); // Load heightmap image (RAM)
Texture2D texture = LoadTextureFromImage(image); // Convert image to texture (VRAM)
diff --git a/examples/models/models_material_pbr.c b/examples/models/models_material_pbr.c
index 9f5763488..4ad2c9e75 100644
--- a/examples/models/models_material_pbr.c
+++ b/examples/models/models_material_pbr.c
@@ -34,7 +34,7 @@ int main()
InitWindow(screenWidth, screenHeight, "raylib [models] example - pbr material");
// Define the camera to look into our 3d world
- Camera camera = {{ 4.0f, 4.0f, 4.0f }, { 0.0f, 0.5f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f };
+ Camera camera = {{ 4.0f, 4.0f, 4.0f }, { 0.0f, 0.5f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f, 0 };
// Load model and PBR material
Model model = LoadModel("resources/pbr/trooper.obj");
@@ -113,7 +113,7 @@ static Material LoadMaterialPBR(Color albedo, float metalness, float roughness)
mat.shader.locs[LOC_MAP_METALNESS] = GetShaderLocation(mat.shader, "metalness.sampler");
mat.shader.locs[LOC_MAP_NORMAL] = GetShaderLocation(mat.shader, "normals.sampler");
mat.shader.locs[LOC_MAP_ROUGHNESS] = GetShaderLocation(mat.shader, "roughness.sampler");
- mat.shader.locs[LOC_MAP_OCCUSION] = GetShaderLocation(mat.shader, "occlusion.sampler");
+ mat.shader.locs[LOC_MAP_OCCLUSION] = GetShaderLocation(mat.shader, "occlusion.sampler");
//mat.shader.locs[LOC_MAP_EMISSION] = GetShaderLocation(mat.shader, "emission.sampler");
//mat.shader.locs[LOC_MAP_HEIGHT] = GetShaderLocation(mat.shader, "height.sampler");
mat.shader.locs[LOC_MAP_IRRADIANCE] = GetShaderLocation(mat.shader, "irradianceMap");
diff --git a/examples/models/models_mesh_generation.c b/examples/models/models_mesh_generation.c
index 72222156c..d9c28ac27 100644
--- a/examples/models/models_mesh_generation.c
+++ b/examples/models/models_mesh_generation.c
@@ -41,7 +41,7 @@ int main()
for (int i = 0; i < NUM_MODELS; i++) models[i].material.maps[MAP_DIFFUSE].texture = texture;
// Define the camera to look into our 3d world
- Camera camera = {{ 5.0f, 5.0f, 5.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f };
+ Camera camera = {{ 5.0f, 5.0f, 5.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f, 0 };
// Model drawing position
Vector3 position = { 0.0f, 0.0f, 0.0f };
diff --git a/examples/models/models_mesh_picking.c b/examples/models/models_mesh_picking.c
index e150fe928..e09f9860c 100644
--- a/examples/models/models_mesh_picking.c
+++ b/examples/models/models_mesh_picking.c
@@ -38,7 +38,7 @@ int main()
tower.material.maps[MAP_DIFFUSE].texture = texture; // Set model diffuse texture
Vector3 towerPos = { 0.0f, 0.0f, 0.0f }; // Set model position
- BoundingBox towerBBox = CalculateBoundingBox(tower.mesh);
+ BoundingBox towerBBox = MeshBoundingBox(tower.mesh); // Get mesh bounding box
bool hitMeshBBox = false;
bool hitTriangle = false;
@@ -101,8 +101,8 @@ int main()
{
hitMeshBBox = true;
- // Check ray collision against mesh
- meshHitInfo = GetCollisionRayMesh(ray, &tower.mesh);
+ // Check ray collision against model
+ meshHitInfo = GetCollisionRayModel(ray, &tower);
if ((meshHitInfo.hit) && (meshHitInfo.distance < nearestHit.distance))
{
diff --git a/examples/models/models_obj_loading.c b/examples/models/models_obj_loading.c
index 70f921686..4f89130f0 100644
--- a/examples/models/models_obj_loading.c
+++ b/examples/models/models_obj_loading.c
@@ -21,7 +21,12 @@ int main()
InitWindow(screenWidth, screenHeight, "raylib [models] example - obj model loading");
// Define the camera to look into our 3d world
- Camera camera = {{ 3.0f, 3.0f, 3.0f }, { 0.0f, 1.5f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f };
+ Camera camera = { 0 };
+ camera.position = (Vector3){ 3.0f, 3.0f, 3.0f };
+ camera.target = (Vector3){ 0.0f, 1.5f, 0.0f };
+ camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
+ camera.fovy = 45.0f;
+ camera.type = CAMERA_PERSPECTIVE;
Model dwarf = LoadModel("resources/model/dwarf.obj"); // Load OBJ model
Texture2D texture = LoadTexture("resources/model/dwarf_diffuse.png"); // Load model texture
diff --git a/examples/models/models_orthographic_projection.c b/examples/models/models_orthographic_projection.c
new file mode 100644
index 000000000..cb5ea053f
--- /dev/null
+++ b/examples/models/models_orthographic_projection.c
@@ -0,0 +1,97 @@
+/*******************************************************************************************
+*
+* raylib [models] example - Show the difference between perspective and orthographic projection
+*
+* This program is heavily based on the geometric objects example
+*
+* This example has been created using raylib 1.9.7 (www.raylib.com)
+* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+*
+* Copyright (c) 2018 Max Danielsson & Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+#define FOVY_PERSPECTIVE 45.0f
+#define WIDTH_ORTHOGRAPHIC 10.0f
+
+int main()
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ int screenWidth = 800;
+ int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [models] example - geometric shapes");
+
+ // Define the camera to look into our 3d world
+ Camera camera = {{ 0.0f, 10.0f, 10.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, FOVY_PERSPECTIVE, CAMERA_PERSPECTIVE };
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ if (IsKeyPressed(KEY_SPACE))
+ {
+ if (camera.type == CAMERA_PERSPECTIVE)
+ {
+ camera.fovy = WIDTH_ORTHOGRAPHIC;
+ camera.type = CAMERA_ORTHOGRAPHIC;
+ }
+ else
+ {
+ camera.fovy = FOVY_PERSPECTIVE;
+ camera.type = CAMERA_PERSPECTIVE;
+ }
+ }
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ Begin3dMode(camera);
+
+ DrawCube((Vector3){-4.0f, 0.0f, 2.0f}, 2.0f, 5.0f, 2.0f, RED);
+ DrawCubeWires((Vector3){-4.0f, 0.0f, 2.0f}, 2.0f, 5.0f, 2.0f, GOLD);
+ DrawCubeWires((Vector3){-4.0f, 0.0f, -2.0f}, 3.0f, 6.0f, 2.0f, MAROON);
+
+ DrawSphere((Vector3){-1.0f, 0.0f, -2.0f}, 1.0f, GREEN);
+ DrawSphereWires((Vector3){1.0f, 0.0f, 2.0f}, 2.0f, 16, 16, LIME);
+
+ DrawCylinder((Vector3){4.0f, 0.0f, -2.0f}, 1.0f, 2.0f, 3.0f, 4, SKYBLUE);
+ DrawCylinderWires((Vector3){4.0f, 0.0f, -2.0f}, 1.0f, 2.0f, 3.0f, 4, DARKBLUE);
+ DrawCylinderWires((Vector3){4.5f, -1.0f, 2.0f}, 1.0f, 1.0f, 2.0f, 6, BROWN);
+
+ DrawCylinder((Vector3){1.0f, 0.0f, -4.0f}, 0.0f, 1.5f, 3.0f, 8, GOLD);
+ DrawCylinderWires((Vector3){1.0f, 0.0f, -4.0f}, 0.0f, 1.5f, 3.0f, 8, PINK);
+
+ DrawGrid(10, 1.0f); // Draw a grid
+
+ End3dMode();
+
+ DrawText("Press Spacebar to switch camera type", 10, GetScreenHeight() - 30, 20, DARKGRAY);
+
+ if (camera.type == CAMERA_ORTHOGRAPHIC) DrawText("ORTHOGRAPHIC", 10, 40, 20, BLACK);
+ else if (camera.type == CAMERA_PERSPECTIVE) DrawText("PERSPECTIVE", 10, 40, 20, BLACK);
+
+ DrawFPS(10, 10);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
diff --git a/examples/models/models_skybox.c b/examples/models/models_skybox.c
index 46297e41a..700824d34 100644
--- a/examples/models/models_skybox.c
+++ b/examples/models/models_skybox.c
@@ -21,7 +21,7 @@ int main()
InitWindow(screenWidth, screenHeight, "raylib [models] example - skybox loading and drawing");
// Define the camera to look into our 3d world
- Camera camera = {{ 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f };
+ Camera camera = {{ 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f, 0 };
// Load skybox model
Mesh cube = GenMeshCube(1.0f, 1.0f, 1.0f);
@@ -62,7 +62,7 @@ int main()
Begin3dMode(camera);
- DrawModel(skybox, Vector3Zero(), 1.0f, WHITE);
+ DrawModel(skybox, (Vector3){0, 0, 0}, 1.0f, WHITE);
DrawGrid(10, 1.0f);
diff --git a/examples/models/models_yaw_pitch_roll.c b/examples/models/models_yaw_pitch_roll.c
index 2bae2bf82..c559e67b7 100644
--- a/examples/models/models_yaw_pitch_roll.c
+++ b/examples/models/models_yaw_pitch_roll.c
@@ -5,7 +5,7 @@
* This example has been created using raylib 1.8 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
-* Example based on Berni work on Raspberry Pi:
+* Example based on Berni work on Raspberry Pi:
* http://forum.raylib.com/index.php?p=/discussion/124/line-versus-triangle-drawing-order
*
* Copyright (c) 2017 Ramon Santamaria (@raysan5)
@@ -30,25 +30,26 @@ int main()
InitWindow(screenWidth, screenHeight, "raylib [models] example - plane rotations (yaw, pitch, roll)");
- Texture2D texAngleGauge = LoadTexture("resources/angle_gauge.png");
+ Texture2D texAngleGauge = LoadTexture("resources/angle_gauge.png");
Texture2D texBackground = LoadTexture("resources/background.png");
- Texture2D texPitch = LoadTexture("resources/pitch.png");
+ Texture2D texPitch = LoadTexture("resources/pitch.png");
Texture2D texPlane = LoadTexture("resources/plane.png");
RenderTexture2D framebuffer = LoadRenderTexture(192, 192);
-
+
// Model loading
Model model = LoadModel("resources/plane.obj"); // Load OBJ model
model.material.maps[MAP_DIFFUSE].texture = LoadTexture("resources/plane_diffuse.png"); // Set map diffuse texture
-
+
GenTextureMipmaps(&model.material.maps[MAP_DIFFUSE].texture);
-
+
Camera camera = { 0 };
camera.position = (Vector3){ 0.0f, 60.0f, -120.0f };// Camera position perspective
camera.target = (Vector3){ 0.0f, 12.0f, 0.0f }; // Camera looking at point
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
camera.fovy = 30.0f; // Camera field-of-view Y
-
+ camera.type = CAMERA_PERSPECTIVE; // Camera type
+
float pitch = 0.0f;
float roll = 0.0f;
float yaw = 0.0f;
@@ -61,7 +62,7 @@ int main()
{
// Update
//----------------------------------------------------------------------------------
-
+
// Plane roll (x-axis) controls
if (IsKeyDown(KEY_LEFT)) roll += 1.0f;
else if (IsKeyDown(KEY_RIGHT)) roll -= 1.0f;
@@ -70,7 +71,7 @@ int main()
if (roll > 0.0f) roll -= 0.5f;
else if (roll < 0.0f) roll += 0.5f;
}
-
+
// Plane yaw (y-axis) controls
if (IsKeyDown(KEY_S)) yaw += 1.0f;
else if (IsKeyDown(KEY_A)) yaw -= 1.0f;
@@ -79,7 +80,7 @@ int main()
if (yaw > 0.0f) yaw -= 0.5f;
else if (yaw < 0.0f) yaw += 0.5f;
}
-
+
// Plane pitch (z-axis) controls
if (IsKeyDown(KEY_DOWN)) pitch += 0.6f;
else if (IsKeyDown(KEY_UP)) pitch -= 0.6f;
@@ -88,7 +89,7 @@ int main()
if (pitch > 0.3f) pitch -= 0.3f;
else if (pitch < -0.3f) pitch += 0.3f;
}
-
+
// Wraps the phase of an angle to fit between -180 and +180 degrees
int pitchOffset = pitch;
while (pitchOffset > 180) pitchOffset -= 360;
@@ -96,20 +97,20 @@ int main()
pitchOffset *= 10;
Matrix transform = MatrixIdentity();
-
+
transform = MatrixMultiply(transform, MatrixRotateZ(DEG2RAD*roll));
transform = MatrixMultiply(transform, MatrixRotateX(DEG2RAD*pitch));
transform = MatrixMultiply(transform, MatrixRotateY(DEG2RAD*yaw));
-
+
model.transform = transform;
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
-
+
ClearBackground(RAYWHITE);
-
+
// Draw framebuffer texture (Ahrs Display)
int centerX = framebuffer.texture.width/2;
int centerY = framebuffer.texture.height/2;
@@ -119,18 +120,18 @@ int main()
BeginBlendMode(BLEND_ALPHA);
- DrawTexturePro(texBackground, (Rectangle){0,0,texBackground.width, texBackground.height},
+ DrawTexturePro(texBackground, (Rectangle){ 0, 0, texBackground.width, texBackground.height },
(Rectangle){ centerX, centerY, texBackground.width*scaleFactor, texBackground.height*scaleFactor},
- (Vector2){texBackground.width/2*scaleFactor, texBackground.height/2*scaleFactor + pitchOffset*scaleFactor}, roll, WHITE);
+ (Vector2){ texBackground.width/2*scaleFactor, texBackground.height/2*scaleFactor + pitchOffset*scaleFactor }, roll, WHITE);
DrawTexturePro(texPitch, (Rectangle){ 0, 0, texPitch.width, texPitch.height },
(Rectangle){ centerX, centerY, texPitch.width*scaleFactor, texPitch.height*scaleFactor },
(Vector2){ texPitch.width/2*scaleFactor, texPitch.height/2*scaleFactor + pitchOffset*scaleFactor }, roll, WHITE);
-
- DrawTexturePro(texPlane, (Rectangle){0,0,texPlane.width, texPlane.height },
- (Rectangle){ centerX, centerY, texPlane.width*scaleFactor, texPlane.height*scaleFactor },
- (Vector2){texPlane.width/2*scaleFactor, texPlane.height/2*scaleFactor }, 0, WHITE);
-
+
+ DrawTexturePro(texPlane, (Rectangle){ 0, 0, texPlane.width, texPlane.height },
+ (Rectangle){ centerX, centerY, texPlane.width*scaleFactor, texPlane.height*scaleFactor },
+ (Vector2){ texPlane.width/2*scaleFactor, texPlane.height/2*scaleFactor }, 0, WHITE);
+
EndBlendMode();
EndTextureMode();
@@ -144,10 +145,10 @@ int main()
End3dMode();
// Draw 2D GUI stuff
- DrawAngleGauge(texAngleGauge, 80, 80, roll, "roll", RED);
- DrawAngleGauge(texAngleGauge, 190, 80, pitch, "pitch", GREEN);
- DrawAngleGauge(texAngleGauge, 300, 80, yaw, "yaw", SKYBLUE);
-
+ DrawAngleGauge(texAngleGauge, 80, 70, roll, "roll", RED);
+ DrawAngleGauge(texAngleGauge, 190, 70, pitch, "pitch", GREEN);
+ DrawAngleGauge(texAngleGauge, 300, 70, yaw, "yaw", SKYBLUE);
+
DrawRectangle(30, 360, 260, 70, Fade(SKYBLUE, 0.5f));
DrawRectangleLines(30, 360, 260, 70, Fade(DARKBLUE, 0.5f));
DrawText("Pitch controlled with: KEY_UP / KEY_DOWN", 40, 370, 10, DARKGRAY);
@@ -155,31 +156,31 @@ int main()
DrawText("Yaw controlled with: KEY_A / KEY_S", 40, 410, 10, DARKGRAY);
// Draw framebuffer texture
- DrawTextureRec(framebuffer.texture, (Rectangle){ 0, 0, framebuffer.texture.width, -framebuffer.texture.height },
+ DrawTextureRec(framebuffer.texture, (Rectangle){ 0, 0, framebuffer.texture.width, -framebuffer.texture.height },
(Vector2){ screenWidth - framebuffer.texture.width - 20, 20 }, Fade(WHITE, 0.8f));
-
+
DrawRectangleLines(screenWidth - framebuffer.texture.width - 20, 20, framebuffer.texture.width, framebuffer.texture.height, DARKGRAY);
-
+
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
-
+
// Unload all loaded data
UnloadModel(model);
-
+
UnloadRenderTexture(framebuffer);
-
- UnloadTexture(texAngleGauge);
+
+ UnloadTexture(texAngleGauge);
UnloadTexture(texBackground);
- UnloadTexture(texPitch);
+ UnloadTexture(texPitch);
UnloadTexture(texPlane);
-
+
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
-
+
return 0;
}
@@ -192,7 +193,7 @@ void DrawAngleGauge(Texture2D angleGauge, int x, int y, float angle, char title[
int textSize = 20;
DrawTexturePro(angleGauge, srcRec, dstRec, origin, angle, color);
-
- DrawText(FormatText("%5.1f°", angle), x - MeasureText(FormatText("%5.1f°", angle), textSize) / 2, y + 10, textSize, DARKGRAY);
- DrawText(title, x - MeasureText(title, textSize) / 2, y + 60, textSize, DARKGRAY);
-}
\ No newline at end of file
+
+ DrawText(FormatText("%5.1f", angle), x - MeasureText(FormatText("%5.1f", angle), textSize) / 2, y + 10, textSize, DARKGRAY);
+ DrawText(title, x - MeasureText(title, textSize) / 2, y + 60, textSize, DARKGRAY);
+}
diff --git a/examples/models/resources/angle_gauge.png b/examples/models/resources/angle_gauge.png
index 120f36012..f7871de6d 100644
Binary files a/examples/models/resources/angle_gauge.png and b/examples/models/resources/angle_gauge.png differ
diff --git a/examples/models/resources/plane.png b/examples/models/resources/plane.png
index 9f28ddb04..58951ea3d 100644
Binary files a/examples/models/resources/plane.png and b/examples/models/resources/plane.png differ
diff --git a/examples/models/resources/shaders/pbr.vs b/examples/models/resources/shaders/pbr.vs
index e852ac1a2..885cb199b 100644
--- a/examples/models/resources/shaders/pbr.vs
+++ b/examples/models/resources/shaders/pbr.vs
@@ -12,7 +12,7 @@
in vec3 vertexPosition;
in vec2 vertexTexCoord;
in vec3 vertexNormal;
-in vec3 vertexTangent;
+in vec4 vertexTangent;
// Input uniform values
uniform mat4 mvp;
@@ -28,7 +28,7 @@ out vec3 fragBinormal;
void main()
{
// Calculate binormal from vertex normal and tangent
- vec3 vertexBinormal = cross(vertexNormal, vertexTangent);
+ vec3 vertexBinormal = cross(vertexNormal, vec3(vertexTangent));
// Calculate fragment normal based on normal transformations
mat3 normalMatrix = transpose(inverse(mat3(mMatrix)));
@@ -39,7 +39,7 @@ void main()
// Send vertex attributes to fragment shader
fragTexCoord = vertexTexCoord;
fragNormal = normalize(normalMatrix*vertexNormal);
- fragTangent = normalize(normalMatrix*vertexTangent);
+ fragTangent = normalize(normalMatrix*vec3(vertexTangent));
fragTangent = normalize(fragTangent - dot(fragTangent, fragNormal)*fragNormal);
fragBinormal = normalize(normalMatrix*vertexBinormal);
fragBinormal = cross(fragNormal, fragTangent);
diff --git a/examples/others/audio_standalone.c b/examples/others/audio_standalone.c
index 0a09c988f..38fe9935d 100644
--- a/examples/others/audio_standalone.c
+++ b/examples/others/audio_standalone.c
@@ -26,14 +26,11 @@
********************************************************************************************/
#include
+#include "audio.h"
#if defined(_WIN32)
#include // Windows only, no stardard library
-#endif
-
-#include "audio.h"
-
-#if defined(__linux__)
+#else
#include
#include
#include
@@ -79,13 +76,13 @@ int main()
{
// Initialization
//--------------------------------------------------------------------------------------
- unsigned char key;
-
+ static unsigned char key;
+
InitAudioDevice();
-
+
Sound fxWav = LoadSound("resources/audio/weird.wav"); // Load WAV audio file
Sound fxOgg = LoadSound("resources/audio/tanatana.ogg"); // Load OGG audio file
-
+
Music music = LoadMusicStream("resources/audio/guitar_noodling.ogg");
PlayMusicStream(music);
@@ -102,23 +99,23 @@ int main()
PlaySound(fxWav);
key = 0;
}
-
+
if (key == 'd')
{
PlaySound(fxOgg);
key = 0;
}
-
+
UpdateMusicStream(music);
}
-
+
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadSound(fxWav); // Unload sound data
UnloadSound(fxOgg); // Unload sound data
-
+
UnloadMusicStream(music); // Unload music stream data
-
+
CloseAudioDevice();
//--------------------------------------------------------------------------------------
diff --git a/examples/others/bunnymark.c b/examples/others/bunnymark.c
index 1ada54db4..8b524b011 100644
--- a/examples/others/bunnymark.c
+++ b/examples/others/bunnymark.c
@@ -10,7 +10,6 @@
********************************************************************************************/
#include "raylib.h"
-
#include // Required for: malloc(), free()
#define MAX_BUNNIES 100000 // 100K bunnies
@@ -29,15 +28,16 @@ int main()
int screenHeight = 960;
InitWindow(screenWidth, screenHeight, "raylib example - Bunnymark");
-
+
Texture2D texBunny = LoadTexture("resources/wabbit_alpha.png");
-
+
Bunny *bunnies = (Bunny *)malloc(MAX_BUNNIES*sizeof(Bunny)); // Bunnies array
+
int bunniesCount = 0; // Bunnies counter
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
-
+
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
@@ -54,7 +54,7 @@ int main()
bunniesCount++;
}
}
-
+
// Update bunnies
for (int i = 0; i < bunniesCount; i++)
{
@@ -65,14 +65,14 @@ int main()
if ((bunnies[i].position.y > GetScreenHeight()) || (bunnies[i].position.y < 0)) bunnies[i].speed.y *= -1;
}
//----------------------------------------------------------------------------------
-
+
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
-
- for (int i = 0; i <= bunniesCount; i++)
+
+ for (int i = 0; i < bunniesCount; i++)
{
// NOTE: When internal QUADS batch limit is reached, a draw call is launched and
// batching buffer starts being filled again; before launching the draw call,
@@ -80,11 +80,10 @@ int main()
// a stall and consequently a frame drop, limiting number of bunnies drawn at 60 fps
DrawTexture(texBunny, bunnies[i].position.x, bunnies[i].position.y, RAYWHITE);
}
-
+
DrawRectangle(0, 0, screenWidth, 40, LIGHTGRAY);
DrawText("raylib bunnymark", 10, 10, 20, DARKGRAY);
DrawText(FormatText("bunnies: %i", bunniesCount), 400, 10, 20, RED);
-
DrawFPS(260, 10);
EndDrawing();
@@ -94,9 +93,9 @@ int main()
// De-Initialization
//--------------------------------------------------------------------------------------
free(bunnies);
-
+
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
-}
\ No newline at end of file
+}
diff --git a/examples/others/resources/shaders/glsl100/standard.vs b/examples/others/resources/shaders/glsl100/standard.vs
index 49c5a3ebf..2b958938c 100644
--- a/examples/others/resources/shaders/glsl100/standard.vs
+++ b/examples/others/resources/shaders/glsl100/standard.vs
@@ -10,7 +10,7 @@ varying vec2 fragTexCoord;
varying vec4 fragColor;
varying vec3 fragNormal;
-uniform mat4 mvpMatrix;
+uniform mat4 mvp;
void main()
{
@@ -19,5 +19,5 @@ void main()
fragColor = vertexColor;
fragNormal = vertexNormal;
- gl_Position = mvpMatrix*vec4(vertexPosition, 1.0);
+ gl_Position = mvp*vec4(vertexPosition, 1.0);
}
\ No newline at end of file
diff --git a/examples/others/resources/shaders/glsl330/standard.vs b/examples/others/resources/shaders/glsl330/standard.vs
index fc0a5ff40..7fbdbf5ee 100644
--- a/examples/others/resources/shaders/glsl330/standard.vs
+++ b/examples/others/resources/shaders/glsl330/standard.vs
@@ -10,7 +10,7 @@ out vec2 fragTexCoord;
out vec4 fragColor;
out vec3 fragNormal;
-uniform mat4 mvpMatrix;
+uniform mat4 mvp;
void main()
{
@@ -19,5 +19,5 @@ void main()
fragColor = vertexColor;
fragNormal = vertexNormal;
- gl_Position = mvpMatrix*vec4(vertexPosition, 1.0);
+ gl_Position = mvp*vec4(vertexPosition, 1.0);
}
\ No newline at end of file
diff --git a/examples/physac/physics_demo.c b/examples/physac/physics_demo.c
index 1b54d51b8..d66d2fbec 100644
--- a/examples/physac/physics_demo.c
+++ b/examples/physac/physics_demo.c
@@ -10,7 +10,7 @@
* gcc -o $(NAME_PART).exe $(FILE_NAME) -s $(RAYLIB_DIR)\raylib\raylib_icon -static -lraylib -lpthread
* -lglfw3 -lopengl32 -lgdi32 -lopenal32 -lwinmm -std=c99 -Wl,--subsystem,windows -Wl,-allow-multiple-definition
*
-* Copyright (c) 2017 Victor Fisac
+* Copyright (c) 2016-2018 Victor Fisac
*
********************************************************************************************/
@@ -32,6 +32,7 @@ int main()
// Physac logo drawing position
int logoX = screenWidth - MeasureText("Physac", 30) - 10;
int logoY = 15;
+ bool needsReset = false;
// Initialize physics and default physics bodies
InitPhysics();
@@ -52,10 +53,9 @@ int main()
{
// Update
//----------------------------------------------------------------------------------
- if (IsKeyPressed('R')) // Reset physics input
+ // Delay initialization of variables due to physics reset async
+ if (needsReset)
{
- ResetPhysics();
-
floor = CreatePhysicsBodyRectangle((Vector2){ screenWidth/2, screenHeight }, 500, 100, 10);
floor->enabled = false;
@@ -63,6 +63,13 @@ int main()
circle->enabled = false;
}
+ // Reset physics input
+ if (IsKeyPressed('R'))
+ {
+ ResetPhysics();
+ needsReset = true;
+ }
+
// Physics body creation inputs
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) CreatePhysicsBodyPolygon(GetMousePosition(), GetRandomValue(20, 80), GetRandomValue(3, 8), 10);
else if (IsMouseButtonPressed(MOUSE_RIGHT_BUTTON)) CreatePhysicsBodyCircle(GetMousePosition(), GetRandomValue(10, 45), 10);
diff --git a/examples/physac/physics_friction.c b/examples/physac/physics_friction.c
index 9472729aa..4c81e8c8b 100644
--- a/examples/physac/physics_friction.c
+++ b/examples/physac/physics_friction.c
@@ -10,7 +10,7 @@
* gcc -o $(NAME_PART).exe $(FILE_NAME) -s $(RAYLIB_DIR)\raylib\raylib_icon -static -lraylib -lpthread
* -lglfw3 -lopengl32 -lgdi32 -lopenal32 -lwinmm -std=c99 -Wl,--subsystem,windows -Wl,-allow-multiple-definition
*
-* Copyright (c) 2017 Victor Fisac
+* Copyright (c) 2016-2018 Victor Fisac
*
********************************************************************************************/
diff --git a/examples/physac/physics_movement.c b/examples/physac/physics_movement.c
index 4b2c9ab0e..f828c0544 100644
--- a/examples/physac/physics_movement.c
+++ b/examples/physac/physics_movement.c
@@ -10,7 +10,7 @@
* gcc -o $(NAME_PART).exe $(FILE_NAME) -s $(RAYLIB_DIR)\raylib\raylib_icon -static -lraylib -lpthread
* -lglfw3 -lopengl32 -lgdi32 -lopenal32 -lwinmm -std=c99 -Wl,--subsystem,windows -Wl,-allow-multiple-definition
*
-* Copyright (c) 2017 Victor Fisac
+* Copyright (c) 2016-2018 Victor Fisac
*
********************************************************************************************/
diff --git a/examples/physac/physics_restitution.c b/examples/physac/physics_restitution.c
index 2be8f42e4..93939ebb6 100644
--- a/examples/physac/physics_restitution.c
+++ b/examples/physac/physics_restitution.c
@@ -10,7 +10,7 @@
* gcc -o $(NAME_PART).exe $(FILE_NAME) -s $(RAYLIB_DIR)\raylib\raylib_icon -static -lraylib -lpthread
* -lglfw3 -lopengl32 -lgdi32 -lopenal32 -lwinmm -std=c99 -Wl,--subsystem,windows -Wl,-allow-multiple-definition
*
-* Copyright (c) 2017 Victor Fisac
+* Copyright (c) 2016-2018 Victor Fisac
*
********************************************************************************************/
diff --git a/examples/physac/physics_shatter.c b/examples/physac/physics_shatter.c
index 6b474cd3a..8102e1624 100644
--- a/examples/physac/physics_shatter.c
+++ b/examples/physac/physics_shatter.c
@@ -10,7 +10,7 @@
* gcc -o $(NAME_PART).exe $(FILE_NAME) -s $(RAYLIB_DIR)\raylib\raylib_icon -static -lraylib -lpthread
* -lglfw3 -lopengl32 -lgdi32 -lopenal32 -lwinmm -std=c99 -Wl,--subsystem,windows -Wl,-allow-multiple-definition
*
-* Copyright (c) 2017 Victor Fisac
+* Copyright (c) 2016-2018 Victor Fisac
*
********************************************************************************************/
@@ -32,14 +32,15 @@ int main()
// Physac logo drawing position
int logoX = screenWidth - MeasureText("Physac", 30) - 10;
int logoY = 15;
+ bool needsReset = false;
// Initialize physics and default physics bodies
InitPhysics();
SetPhysicsGravity(0, 0);
// Create random polygon physics body to shatter
- PhysicsBody body = CreatePhysicsBodyPolygon((Vector2){ screenWidth/2, screenHeight/2 }, GetRandomValue(80, 200), GetRandomValue(3, 8), 10);
-
+ CreatePhysicsBodyPolygon((Vector2){ screenWidth/2, screenHeight/2 }, GetRandomValue(80, 200), GetRandomValue(3, 8), 10);
+
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
@@ -48,12 +49,17 @@ int main()
{
// Update
//----------------------------------------------------------------------------------
+ // Delay initialization of variables due to physics reset asynchronous
+ if (needsReset)
+ {
+ // Create random polygon physics body to shatter
+ CreatePhysicsBodyPolygon((Vector2){ screenWidth/2, screenHeight/2 }, GetRandomValue(80, 200), GetRandomValue(3, 8), 10);
+ }
+
if (IsKeyPressed('R')) // Reset physics input
{
ResetPhysics();
-
- // Create random polygon physics body to shatter
- body = CreatePhysicsBodyPolygon((Vector2){ screenWidth/2, screenHeight/2 }, GetRandomValue(80, 200), GetRandomValue(3, 8), 10);
+ needsReset = true;
}
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) // Physics shatter input
diff --git a/examples/shaders/resources/shaders/glsl120/base.fs b/examples/shaders/resources/shaders/glsl120/base.fs
new file mode 100644
index 000000000..18799f957
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/base.fs
@@ -0,0 +1,22 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// NOTE: Add here your custom variables
+uniform vec2 resolution = vec2(800, 450);
+
+void main()
+{
+ // Texel color fetching from texture sampler
+ vec4 texelColor = texture2D(texture0, fragTexCoord);
+
+ // NOTE: Implement here your fragment shader code
+
+ gl_FragColor = texelColor*colDiffuse;
+}
\ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl120/base.vs b/examples/shaders/resources/shaders/glsl120/base.vs
new file mode 100644
index 000000000..674153d8c
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/base.vs
@@ -0,0 +1,26 @@
+#version 120
+
+// Input vertex attributes
+attribute vec3 vertexPosition;
+attribute vec2 vertexTexCoord;
+attribute vec3 vertexNormal;
+attribute vec4 vertexColor;
+
+// Input uniform values
+uniform mat4 mvp;
+
+// Output vertex attributes (to fragment shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// NOTE: Add here your custom variables
+
+void main()
+{
+ // Send vertex attributes to fragment shader
+ fragTexCoord = vertexTexCoord;
+ fragColor = vertexColor;
+
+ // Calculate final vertex position
+ gl_Position = mvp*vec4(vertexPosition, 1.0);
+}
\ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl120/bloom.fs b/examples/shaders/resources/shaders/glsl120/bloom.fs
new file mode 100644
index 000000000..c28836b0d
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/bloom.fs
@@ -0,0 +1,37 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// NOTE: Add here your custom variables
+
+const vec2 size = vec2(800, 450); // render size
+const float samples = 5.0; // pixels per axis; higher = bigger glow, worse performance
+const float quality = 2.5; // lower = smaller glow, better quality
+
+void main()
+{
+ vec4 sum = vec4(0);
+ vec2 sizeFactor = vec2(1)/size*quality;
+
+ // Texel color fetching from texture sampler
+ vec4 source = texture2D(texture0, fragTexCoord);
+
+ const int range = 2; // should be = (samples - 1)/2;
+
+ for (int x = -range; x <= range; x++)
+ {
+ for (int y = -range; y <= range; y++)
+ {
+ sum += texture2D(texture0, fragTexCoord + vec2(x, y)*sizeFactor);
+ }
+ }
+
+ // Calculate final fragment color
+ gl_FragColor = ((sum/(samples*samples)) + source)*colDiffuse;
+}
\ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl120/blur.fs b/examples/shaders/resources/shaders/glsl120/blur.fs
new file mode 100644
index 000000000..99cddfc97
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/blur.fs
@@ -0,0 +1,32 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// NOTE: Add here your custom variables
+
+// NOTE: Render size values must be passed from code
+const float renderWidth = 800.0;
+const float renderHeight = 450.0;
+
+vec3 offset = vec3(0.0, 1.3846153846, 3.2307692308);
+vec3 weight = vec3(0.2270270270, 0.3162162162, 0.0702702703);
+
+void main()
+{
+ // Texel color fetching from texture sampler
+ vec3 tc = texture2D(texture0, fragTexCoord).rgb*weight.x;
+
+ tc += texture2D(texture0, fragTexCoord + vec2(offset.y)/renderWidth, 0.0).rgb*weight.y;
+ tc += texture2D(texture0, fragTexCoord - vec2(offset.y)/renderWidth, 0.0).rgb*weight.y;
+
+ tc += texture2D(texture0, fragTexCoord + vec2(offset.z)/renderWidth, 0.0).rgb*weight.z;
+ tc += texture2D(texture0, fragTexCoord - vec2(offset.z)/renderWidth, 0.0).rgb*weight.z;
+
+ gl_FragColor = vec4(tc, 1.0);
+}
\ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl120/cross_hatching.fs b/examples/shaders/resources/shaders/glsl120/cross_hatching.fs
new file mode 100644
index 000000000..46514120f
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/cross_hatching.fs
@@ -0,0 +1,45 @@
+# version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// NOTE: Add here your custom variables
+
+float hatchOffsetY = 5.0;
+float lumThreshold01 = 0.9;
+float lumThreshold02 = 0.7;
+float lumThreshold03 = 0.5;
+float lumThreshold04 = 0.3;
+
+void main()
+{
+ vec3 tc = vec3(1.0, 1.0, 1.0);
+ float lum = length(texture2D(texture0, fragTexCoord).rgb);
+
+ if (lum < lumThreshold01)
+ {
+ if (mod(gl_FragCoord.x + gl_FragCoord.y, 10.0) == 0.0) tc = vec3(0.0, 0.0, 0.0);
+ }
+
+ if (lum < lumThreshold02)
+ {
+ if (mod(gl_FragCoord .x - gl_FragCoord .y, 10.0) == 0.0) tc = vec3(0.0, 0.0, 0.0);
+ }
+
+ if (lum < lumThreshold03)
+ {
+ if (mod(gl_FragCoord .x + gl_FragCoord .y - hatchOffsetY, 10.0) == 0.0) tc = vec3(0.0, 0.0, 0.0);
+ }
+
+ if (lum < lumThreshold04)
+ {
+ if (mod(gl_FragCoord .x - gl_FragCoord .y - hatchOffsetY, 10.0) == 0.0) tc = vec3(0.0, 0.0, 0.0);
+ }
+
+ gl_FragColor = vec4(tc, 1.0);
+}
\ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl120/cross_stitching.fs b/examples/shaders/resources/shaders/glsl120/cross_stitching.fs
new file mode 100644
index 000000000..dee4617e2
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/cross_stitching.fs
@@ -0,0 +1,55 @@
+# version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// NOTE: Add here your custom variables
+
+// NOTE: Render size values must be passed from code
+const float renderWidth = 800.0;
+const float renderHeight = 450.0;
+
+float stitchingSize = 6.0;
+int invert = 0;
+
+vec4 PostFX(sampler2D tex, vec2 uv)
+{
+ vec4 c = vec4(0.0);
+ float size = stitchingSize;
+ vec2 cPos = uv * vec2(renderWidth, renderHeight);
+ vec2 tlPos = floor(cPos / vec2(size, size));
+ tlPos *= size;
+
+ int remX = int(mod(cPos.x, size));
+ int remY = int(mod(cPos.y, size));
+
+ if (remX == 0 && remY == 0) tlPos = cPos;
+
+ vec2 blPos = tlPos;
+ blPos.y += (size - 1.0);
+
+ if ((remX == remY) || (((int(cPos.x) - int(blPos.x)) == (int(blPos.y) - int(cPos.y)))))
+ {
+ if (invert == 1) c = vec4(0.2, 0.15, 0.05, 1.0);
+ else c = texture2D(tex, tlPos * vec2(1.0/renderWidth, 1.0/renderHeight)) * 1.4;
+ }
+ else
+ {
+ if (invert == 1) c = texture2D(tex, tlPos * vec2(1.0/renderWidth, 1.0/renderHeight)) * 1.4;
+ else c = vec4(0.0, 0.0, 0.0, 1.0);
+ }
+
+ return c;
+}
+
+void main()
+{
+ vec3 tc = PostFX(texture0, fragTexCoord).rgb;
+
+ gl_FragColor = vec4(tc, 1.0);
+}
\ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl120/distortion.fs b/examples/shaders/resources/shaders/glsl120/distortion.fs
new file mode 100644
index 000000000..f9d7f1e5a
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/distortion.fs
@@ -0,0 +1,52 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+
+// Input uniform values
+uniform sampler2D texture0;
+
+// NOTE: Default parameters for Oculus Rift DK2 device
+const vec2 LeftLensCenter = vec2(0.2863248, 0.5);
+const vec2 RightLensCenter = vec2(0.7136753, 0.5);
+const vec2 LeftScreenCenter = vec2(0.25, 0.5);
+const vec2 RightScreenCenter = vec2(0.75, 0.5);
+const vec2 Scale = vec2(0.25, 0.45);
+const vec2 ScaleIn = vec2(4.0, 2.5);
+const vec4 HmdWarpParam = vec4(1.0, 0.22, 0.24, 0.0);
+const vec4 ChromaAbParam = vec4(0.996, -0.004, 1.014, 0.0);
+
+void main()
+{
+ // The following two variables need to be set per eye
+ vec2 LensCenter = fragTexCoord.x < 0.5 ? LeftLensCenter : RightLensCenter;
+ vec2 ScreenCenter = fragTexCoord.x < 0.5 ? LeftScreenCenter : RightScreenCenter;
+
+ // Scales input texture coordinates for distortion: vec2 HmdWarp(vec2 fragTexCoord, vec2 LensCenter)
+ vec2 theta = (fragTexCoord - LensCenter)*ScaleIn; // Scales to [-1, 1]
+ float rSq = theta.x*theta.x + theta.y*theta.y;
+ vec2 theta1 = theta*(HmdWarpParam.x + HmdWarpParam.y*rSq + HmdWarpParam.z*rSq*rSq + HmdWarpParam.w*rSq*rSq*rSq);
+ //vec2 tc = LensCenter + Scale*theta1;
+
+ // Detect whether blue texture coordinates are out of range since these will scaled out the furthest
+ vec2 thetaBlue = theta1*(ChromaAbParam.z + ChromaAbParam.w*rSq);
+ vec2 tcBlue = LensCenter + Scale*thetaBlue;
+
+ if (any(bvec2(clamp(tcBlue, ScreenCenter - vec2(0.25, 0.5), ScreenCenter + vec2(0.25, 0.5)) - tcBlue))) gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
+ else
+ {
+ // Do blue texture lookup
+ float blue = texture2D(texture0, tcBlue).b;
+
+ // Do green lookup (no scaling)
+ vec2 tcGreen = LensCenter + Scale*theta1;
+ float green = texture2D(texture0, tcGreen).g;
+
+ // Do red scale and lookup
+ vec2 thetaRed = theta1*(ChromaAbParam.x + ChromaAbParam.y*rSq);
+ vec2 tcRed = LensCenter + Scale*thetaRed;
+ float red = texture2D(texture0, tcRed).r;
+
+ gl_FragColor = vec4(red, green, blue, 1.0);
+ }
+}
diff --git a/examples/shaders/resources/shaders/glsl120/dream_vision.fs b/examples/shaders/resources/shaders/glsl120/dream_vision.fs
new file mode 100644
index 000000000..4ca2a8634
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/dream_vision.fs
@@ -0,0 +1,35 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// NOTE: Add here your custom variables
+
+void main()
+{
+ vec4 color = texture2D(texture0, fragTexCoord);
+
+ color += texture2D(texture0, fragTexCoord + 0.001);
+ color += texture2D(texture0, fragTexCoord + 0.003);
+ color += texture2D(texture0, fragTexCoord + 0.005);
+ color += texture2D(texture0, fragTexCoord + 0.007);
+ color += texture2D(texture0, fragTexCoord + 0.009);
+ color += texture2D(texture0, fragTexCoord + 0.011);
+
+ color += texture2D(texture0, fragTexCoord - 0.001);
+ color += texture2D(texture0, fragTexCoord - 0.003);
+ color += texture2D(texture0, fragTexCoord - 0.005);
+ color += texture2D(texture0, fragTexCoord - 0.007);
+ color += texture2D(texture0, fragTexCoord - 0.009);
+ color += texture2D(texture0, fragTexCoord - 0.011);
+
+ color.rgb = vec3((color.r + color.g + color.b)/3.0);
+ color = color/9.5;
+
+ gl_FragColor = color;
+}
\ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl120/fisheye.fs b/examples/shaders/resources/shaders/glsl120/fisheye.fs
new file mode 100644
index 000000000..6f376ba39
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/fisheye.fs
@@ -0,0 +1,41 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// NOTE: Add here your custom variables
+
+const float PI = 3.1415926535;
+
+void main()
+{
+ float aperture = 178.0;
+ float apertureHalf = 0.5 * aperture * (PI / 180.0);
+ float maxFactor = sin(apertureHalf);
+
+ vec2 uv = vec2(0.0);
+ vec2 xy = 2.0 * fragTexCoord.xy - 1.0;
+ float d = length(xy);
+
+ if (d < (2.0 - maxFactor))
+ {
+ d = length(xy * maxFactor);
+ float z = sqrt(1.0 - d * d);
+ float r = atan(d, z) / PI;
+ float phi = atan(xy.y, xy.x);
+
+ uv.x = r * cos(phi) + 0.5;
+ uv.y = r * sin(phi) + 0.5;
+ }
+ else
+ {
+ uv = fragTexCoord.xy;
+ }
+
+ gl_FragColor = texture2D(texture0, uv);
+}
\ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl120/grayscale.fs b/examples/shaders/resources/shaders/glsl120/grayscale.fs
new file mode 100644
index 000000000..4de60d224
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/grayscale.fs
@@ -0,0 +1,23 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// NOTE: Add here your custom variables
+
+void main()
+{
+ // Texel color fetching from texture sampler
+ vec4 texelColor = texture2D(texture0, fragTexCoord)*colDiffuse*fragColor;
+
+ // Convert texel color to grayscale using NTSC conversion weights
+ float gray = dot(texelColor.rgb, vec3(0.299, 0.587, 0.114));
+
+ // Calculate final fragment color
+ gl_FragColor = vec4(gray, gray, gray, texelColor.a);
+}
\ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl120/pixelizer.fs b/examples/shaders/resources/shaders/glsl120/pixelizer.fs
new file mode 100644
index 000000000..6f741fafc
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/pixelizer.fs
@@ -0,0 +1,30 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// NOTE: Add here your custom variables
+
+// NOTE: Render size values must be passed from code
+const float renderWidth = 800.0;
+const float renderHeight = 450.0;
+
+float pixelWidth = 5.0;
+float pixelHeight = 5.0;
+
+void main()
+{
+ float dx = pixelWidth*(1.0/renderWidth);
+ float dy = pixelHeight*(1.0/renderHeight);
+
+ vec2 coord = vec2(dx*floor(fragTexCoord.x/dx), dy*floor(fragTexCoord.y/dy));
+
+ vec3 tc = texture2D(texture0, coord).rgb;
+
+ gl_FragColor = vec4(tc, 1.0);
+}
\ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl120/posterization.fs b/examples/shaders/resources/shaders/glsl120/posterization.fs
new file mode 100644
index 000000000..475b93a16
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/posterization.fs
@@ -0,0 +1,27 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// NOTE: Add here your custom variables
+
+float gamma = 0.6;
+float numColors = 8.0;
+
+void main()
+{
+ vec3 color = texture2D(texture0, fragTexCoord.xy).rgb;
+
+ color = pow(color, vec3(gamma, gamma, gamma));
+ color = color*numColors;
+ color = floor(color);
+ color = color/numColors;
+ color = pow(color, vec3(1.0/gamma));
+
+ gl_FragColor = vec4(color, 1.0);
+}
\ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl120/predator.fs b/examples/shaders/resources/shaders/glsl120/predator.fs
new file mode 100644
index 000000000..2999cc8dd
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/predator.fs
@@ -0,0 +1,29 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// NOTE: Add here your custom variables
+
+void main()
+{
+ vec3 color = texture2D(texture0, fragTexCoord).rgb;
+ vec3 colors[3];
+ colors[0] = vec3(0.0, 0.0, 1.0);
+ colors[1] = vec3(1.0, 1.0, 0.0);
+ colors[2] = vec3(1.0, 0.0, 0.0);
+
+ float lum = (color.r + color.g + color.b)/3.0;
+
+ vec3 tc = vec3(0.0, 0.0, 0.0);
+
+ if (lum < 0.5) tc = mix(colors[0], colors[1], lum/0.5);
+ else tc = mix(colors[1], colors[2], (lum - 0.5)/0.5);
+
+ gl_FragColor = vec4(tc, 1.0);
+}
\ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl120/scanlines.fs b/examples/shaders/resources/shaders/glsl120/scanlines.fs
new file mode 100644
index 000000000..929c79eba
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/scanlines.fs
@@ -0,0 +1,42 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// NOTE: Add here your custom variables
+
+float offset = 0.0;
+float frequency = 450.0/3.0;
+
+uniform float time;
+
+void main()
+{
+/*
+ // Scanlines method 1
+ float tval = 0; //time
+ vec2 uv = 0.5 + (fragTexCoord - 0.5)*(0.9 + 0.01*sin(0.5*tval));
+
+ vec4 color = texture2D(texture0, fragTexCoord);
+
+ color = clamp(color*0.5 + 0.5*color*color*1.2, 0.0, 1.0);
+ color *= 0.5 + 0.5*16.0*uv.x*uv.y*(1.0 - uv.x)*(1.0 - uv.y);
+ color *= vec4(0.8, 1.0, 0.7, 1);
+ color *= 0.9 + 0.1*sin(10.0*tval + uv.y*1000.0);
+ color *= 0.97 + 0.03*sin(110.0*tval);
+
+ fragColor = color;
+*/
+ // Scanlines method 2
+ float globalPos = (fragTexCoord.y + offset) * frequency;
+ float wavePos = cos((fract(globalPos) - 0.5)*3.14);
+
+ vec4 color = texture2D(texture0, fragTexCoord);
+
+ gl_FragColor = mix(vec4(0.0, 0.3, 0.0, 0.0), color, wavePos);
+}
\ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl120/sobel.fs b/examples/shaders/resources/shaders/glsl120/sobel.fs
new file mode 100644
index 000000000..a3f3f2bf7
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/sobel.fs
@@ -0,0 +1,38 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// NOTE: Add here your custom variables
+vec2 resolution = vec2(800.0, 450.0);
+
+void main()
+{
+ float x = 1.0/resolution.x;
+ float y = 1.0/resolution.y;
+
+ vec4 horizEdge = vec4(0.0);
+ horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y))*1.0;
+ horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y ))*2.0;
+ horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y))*1.0;
+ horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y))*1.0;
+ horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y ))*2.0;
+ horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y))*1.0;
+
+ vec4 vertEdge = vec4(0.0);
+ vertEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y))*1.0;
+ vertEdge -= texture2D(texture0, vec2(fragTexCoord.x , fragTexCoord.y - y))*2.0;
+ vertEdge -= texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y))*1.0;
+ vertEdge += texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y))*1.0;
+ vertEdge += texture2D(texture0, vec2(fragTexCoord.x , fragTexCoord.y + y))*2.0;
+ vertEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y))*1.0;
+
+ vec3 edge = sqrt((horizEdge.rgb*horizEdge.rgb) + (vertEdge.rgb*vertEdge.rgb));
+
+ gl_FragColor = vec4(edge, texture2D(texture0, fragTexCoord).a);
+}
\ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl120/swirl.fs b/examples/shaders/resources/shaders/glsl120/swirl.fs
new file mode 100644
index 000000000..0618e013f
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/swirl.fs
@@ -0,0 +1,44 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// NOTE: Add here your custom variables
+
+// NOTE: Render size values should be passed from code
+const float renderWidth = 800;
+const float renderHeight = 450;
+
+float radius = 250.0;
+float angle = 0.8;
+
+uniform vec2 center;
+
+void main()
+{
+ vec2 texSize = vec2(renderWidth, renderHeight);
+ vec2 tc = fragTexCoord*texSize;
+ tc -= center;
+
+ float dist = length(tc);
+
+ if (dist < radius)
+ {
+ float percent = (radius - dist)/radius;
+ float theta = percent*percent*angle*8.0;
+ float s = sin(theta);
+ float c = cos(theta);
+
+ tc = vec2(dot(tc, vec2(c, -s)), dot(tc, vec2(s, c)));
+ }
+
+ tc += center;
+ vec4 color = texture2D(texture0, tc/texSize)*colDiffuse*fragColor;;
+
+ gl_FragColor = vec4(color.rgb, 1.0);;
+}
\ No newline at end of file
diff --git a/examples/shaders/shaders_custom_uniform.c b/examples/shaders/shaders_custom_uniform.c
index a0f6fd22b..4e160455a 100644
--- a/examples/shaders/shaders_custom_uniform.c
+++ b/examples/shaders/shaders_custom_uniform.c
@@ -30,7 +30,12 @@ int main()
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - custom uniform variable");
// Define the camera to look into our 3d world
- Camera camera = {{ 3.0f, 3.0f, 3.0f }, { 0.0f, 1.5f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f };
+ Camera camera = { 0 };
+ camera.position = (Vector3){ 3.0f, 3.0f, 3.0f };
+ camera.target = (Vector3){ 0.0f, 1.5f, 0.0f };
+ camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
+ camera.fovy = 45.0f;
+ camera.type = CAMERA_PERSPECTIVE;
Model dwarf = LoadModel("resources/model/dwarf.obj"); // Load OBJ model
Texture2D texture = LoadTexture("resources/model/dwarf_diffuse.png"); // Load model texture (diffuse map)
diff --git a/examples/shaders/shaders_model_shader.c b/examples/shaders/shaders_model_shader.c
index f1a349c65..51acc8368 100644
--- a/examples/shaders/shaders_model_shader.c
+++ b/examples/shaders/shaders_model_shader.c
@@ -30,7 +30,12 @@ int main()
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - model shader");
// Define the camera to look into our 3d world
- Camera camera = {{ 3.0f, 3.0f, 3.0f }, { 0.0f, 1.5f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f };
+ Camera camera = { 0 };
+ camera.position = (Vector3){ 3.0f, 3.0f, 3.0f };
+ camera.target = (Vector3){ 0.0f, 1.5f, 0.0f };
+ camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
+ camera.fovy = 45.0f;
+ camera.type = CAMERA_PERSPECTIVE;
Model dwarf = LoadModel("resources/model/dwarf.obj"); // Load OBJ model
Texture2D texture = LoadTexture("resources/model/dwarf_diffuse.png"); // Load model texture
diff --git a/examples/shaders/shaders_postprocessing.c b/examples/shaders/shaders_postprocessing.c
index 4aac5f911..5eeda8968 100644
--- a/examples/shaders/shaders_postprocessing.c
+++ b/examples/shaders/shaders_postprocessing.c
@@ -20,10 +20,8 @@
#if defined(PLATFORM_DESKTOP)
#define GLSL_VERSION 330
- #define DEFAULT_VERTEX_SHADER "resources/shaders/glsl330/base.vs"
#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB
#define GLSL_VERSION 100
- #define DEFAULT_VERTEX_SHADER "resources/shaders/glsl100/base.vs"
#endif
#define MAX_POSTPRO_SHADERS 12
@@ -72,7 +70,7 @@ int main()
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - postprocessing shader");
// Define the camera to look into our 3d world
- Camera camera = {{ 3.0f, 3.0f, 3.0f }, { 0.0f, 1.5f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f };
+ Camera camera = {{ 3.0f, 3.0f, 3.0f }, { 0.0f, 1.5f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f, 0 };
Model dwarf = LoadModel("resources/model/dwarf.obj"); // Load OBJ model
Texture2D texture = LoadTexture("resources/model/dwarf_diffuse.png"); // Load model texture (diffuse map)
@@ -85,18 +83,19 @@ int main()
// NOTE 2: We load the correct shader depending on GLSL version
Shader shaders[MAX_POSTPRO_SHADERS];
- shaders[FX_GRAYSCALE] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/grayscale.fs", GLSL_VERSION));
- shaders[FX_POSTERIZATION] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/posterization.fs", GLSL_VERSION));
- shaders[FX_DREAM_VISION] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/dream_vision.fs", GLSL_VERSION));
- shaders[FX_PIXELIZER] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/pixelizer.fs", GLSL_VERSION));
- shaders[FX_CROSS_HATCHING] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/cross_hatching.fs", GLSL_VERSION));
- shaders[FX_CROSS_STITCHING] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/cross_stitching.fs", GLSL_VERSION));
- shaders[FX_PREDATOR_VIEW] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/predator.fs", GLSL_VERSION));
- shaders[FX_SCANLINES] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/scanlines.fs", GLSL_VERSION));
- shaders[FX_FISHEYE] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/fisheye.fs", GLSL_VERSION));
- shaders[FX_SOBEL] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/sobel.fs", GLSL_VERSION));
- shaders[FX_BLOOM] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/bloom.fs", GLSL_VERSION));
- shaders[FX_BLUR] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/blur.fs", GLSL_VERSION));
+ // NOTE: Defining 0 (NULL) for vertex shader forces usage of internal default vertex shader
+ shaders[FX_GRAYSCALE] = LoadShader(0, FormatText("resources/shaders/glsl%i/grayscale.fs", GLSL_VERSION));
+ shaders[FX_POSTERIZATION] = LoadShader(0, FormatText("resources/shaders/glsl%i/posterization.fs", GLSL_VERSION));
+ shaders[FX_DREAM_VISION] = LoadShader(0, FormatText("resources/shaders/glsl%i/dream_vision.fs", GLSL_VERSION));
+ shaders[FX_PIXELIZER] = LoadShader(0, FormatText("resources/shaders/glsl%i/pixelizer.fs", GLSL_VERSION));
+ shaders[FX_CROSS_HATCHING] = LoadShader(0, FormatText("resources/shaders/glsl%i/cross_hatching.fs", GLSL_VERSION));
+ shaders[FX_CROSS_STITCHING] = LoadShader(0, FormatText("resources/shaders/glsl%i/cross_stitching.fs", GLSL_VERSION));
+ shaders[FX_PREDATOR_VIEW] = LoadShader(0, FormatText("resources/shaders/glsl%i/predator.fs", GLSL_VERSION));
+ shaders[FX_SCANLINES] = LoadShader(0, FormatText("resources/shaders/glsl%i/scanlines.fs", GLSL_VERSION));
+ shaders[FX_FISHEYE] = LoadShader(0, FormatText("resources/shaders/glsl%i/fisheye.fs", GLSL_VERSION));
+ shaders[FX_SOBEL] = LoadShader(0, FormatText("resources/shaders/glsl%i/sobel.fs", GLSL_VERSION));
+ shaders[FX_BLOOM] = LoadShader(0, FormatText("resources/shaders/glsl%i/bloom.fs", GLSL_VERSION));
+ shaders[FX_BLUR] = LoadShader(0, FormatText("resources/shaders/glsl%i/blur.fs", GLSL_VERSION));
int currentShader = FX_GRAYSCALE;
@@ -177,4 +176,4 @@ int main()
//--------------------------------------------------------------------------------------
return 0;
-}
\ No newline at end of file
+}
diff --git a/examples/text/text_input_box.c b/examples/text/text_input_box.c
index 54eebf40b..5f8d1c018 100644
--- a/examples/text/text_input_box.c
+++ b/examples/text/text_input_box.c
@@ -52,7 +52,7 @@ int main()
letterCount++;
}
- if (key == KEY_BACKSPACE)
+ if (IsKeyPressed(KEY_BACKSPACE))
{
letterCount--;
name[letterCount] = '\0';
diff --git a/examples/text/text_ttf_loading.c b/examples/text/text_ttf_loading.c
index c9c2fb274..fedfbfb8e 100644
--- a/examples/text/text_ttf_loading.c
+++ b/examples/text/text_ttf_loading.c
@@ -32,7 +32,7 @@ int main()
GenTextureMipmaps(&font.texture);
float fontSize = font.baseSize;
- Vector2 fontPosition = { 40, screenHeight/2 + 50 };
+ Vector2 fontPosition = { 40, screenHeight/2 - 50 };
Vector2 textSize;
SetTextureFilter(font.texture, FILTER_POINT);
diff --git a/examples/textures/resources/KAISG.ttf b/examples/textures/resources/KAISG.ttf
new file mode 100644
index 000000000..04478b25c
Binary files /dev/null and b/examples/textures/resources/KAISG.ttf differ
diff --git a/examples/textures/textures_image_generation.c b/examples/textures/textures_image_generation.c
index 7d8e017e2..790c34f1c 100644
--- a/examples/textures/textures_image_generation.c
+++ b/examples/textures/textures_image_generation.c
@@ -24,10 +24,10 @@ int main()
Image verticalGradient = GenImageGradientV(screenWidth, screenHeight, RED, BLUE);
Image horizontalGradient = GenImageGradientH(screenWidth, screenHeight, RED, BLUE);
- Image radialGradient = GenImageGradientRadial(screenWidth, screenHeight, 0.f, WHITE, BLACK);
+ Image radialGradient = GenImageGradientRadial(screenWidth, screenHeight, 0.0f, WHITE, BLACK);
Image checked = GenImageChecked(screenWidth, screenHeight, 32, 32, RED, BLUE);
Image whiteNoise = GenImageWhiteNoise(screenWidth, screenHeight, 0.5f);
- Image perlinNoise = GenImagePerlinNoise(screenWidth, screenHeight, 8.f);
+ Image perlinNoise = GenImagePerlinNoise(screenWidth, screenHeight, 50, 50, 4.0f);
Image cellular = GenImageCellular(screenWidth, screenHeight, 32);
Texture2D textures[NUM_TEXTURES];
diff --git a/examples/textures/textures_image_text.c b/examples/textures/textures_image_text.c
new file mode 100644
index 000000000..1d4231f74
--- /dev/null
+++ b/examples/textures/textures_image_text.c
@@ -0,0 +1,83 @@
+/*******************************************************************************************
+*
+* raylib [texture] example - Image text drawing using TTF generated spritefont
+*
+* This example has been created using raylib 1.8 (www.raylib.com)
+* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+*
+* Copyright (c) 2017 Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+int main()
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ int screenWidth = 800;
+ int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [texture] example - image text drawing");
+
+ // TTF SpriteFont loading with custom generation parameters
+ SpriteFont font = LoadSpriteFontEx("resources/KAISG.ttf", 64, 0, 0);
+
+ Image parrots = LoadImage("resources/parrots.png"); // Load image in CPU memory (RAM)
+
+ // Draw over image using custom font
+ ImageDrawTextEx(&parrots, (Vector2){ 20, 20 }, font, "[Parrots font drawing]", font.baseSize, 0, WHITE);
+
+ Texture2D texture = LoadTextureFromImage(parrots); // Image converted to texture, uploaded to GPU memory (VRAM)
+ UnloadImage(parrots); // Once image has been converted to texture and uploaded to VRAM, it can be unloaded from RAM
+
+ Vector2 position = { screenWidth/2 - texture.width/2, screenHeight/2 - texture.height/2 - 20 };
+
+ bool showFont = false;
+
+ SetTargetFPS(60);
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ if (IsKeyDown(KEY_SPACE)) showFont = true;
+ else showFont = false;
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ if (!showFont)
+ {
+ // Draw texture with text already drawn inside
+ DrawTextureV(texture, position, WHITE);
+
+ // Draw text directly using sprite font
+ DrawTextEx(font, "[Parrots font drawing]", (Vector2){ position.x + 20,
+ position.y + 20 + 280 }, font.baseSize, 0, WHITE);
+ }
+ else DrawTexture(font.texture, screenWidth/2 - font.texture.width/2, 50, BLACK);
+
+ DrawText("PRESS SPACE to SEE USED SPRITEFONT ", 290, 420, 10, DARKGRAY);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ UnloadTexture(texture); // Texture unloading
+
+ UnloadSpriteFont(font); // Unload custom spritefont
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
\ No newline at end of file
diff --git a/examples/textures/textures_image_text.png b/examples/textures/textures_image_text.png
new file mode 100644
index 000000000..dafbabfb6
Binary files /dev/null and b/examples/textures/textures_image_text.png differ
diff --git a/games/Makefile b/games/Makefile
index 7c8fc9389..c299e0657 100644
--- a/games/Makefile
+++ b/games/Makefile
@@ -2,7 +2,7 @@
#
# raylib makefile for Desktop platforms, Raspberry Pi, Android and HTML5
#
-# Copyright (c) 2013-2017 Ramon Santamaria (@raysan5)
+# Copyright (c) 2013-2018 Ramon Santamaria (@raysan5)
#
# This software is provided "as-is", without any express or implied warranty. In no event
# will the authors be held liable for any damages arising from the use of this software.
@@ -29,72 +29,87 @@ PLATFORM ?= PLATFORM_DESKTOP
RAYLIB_PATH ?= ..
PROJECT_NAME ?= sample_game
-# Library type used for raylib and OpenAL Soft: STATIC (.a) or SHARED (.so/.dll)
-# NOTE: Libraries should be provided in the selected form
-RAYLIB_LIBTYPE ?= STATIC
-OPENAL_LIBTYPE ?= STATIC
-
-# On PLATFORM_WEB force OpenAL Soft shared library
-ifeq ($(PLATFORM),PLATFORM_WEB)
- OPENAL_LIBTYPE = SHARED
+# Default path for raylib on Raspberry Pi, if installed in different path, update it!
+ifeq ($(PLATFORM),PLATFORM_RPI)
+ RAYLIB_PATH ?= /home/pi/raylib
endif
+# Library type used for raylib: STATIC (.a) or SHARED (.so/.dll)
+RAYLIB_LIBTYPE ?= STATIC
+
+# Use external GLFW library instead of rglfw module
+USE_EXTERNAL_GLFW ?= FALSE
+
+# Use Wayland display server protocol on Linux desktop
+# by default it uses X11 windowing system
+USE_WAYLAND_DISPLAY ?= FALSE
+
+# NOTE: On PLATFORM_WEB OpenAL Soft backend is used by default (check raylib/src/Makefile)
+
+
# Determine PLATFORM_OS in case PLATFORM_DESKTOP selected
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
- # No uname.exe on MinGW!, but OS=Windows_NT on Windows! ifeq ($(UNAME),Msys) -> Windows
+ # No uname.exe on MinGW!, but OS=Windows_NT on Windows!
+ # ifeq ($(UNAME),Msys) -> Windows
ifeq ($(OS),Windows_NT)
PLATFORM_OS=WINDOWS
- LIBPATH=win32
else
UNAMEOS=$(shell uname)
ifeq ($(UNAMEOS),Linux)
PLATFORM_OS=LINUX
- LIBPATH=linux
- else
+ endif
+ ifeq ($(UNAMEOS),FreeBSD)
+ PLATFORM_OS=FREEBSD
+ endif
ifeq ($(UNAMEOS),Darwin)
PLATFORM_OS=OSX
- LIBPATH=osx
- endif
endif
endif
endif
-
ifeq ($(PLATFORM),PLATFORM_RPI)
- # RPI cross-compiler
- RPI_CROSS_COMPILE ?= NO
+ UNAMEOS=$(shell uname)
+ ifeq ($(UNAMEOS),Linux)
+ PLATFORM_OS=LINUX
+ endif
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
# Emscripten required variables
EMSDK_PATH = C:/emsdk
- EMSCRIPTEN_VERSION = 1.37.21
- CLANG_VERSION=e1.37.21_64bit
+ EMSCRIPTEN_VERSION = 1.37.28
+ CLANG_VERSION=e1.37.28_64bit
PYTHON_VERSION=2.7.5.3_64bit
NODE_VERSION=4.1.1_64bit
export PATH=$(EMSDK_PATH);$(EMSDK_PATH)\clang\$(CLANG_VERSION);$(EMSDK_PATH)\node\$(NODE_VERSION)\bin;$(EMSDK_PATH)\python\$(PYTHON_VERSION);$(EMSDK_PATH)\emscripten\$(EMSCRIPTEN_VERSION);C:\raylib\MinGW\bin:$$(PATH)
EMSCRIPTEN=$(EMSDK_PATH)\emscripten\$(EMSCRIPTEN_VERSION)
endif
+RAYLIB_RELEASE_PATH ?= $(RAYLIB_PATH)/release/libs
+
# Define raylib release directory for compiled library
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),WINDOWS)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/win32/mingw32
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/win32/mingw32
endif
ifeq ($(PLATFORM_OS),LINUX)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/linux
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/linux
endif
ifeq ($(PLATFORM_OS),OSX)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/osx
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/osx
+ endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/freebsd
endif
endif
-ifeq ($(PLATFORM),PLATFORM_WEB)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/html5
-endif
ifeq ($(PLATFORM),PLATFORM_RPI)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/rpi
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/rpi
+endif
+ifeq ($(PLATFORM),PLATFORM_WEB)
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/html5
endif
# Define default C compiler: gcc
+# NOTE: define g++ compiler if using C++
CC = gcc
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
@@ -102,11 +117,16 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
# OSX default compiler
CC = clang
endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ # FreeBSD default compiler
+ CC = clang
+ endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
- ifeq ($(RPI_CROSS_COMPILE),YES)
- # RPI cross-compiler
- CC = armv6j-hardfloat-linux-gnueabi-gcc
+ ifeq ($(USE_RPI_CROSS_COMPILER),TRUE)
+ # Define RPI cross-compiler
+ #CC = armv6j-hardfloat-linux-gnueabi-gcc
+ CC = $(RPI_TOOLCHAIN)/bin/arm-linux-gnueabihf-gcc
endif
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
@@ -125,19 +145,23 @@ endif
# Define compiler flags:
# -O1 defines optimization level
-# -Og enable debugging
+# -g enable debugging
# -s strip unnecessary data from build
# -Wall turns on most, but not all, compiler warnings
# -std=c99 defines C language mode (standard C from 1999 revision)
# -std=gnu99 defines C language mode (GNU C from 1999 revision)
-# -fgnu89-inline declaring inline functions support (GCC optimized)
# -Wno-missing-braces ignore invalid warning (GCC bug 53119)
# -D_DEFAULT_SOURCE use with -std=c99 on Linux and PLATFORM_WEB, required for timespec
-CFLAGS += -O1 -s -Wall -std=c99 -D_DEFAULT_SOURCE -fgnu89-inline -Wno-missing-braces
+CFLAGS += -O1 -s -Wall -std=c99 -D_DEFAULT_SOURCE -Wno-missing-braces
# Additional flags for compiler (if desired)
#CFLAGS += -Wextra -Wmissing-prototypes -Wstrict-prototypes
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ ifeq ($(PLATFORM_OS),WINDOWS)
+ # resources file contains windows exe icon
+ # -Wl,--subsystem,windows hides the console window
+ CFLAGS += $(RAYLIB_PATH)/src/resources -Wl,--subsystem,windows
+ endif
ifeq ($(PLATFORM_OS),LINUX)
CFLAGS += -no-pie -D_DEFAULT_SOURCE
endif
@@ -151,7 +175,13 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
# -s ALLOW_MEMORY_GROWTH=1 # to allow memory resizing
# -s TOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB)
# -s USE_PTHREADS=1 # multithreading support
- CFLAGS += -s USE_GLFW=3 -s ASSERTIONS=1 --profiling -s TOTAL_MEMORY=16777216 --preload-file resources
+ # -s WASM=1 # support Web Assembly (https://github.com/kripken/emscripten/wiki/WebAssembly)
+ # --preload-file resources # specify a resources folder for data compilation
+ CFLAGS += -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 --profiling --preload-file resources
+
+ # Define a custom shell .html and output extension
+ CFLAGS += --shell-file $(RAYLIB_PATH)\templates\web_shell\shell.html
+ EXT = .html
endif
# Define include paths for required headers
@@ -167,7 +197,14 @@ ifeq ($(PLATFORM),PLATFORM_RPI)
endif
# Define library paths containing required libs
-LDFLAGS = -L. -L$(RAYLIB_RELEASE) -L$(RAYLIB_PATH)/src
+LDFLAGS = -L. -L$(RAYLIB_RELEASE_PATH) -L$(RAYLIB_PATH)/src
+
+ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ INCLUDE_PATHS += -I/usr/local/include
+ LDFLAGS += -L. -Lsrc -L/usr/local/lib
+ endif
+endif
ifeq ($(PLATFORM),PLATFORM_RPI)
LDFLAGS += -L/opt/vc/lib
@@ -177,57 +214,53 @@ endif
# if you want to link libraries (libname.so or libname.a), use the -lname
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),WINDOWS)
- # Libraries for Windows desktop compiling
- # NOTE: GLFW3 and OpenAL Soft libraries should be installed
- LDLIBS = -lraylib -lglfw3 -lopengl32 -lgdi32
-
- # Define required flags and libs for OpenAL Soft STATIC/SHARED usage
- # NOTE: ALLIBS flag only required for raylib Win32 SHARED library building
- ifeq ($(OPENAL_LIBTYPE),STATIC)
- LDLIBS += -lopenal32 -lwinmm
- CFLAGS += -DAL_LIBTYPE_STATIC -Wl,-allow-multiple-definition
- else
- LDLIBS += -lopenal32dll
- endif
+ # Libraries for Windows desktop compilation
+ LDLIBS = -lraylib -lopengl32 -lgdi32
endif
ifeq ($(PLATFORM_OS),LINUX)
# Libraries for Debian GNU/Linux desktop compiling
- # NOTE: Required packages: libglfw3-dev libopenal-dev libegl1-mesa-dev
- LDLIBS = -lraylib -lglfw3 -lGL -lopenal -lm -lpthread -ldl
+ # NOTE: Required packages: libegl1-mesa-dev
+ LDLIBS = -lraylib -lGL -lm -lpthread -ldl -lrt
- # On XWindow requires also below libraries
- LDLIBS += -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
+ # On X11 requires also below libraries
+ LDLIBS += -lX11
+ # NOTE: It seems additional libraries are not required any more, latest GLFW just dlopen them
+ #LDLIBS += -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
+
+ # On Wayland windowing system, additional libraries requires
+ ifeq ($(USE_WAYLAND_DISPLAY),TRUE)
+ LDLIBS += -lwayland-client -lwayland-cursor -lwayland-egl -lxkbcommon
+ endif
endif
ifeq ($(PLATFORM_OS),OSX)
# Libraries for OSX 10.9 desktop compiling
- # NOTE: Required packages: libglfw3-dev libopenal-dev libegl1-mesa-dev
- LDLIBS = -lraylib -lglfw -framework OpenGL -framework OpenAL -framework Cocoa
+ # NOTE: Required packages: libopenal-dev libegl1-mesa-dev
+ LDLIBS = -lraylib -framework OpenGL -framework OpenAL -framework Cocoa
+ endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ # Libraries for FreeBSD desktop compiling
+ # NOTE: Required packages: mesa-libs
+ LDLIBS = -lraylib -lGL -lpthread -lm
+
+ # On XWindow requires also below libraries
+ LDLIBS += -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
+ endif
+ ifeq ($(USE_EXTERNAL_GLFW),TRUE)
+ # NOTE: It could require additional packages installed: libglfw3-dev
+ LDLIBS += -lglfw
endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
# Libraries for Raspberry Pi compiling
- # NOTE: Required packages: libopenal1
- LDLIBS = -lraylib -lGLESv2 -lEGL -lpthread -lrt -lm -lbcm_host -lopenal
+ # NOTE: Required packages: libasound2-dev (ALSA)
+ LDLIBS = -lraylib -lbrcmGLESv2 -lbrcmEGL -lpthread -lrt -lm -lbcm_host -ldl
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
# Libraries for web (HTML5) compiling
- LDLIBS = $(RAYLIB_RELEASE)/libraylib.bc
+ LDLIBS = $(RAYLIB_RELEASE_PATH)/libraylib.bc
endif
-# Define additional parameters and flags for windows
-ifeq ($(PLATFORM_OS),WINDOWS)
- # resources file contains raylib icon for windows .exe
- # -Wl,--subsystem,windows hides the console window
- CFLAGS += $(RAYLIB_PATH)/src/resources -Wl,--subsystem,windows
-endif
-
-# Define output extension to generate a .html file using provided shell
-ifeq ($(PLATFORM),PLATFORM_WEB)
- EXT = .html
- CFLAGS += --shell-file $(RAYLIB_PATH)\templates\web_shell\shell.html
-endif
-
-# define all object files required
+# Define all source files required
SAMPLES = \
arkanoid \
asteroids \
@@ -246,17 +279,11 @@ all: $(SAMPLES)
%: %.c
ifeq ($(PLATFORM),PLATFORM_ANDROID)
- mingw32-make -f Makefile.Android PROJECT_NAME=$@ PROJECT_SOURCE_FILES=$<
+ $(MAKE) -f Makefile.Android PROJECT_NAME=$@ PROJECT_SOURCE_FILES=$<
else
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
endif
-# fix dylib install path name for each executable (MAC)
-fix_dylib:
-ifeq ($(PLATFORM_OS),OSX)
- find . -type f -perm +ugo+x -print0 | xargs -t -0 -R 1 -I file install_name_tool -change libglfw.3.0.dylib ../external/glfw3/lib/osx/libglfw.3.0.dylib file
-endif
-
# Clean everything
clean:
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
@@ -279,3 +306,4 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
del *.o *.html *.js
endif
@echo Cleaning done
+
diff --git a/games/arkanoid.c b/games/arkanoid.c
index 1da80a1e4..2a4a2e536 100644
--- a/games/arkanoid.c
+++ b/games/arkanoid.c
@@ -18,10 +18,6 @@
#include
#include
-#if defined(PLATFORM_ANDROID)
- #include "android_native_app_glue.h"
-#endif
-
#if defined(PLATFORM_WEB)
#include
#endif
@@ -83,19 +79,11 @@ static void UpdateDrawFrame(void); // Update and Draw (one frame)
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
-#if defined(PLATFORM_ANDROID)
-void android_main(struct android_app *app)
-#else
int main(void)
-#endif
{
- // Initialization
+ // Initialization (Note windowTitle is unused on Android)
//---------------------------------------------------------
-#if defined(PLATFORM_ANDROID)
- InitWindow(screenWidth, screenHeight, app);
-#else
InitWindow(screenWidth, screenHeight, "sample game: arkanoid");
-#endif
InitGame();
@@ -122,9 +110,8 @@ int main(void)
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
-#if !defined(PLATFORM_ANDROID)
+
return 0;
-#endif
}
//------------------------------------------------------------------------------------
@@ -338,4 +325,4 @@ void UpdateDrawFrame(void)
{
UpdateGame();
DrawGame();
-}
\ No newline at end of file
+}
diff --git a/games/asteroids.c b/games/asteroids.c
index dc8a9e076..80096de66 100644
--- a/games/asteroids.c
+++ b/games/asteroids.c
@@ -15,10 +15,6 @@
#include
-#if defined(PLATFORM_ANDROID)
- #include "android_native_app_glue.h"
-#endif
-
#if defined(PLATFORM_WEB)
#include
#endif
@@ -101,19 +97,11 @@ static void UpdateDrawFrame(void); // Update and Draw (one frame)
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
-#if defined(PLATFORM_ANDROID)
-void android_main(struct android_app *app)
-#else
int main(void)
-#endif
{
- // Initialization
+ // Initialization (Note windowTitle is unused on Android)
//---------------------------------------------------------
-#if defined(PLATFORM_ANDROID)
- InitWindow(screenWidth, screenHeight, app);
-#else
InitWindow(screenWidth, screenHeight, "sample game: asteroids");
-#endif
InitGame();
@@ -140,9 +128,8 @@ int main(void)
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
-#if !defined(PLATFORM_ANDROID)
+
return 0;
-#endif
}
//------------------------------------------------------------------------------------
@@ -578,4 +565,4 @@ void UpdateDrawFrame(void)
{
UpdateGame();
DrawGame();
-}
\ No newline at end of file
+}
diff --git a/games/asteroids_survival.c b/games/asteroids_survival.c
index 12759606d..8086433e4 100644
--- a/games/asteroids_survival.c
+++ b/games/asteroids_survival.c
@@ -15,10 +15,6 @@
#include
-#if defined(PLATFORM_ANDROID)
- #include "android_native_app_glue.h"
-#endif
-
#if defined(PLATFORM_WEB)
#include
#endif
@@ -84,19 +80,11 @@ static void UpdateDrawFrame(void); // Update and Draw (one frame)
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
-#if defined(PLATFORM_ANDROID)
-void android_main(struct android_app *app)
-#else
int main(void)
-#endif
{
- // Initialization
+ // Initialization (Note windowTitle is unused on Android)
//---------------------------------------------------------
-#if defined(PLATFORM_ANDROID)
- InitWindow(screenWidth, screenHeight, app);
-#else
InitWindow(screenWidth, screenHeight, "sample game: asteroids survival");
-#endif
InitGame();
@@ -123,9 +111,8 @@ int main(void)
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
-#if !defined(PLATFORM_ANDROID)
+
return 0;
-#endif
}
//------------------------------------------------------------------------------------
@@ -388,4 +375,4 @@ void UpdateDrawFrame(void)
{
UpdateGame();
DrawGame();
-}
\ No newline at end of file
+}
diff --git a/games/drturtle/Makefile b/games/drturtle/Makefile
index 898219290..9a2486fea 100644
--- a/games/drturtle/Makefile
+++ b/games/drturtle/Makefile
@@ -1,8 +1,8 @@
#**************************************************************************************************
#
-# raylib makefile for desktop platforms, Raspberry Pi and HTML5 (emscripten)
+# raylib makefile for Desktop platforms, Raspberry Pi, Android and HTML5
#
-# Copyright (c) 2013-2017 Ramon Santamaria (@raysan5)
+# Copyright (c) 2013-2018 Ramon Santamaria (@raysan5)
#
# This software is provided "as-is", without any express or implied warranty. In no event
# will the authors be held liable for any damages arising from the use of this software.
@@ -23,223 +23,268 @@
.PHONY: all clean
-# define raylib platform to compile for
-# possible platforms: PLATFORM_DESKTOP PLATFORM_RPI PLATFORM_WEB
+# Define required raylib variables
# WARNING: To compile to HTML5, code must be redesigned to use emscripten.h and emscripten_set_main_loop()
PLATFORM ?= PLATFORM_DESKTOP
+RAYLIB_PATH ?= ..\..
+PROJECT_NAME ?= drturtle
-# define NO to use OpenAL Soft as static library (shared by default)
-SHARED_OPENAL ?= NO
-
-ifeq ($(PLATFORM),PLATFORM_WEB)
- SHARED_OPENAL = NO
+# Default path for raylib on Raspberry Pi, if installed in different path, update it!
+ifeq ($(PLATFORM),PLATFORM_RPI)
+ RAYLIB_PATH ?= /home/pi/raylib
endif
-# define raylib directory for include and library
-RAYLIB_PATH ?= C:\raylib\raylib
+# Library type used for raylib: STATIC (.a) or SHARED (.so/.dll)
+RAYLIB_LIBTYPE ?= STATIC
-# determine PLATFORM_OS in case PLATFORM_DESKTOP selected
+# Use external GLFW library instead of rglfw module
+USE_EXTERNAL_GLFW ?= FALSE
+
+# Use Wayland display server protocol on Linux desktop
+# by default it uses X11 windowing system
+USE_WAYLAND_DISPLAY ?= FALSE
+
+# NOTE: On PLATFORM_WEB OpenAL Soft backend is used by default (check raylib/src/Makefile)
+
+
+# Determine PLATFORM_OS in case PLATFORM_DESKTOP selected
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
- # No uname.exe on MinGW!, but OS=Windows_NT on Windows! ifeq ($(UNAME),Msys) -> Windows
+ # No uname.exe on MinGW!, but OS=Windows_NT on Windows!
+ # ifeq ($(UNAME),Msys) -> Windows
ifeq ($(OS),Windows_NT)
PLATFORM_OS=WINDOWS
- LIBPATH=win32
else
- UNAMEOS:=$(shell uname)
+ UNAMEOS=$(shell uname)
ifeq ($(UNAMEOS),Linux)
PLATFORM_OS=LINUX
- LIBPATH=linux
- else
+ endif
+ ifeq ($(UNAMEOS),FreeBSD)
+ PLATFORM_OS=FREEBSD
+ endif
ifeq ($(UNAMEOS),Darwin)
PLATFORM_OS=OSX
- LIBPATH=osx
- endif
endif
endif
endif
+ifeq ($(PLATFORM),PLATFORM_RPI)
+ UNAMEOS=$(shell uname)
+ ifeq ($(UNAMEOS),Linux)
+ PLATFORM_OS=LINUX
+ endif
+endif
-# define compiler: gcc for C program, define as g++ for C++
ifeq ($(PLATFORM),PLATFORM_WEB)
- # define emscripten compiler
- CC = emcc
-else
-ifeq ($(PLATFORM_OS),OSX)
- # define llvm compiler for mac
- CC = clang
-else
- # define default gcc compiler
- CC = gcc
-endif
+ # Emscripten required variables
+ EMSDK_PATH = C:/emsdk
+ EMSCRIPTEN_VERSION = 1.37.28
+ CLANG_VERSION=e1.37.28_64bit
+ PYTHON_VERSION=2.7.5.3_64bit
+ NODE_VERSION=4.1.1_64bit
+ export PATH=$(EMSDK_PATH);$(EMSDK_PATH)\clang\$(CLANG_VERSION);$(EMSDK_PATH)\node\$(NODE_VERSION)\bin;$(EMSDK_PATH)\python\$(PYTHON_VERSION);$(EMSDK_PATH)\emscripten\$(EMSCRIPTEN_VERSION);C:\raylib\MinGW\bin:$$(PATH)
+ EMSCRIPTEN=$(EMSDK_PATH)\emscripten\$(EMSCRIPTEN_VERSION)
endif
-# define compiler flags:
-# -O2 defines optimization level
-# -Og enable debugging
+RAYLIB_RELEASE_PATH ?= $(RAYLIB_PATH)/release/libs
+
+# Define raylib release directory for compiled library
+ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ ifeq ($(PLATFORM_OS),WINDOWS)
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/win32/mingw32
+ endif
+ ifeq ($(PLATFORM_OS),LINUX)
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/linux
+ endif
+ ifeq ($(PLATFORM_OS),OSX)
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/osx
+ endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/freebsd
+ endif
+endif
+ifeq ($(PLATFORM),PLATFORM_RPI)
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/rpi
+endif
+ifeq ($(PLATFORM),PLATFORM_WEB)
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/html5
+endif
+
+# Define default C compiler: gcc
+# NOTE: define g++ compiler if using C++
+CC = gcc
+
+ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ ifeq ($(PLATFORM_OS),OSX)
+ # OSX default compiler
+ CC = clang
+ endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ # FreeBSD default compiler
+ CC = clang
+ endif
+endif
+ifeq ($(PLATFORM),PLATFORM_RPI)
+ ifeq ($(USE_RPI_CROSS_COMPILER),TRUE)
+ # Define RPI cross-compiler
+ #CC = armv6j-hardfloat-linux-gnueabi-gcc
+ CC = $(RPI_TOOLCHAIN)/bin/arm-linux-gnueabihf-gcc
+ endif
+endif
+ifeq ($(PLATFORM),PLATFORM_WEB)
+ # HTML5 emscripten compiler
+ CC = emcc
+endif
+
+# Define default make program: Mingw32-make
+MAKE = mingw32-make
+
+ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ ifeq ($(PLATFORM_OS),LINUX)
+ MAKE = make
+ endif
+endif
+
+# Define compiler flags:
+# -O1 defines optimization level
+# -g enable debugging
# -s strip unnecessary data from build
# -Wall turns on most, but not all, compiler warnings
# -std=c99 defines C language mode (standard C from 1999 revision)
# -std=gnu99 defines C language mode (GNU C from 1999 revision)
-# -fgnu89-inline declaring inline functions support (GCC optimized)
# -Wno-missing-braces ignore invalid warning (GCC bug 53119)
# -D_DEFAULT_SOURCE use with -std=c99 on Linux and PLATFORM_WEB, required for timespec
+CFLAGS += -O1 -s -Wall -std=c99 -D_DEFAULT_SOURCE -Wno-missing-braces
+
+# Additional flags for compiler (if desired)
+#CFLAGS += -Wextra -Wmissing-prototypes -Wstrict-prototypes
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),WINDOWS)
- CFLAGS = -O2 -s -Wall -std=c99
+ # resources file contains windows exe icon
+ # -Wl,--subsystem,windows hides the console window
+ CFLAGS += $(RAYLIB_PATH)/src/resources -Wl,--subsystem,windows
endif
ifeq ($(PLATFORM_OS),LINUX)
- CFLAGS = -O2 -s -Wall -std=c99 -D_DEFAULT_SOURCE
- endif
- ifeq ($(PLATFORM_OS),OSX)
- CFLAGS = -O2 -s -Wall -std=c99
+ CFLAGS += -no-pie -D_DEFAULT_SOURCE
endif
endif
+ifeq ($(PLATFORM),PLATFORM_RPI)
+ CFLAGS += -std=gnu99
+endif
ifeq ($(PLATFORM),PLATFORM_WEB)
- CFLAGS = -O1 -Wall -std=c99 -D_DEFAULT_SOURCE -s USE_GLFW=3 -s ASSERTIONS=1 -s TOTAL_MEMORY=33554432 --profiling --preload-file resources
- # -O2 # if used, also set --memory-init-file 0
- # --memory-init-file 0 # to avoid an external memory initialization code file (.mem)
- # -s ALLOW_MEMORY_GROWTH=1 # to allow memory resizing
- # -s TOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB)
- # --preload-file file.res # embbed file.res resource into .data file
+ # -O2 # if used, also set --memory-init-file 0
+ # --memory-init-file 0 # to avoid an external memory initialization code file (.mem)
+ # -s ALLOW_MEMORY_GROWTH=1 # to allow memory resizing
+ # -s TOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB)
+ # -s USE_PTHREADS=1 # multithreading support
+ # -s WASM=1 # support Web Assembly (https://github.com/kripken/emscripten/wiki/WebAssembly)
+ # --preload-file resources # specify a resources folder for data compilation
+ CFLAGS += -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 --profiling --preload-file resources
+
+ # Define a custom shell .html and output extension
+ CFLAGS += --shell-file $(RAYLIB_PATH)\templates\web_shell\shell.html
+ EXT = .html
endif
-ifeq ($(PLATFORM),PLATFORM_RPI)
- CFLAGS = -O2 -s -Wall -std=gnu99 -fgnu89-inline
-endif
-#CFLAGSEXTRA = -Wextra -Wmissing-prototypes -Wstrict-prototypes
-# define raylib release directory for compiled library
+# Define include paths for required headers
+# NOTE: Several external required libraries (stb and others)
+INCLUDE_PATHS = -I. -I$(RAYLIB_PATH)/release/include -I$(RAYLIB_PATH)/src -I$(RAYLIB_PATH)/src/external
+
+# Define additional directories containing required header files
+ifeq ($(PLATFORM),PLATFORM_RPI)
+ # RPI requried libraries
+ INCLUDE_PATHS += -I/opt/vc/include
+ INCLUDE_PATHS += -I/opt/vc/include/interface/vmcs_host/linux
+ INCLUDE_PATHS += -I/opt/vc/include/interface/vcos/pthreads
+endif
+
+# Define library paths containing required libs
+LDFLAGS = -L. -L$(RAYLIB_RELEASE_PATH) -L$(RAYLIB_PATH)/src
+
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
- ifeq ($(PLATFORM_OS),WINDOWS)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/win32/mingw32
- endif
- ifeq ($(PLATFORM_OS),LINUX)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/linux
- endif
- ifeq ($(PLATFORM_OS),OSX)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/osx
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ INCLUDE_PATHS += -I/usr/local/include
+ LDFLAGS += -L. -Lsrc -L/usr/local/lib
endif
endif
-ifeq ($(PLATFORM),PLATFORM_WEB)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/html5
-endif
-ifeq ($(PLATFORM),PLATFORM_RPI)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/rpi
-endif
-
-# define any directories containing required header files
-INCLUDES = -I. -I$(RAYLIB_RELEASE) -I$(RAYLIB_PATH)/src -I$(RAYLIB_PATH)/src/external
ifeq ($(PLATFORM),PLATFORM_RPI)
- INCLUDES += -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads
-endif
-ifeq ($(PLATFORM),PLATFORM_DESKTOP)
- ifeq ($(PLATFORM_OS),WINDOWS)
- # external libraries headers
- # GLFW3
- INCLUDES += -I$(RAYLIB_PATH)/src/external/glfw3/include
- # OpenAL Soft
- INCLUDES += -I$(RAYLIB_PATH)/src/external/openal_soft/include
- endif
- ifeq ($(PLATFORM_OS),LINUX)
- # you may optionally create this directory and install raylib
- # and related headers there. Edit ../src/Makefile appropriately.
- INCLUDES += -I/usr/local/include/raylib
- endif
- ifeq ($(PLATFORM_OS),OSX)
- # additional directories for MacOS
- endif
+ LDFLAGS += -L/opt/vc/lib
endif
-# define library paths containing required libs
-LFLAGS = -L. -L$(RAYLIB_RELEASE) -L$(RAYLIB_PATH)/src
-
-ifeq ($(PLATFORM),PLATFORM_RPI)
- LFLAGS += -L/opt/vc/lib
-endif
-ifeq ($(PLATFORM),PLATFORM_DESKTOP)
- # add standard directories for GNU/Linux
- ifeq ($(PLATFORM_OS),WINDOWS)
- # external libraries to link with
- # GLFW3
- LFLAGS += -L$(RAYLIB_PATH)/src/external/glfw3/lib/$(LIBPATH)
- # OpenAL Soft
- LFLAGS += -L$(RAYLIB_PATH)/src/external/openal_soft/lib/$(LIBPATH)
- endif
-endif
-
-# define any libraries to link into executable
+# Define any libraries required on linking
# if you want to link libraries (libname.so or libname.a), use the -lname
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ ifeq ($(PLATFORM_OS),WINDOWS)
+ # Libraries for Windows desktop compilation
+ LDLIBS = -lraylib -lopengl32 -lgdi32
+ endif
ifeq ($(PLATFORM_OS),LINUX)
- # libraries for Debian GNU/Linux desktop compiling
- # requires the following packages:
- # libglfw3-dev libopenal-dev libegl1-mesa-dev
- LIBS = -lraylib -lglfw3 -lGL -lopenal -lm -lpthread -ldl
- # on XWindow requires also below libraries
- LIBS += -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
- else
- ifeq ($(PLATFORM_OS),OSX)
- # libraries for OSX 10.9 desktop compiling
- # requires the following packages:
- # libglfw3-dev libopenal-dev libegl1-mesa-dev
- LIBS = -lraylib -lglfw -framework OpenGL -framework OpenAL -framework Cocoa
- else
- # libraries for Windows desktop compiling
- # NOTE: GLFW3 and OpenAL Soft libraries should be installed
- LIBS = -lraylib -lglfw3 -lopengl32 -lgdi32
- # if static OpenAL Soft required, define the corresponding libs
- ifeq ($(SHARED_OPENAL),NO)
- LIBS += -lopenal32 -lwinmm
- CFLAGS += -Wl,-allow-multiple-definition
- else
- LIBS += -lopenal32dll
+ # Libraries for Debian GNU/Linux desktop compiling
+ # NOTE: Required packages: libegl1-mesa-dev
+ LDLIBS = -lraylib -lGL -lm -lpthread -ldl -lrt
+
+ # On X11 requires also below libraries
+ LDLIBS += -lX11
+ # NOTE: It seems additional libraries are not required any more, latest GLFW just dlopen them
+ #LDLIBS += -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
+
+ # On Wayland windowing system, additional libraries requires
+ ifeq ($(USE_WAYLAND_DISPLAY),TRUE)
+ LDLIBS += -lwayland-client -lwayland-cursor -lwayland-egl -lxkbcommon
endif
endif
+ ifeq ($(PLATFORM_OS),OSX)
+ # Libraries for OSX 10.9 desktop compiling
+ # NOTE: Required packages: libopenal-dev libegl1-mesa-dev
+ LDLIBS = -lraylib -framework OpenGL -framework OpenAL -framework Cocoa
+ endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ # Libraries for FreeBSD desktop compiling
+ # NOTE: Required packages: mesa-libs
+ LDLIBS = -lraylib -lGL -lpthread -lm
+
+ # On XWindow requires also below libraries
+ LDLIBS += -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
+ endif
+ ifeq ($(USE_EXTERNAL_GLFW),TRUE)
+ # NOTE: It could require additional packages installed: libglfw3-dev
+ LDLIBS += -lglfw
endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
- # libraries for Raspberry Pi compiling
- # NOTE: OpenAL Soft library should be installed (libopenal1 package)
- LIBS = -lraylib -lGLESv2 -lEGL -lpthread -lrt -lm -lbcm_host -lopenal
+ # Libraries for Raspberry Pi compiling
+ # NOTE: Required packages: libasound2-dev (ALSA)
+ LDLIBS = -lraylib -lbrcmGLESv2 -lbrcmEGL -lpthread -lrt -lm -lbcm_host -ldl
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
- # NOTE: Set the correct path to libraylib.bc
- LIBS = $(RAYLIB_RELEASE)/libraylib.bc
+ # Libraries for web (HTML5) compiling
+ LDLIBS = $(RAYLIB_RELEASE_PATH)/libraylib.bc
endif
-# define additional parameters and flags for windows
-ifeq ($(PLATFORM_OS),WINDOWS)
- # resources file contains windows exe icon
- # -Wl,--subsystem,windows hides the console window
- WINFLAGS = $(RAYLIB_PATH)/src/resources -Wl,--subsystem,windows
-endif
-
-ifeq ($(PLATFORM),PLATFORM_WEB)
- EXT = .html
- WEB_SHELL = --shell-file $(RAYLIB_PATH)\templates\web_shell\shell.html
-endif
-
-# define all screen object files required
-SCREENS = \
+# Define all source files required
+SCREENS = drturtle_final_web \
# typing 'make' will invoke the default target entry
-default: drturtle
+all: $(SCREENS)
-# compile program
-drturtle: drturtle_final_web.c $(SCREENS)
- $(CC) -o $@$(EXT) $^ $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) $(WEB_SHELL)
+%: %.c
+ifeq ($(PLATFORM),PLATFORM_ANDROID)
+ $(MAKE) -f Makefile.Android PROJECT_NAME=$@ PROJECT_SOURCE_FILES=$<
+else
+ $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+endif
-# clean everything
+# Clean everything
clean:
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ ifeq ($(PLATFORM_OS),WINDOWS)
+ del *.o *.exe /s
+ endif
+ ifeq ($(PLATFORM_OS),LINUX)
+ find -type f -executable | xargs file -i | grep -E 'x-object|x-archive|x-sharedlib|x-executable' | rev | cut -d ':' -f 2- | rev | xargs rm -f
+ endif
ifeq ($(PLATFORM_OS),OSX)
find . -type f -perm +ugo+x -delete
rm -f *.o
- else
- ifeq ($(PLATFORM_OS),LINUX)
- find -type f -executable | xargs file -i | grep -E 'x-object|x-archive|x-sharedlib|x-executable' | rev | cut -d ':' -f 2- | rev | xargs rm -f
- else
- del *.o *.exe /s
- endif
endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
@@ -251,7 +296,3 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
endif
@echo Cleaning done
-# instead of defining every module one by one, we can define a pattern
-# this pattern below will automatically compile every module defined on $(OBJS)
-#%.exe : %.c
-# $(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM)
diff --git a/games/floppy.c b/games/floppy.c
index d7c4f1294..2ca91a141 100644
--- a/games/floppy.c
+++ b/games/floppy.c
@@ -13,10 +13,6 @@
#include "raylib.h"
-#if defined(PLATFORM_ANDROID)
- #include "android_native_app_glue.h"
-#endif
-
#if defined(PLATFORM_WEB)
#include
#endif
@@ -72,19 +68,11 @@ static void UpdateDrawFrame(void); // Update and Draw (one frame)
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
-#if defined(PLATFORM_ANDROID)
-void android_main(struct android_app *app)
-#else
int main(void)
-#endif
{
// Initialization
//---------------------------------------------------------
-#if defined(PLATFORM_ANDROID)
- InitWindow(screenWidth, screenHeight, app);
-#else
InitWindow(screenWidth, screenHeight, "sample game: floppy");
-#endif
InitGame();
@@ -111,9 +99,8 @@ int main(void)
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
-#if !defined(PLATFORM_ANDROID)
+
return 0;
-#endif
}
//------------------------------------------------------------------------------------
// Module Functions Definitions (local)
@@ -250,4 +237,4 @@ void UpdateDrawFrame(void)
{
UpdateGame();
DrawGame();
-}
\ No newline at end of file
+}
diff --git a/games/gold_fever.c b/games/gold_fever.c
index 1d8b6b7c3..c5f36efa5 100644
--- a/games/gold_fever.c
+++ b/games/gold_fever.c
@@ -13,10 +13,6 @@
#include "raylib.h"
-#if defined(PLATFORM_ANDROID)
- #include "android_native_app_glue.h"
-#endif
-
#if defined(PLATFORM_WEB)
#include
#endif
@@ -81,19 +77,11 @@ static void UpdateDrawFrame(void); // Update and Draw (one frame)
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
-#if defined(PLATFORM_ANDROID)
-void android_main(struct android_app *app)
-#else
int main(void)
-#endif
{
- // Initialization
+ // Initialization (Note windowTitle is unused on Android)
//---------------------------------------------------------
-#if defined(PLATFORM_ANDROID)
- InitWindow(screenWidth, screenHeight, app);
-#else
InitWindow(screenWidth, screenHeight, "sample game: gold fever");
-#endif
InitGame();
@@ -120,9 +108,8 @@ int main(void)
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
-#if !defined(PLATFORM_ANDROID)
+
return 0;
-#endif
}
//------------------------------------------------------------------------------------
@@ -291,4 +278,4 @@ void UpdateDrawFrame(void)
{
UpdateGame();
DrawGame();
-}
\ No newline at end of file
+}
diff --git a/games/gorilas.c b/games/gorilas.c
index 75decd96a..9ef71b552 100644
--- a/games/gorilas.c
+++ b/games/gorilas.c
@@ -18,10 +18,6 @@
#include
#include
-#if defined(PLATFORM_ANDROID)
- #include "android_native_app_glue.h"
-#endif
-
#if defined(PLATFORM_WEB)
#include
#endif
@@ -120,19 +116,11 @@ static bool UpdateBall(int playerTurn);
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
-#if defined(PLATFORM_ANDROID)
-void android_main(struct android_app *app)
-#else
int main(void)
-#endif
{
- // Initialization
+ // Initialization (Note windowTitle is unused on Android)
//---------------------------------------------------------
-#if defined(PLATFORM_ANDROID)
- InitWindow(screenWidth, screenHeight, app);
-#else
InitWindow(screenWidth, screenHeight, "sample game: gorilas");
-#endif
InitGame();
@@ -159,9 +147,8 @@ int main(void)
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
-#if !defined(PLATFORM_ANDROID)
+
return 0;
-#endif
}
//------------------------------------------------------------------------------------
@@ -576,4 +563,4 @@ static bool UpdateBall(int playerTurn)
}
return false;
-}
\ No newline at end of file
+}
diff --git a/games/just_do/Makefile b/games/just_do/Makefile
index 3d41ff973..3f764abc7 100644
--- a/games/just_do/Makefile
+++ b/games/just_do/Makefile
@@ -2,7 +2,7 @@
#
# raylib makefile for Desktop platforms, Raspberry Pi, Android and HTML5
#
-# Copyright (c) 2013-2017 Ramon Santamaria (@raysan5)
+# Copyright (c) 2013-2018 Ramon Santamaria (@raysan5)
#
# This software is provided "as-is", without any express or implied warranty. In no event
# will the authors be held liable for any damages arising from the use of this software.
@@ -29,72 +29,87 @@ PLATFORM ?= PLATFORM_DESKTOP
RAYLIB_PATH ?= ..\..
PROJECT_NAME ?= just_do
-# Library type used for raylib and OpenAL Soft: STATIC (.a) or SHARED (.so/.dll)
-# NOTE: Libraries should be provided in the selected form
-RAYLIB_LIBTYPE ?= STATIC
-OPENAL_LIBTYPE ?= STATIC
-
-# On PLATFORM_WEB force OpenAL Soft shared library
-ifeq ($(PLATFORM),PLATFORM_WEB)
- OPENAL_LIBTYPE = SHARED
+# Default path for raylib on Raspberry Pi, if installed in different path, update it!
+ifeq ($(PLATFORM),PLATFORM_RPI)
+ RAYLIB_PATH ?= /home/pi/raylib
endif
+# Library type used for raylib: STATIC (.a) or SHARED (.so/.dll)
+RAYLIB_LIBTYPE ?= STATIC
+
+# Use external GLFW library instead of rglfw module
+USE_EXTERNAL_GLFW ?= FALSE
+
+# Use Wayland display server protocol on Linux desktop
+# by default it uses X11 windowing system
+USE_WAYLAND_DISPLAY ?= FALSE
+
+# NOTE: On PLATFORM_WEB OpenAL Soft backend is used by default (check raylib/src/Makefile)
+
+
# Determine PLATFORM_OS in case PLATFORM_DESKTOP selected
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
- # No uname.exe on MinGW!, but OS=Windows_NT on Windows! ifeq ($(UNAME),Msys) -> Windows
+ # No uname.exe on MinGW!, but OS=Windows_NT on Windows!
+ # ifeq ($(UNAME),Msys) -> Windows
ifeq ($(OS),Windows_NT)
PLATFORM_OS=WINDOWS
- LIBPATH=win32
else
UNAMEOS=$(shell uname)
ifeq ($(UNAMEOS),Linux)
PLATFORM_OS=LINUX
- LIBPATH=linux
- else
+ endif
+ ifeq ($(UNAMEOS),FreeBSD)
+ PLATFORM_OS=FREEBSD
+ endif
ifeq ($(UNAMEOS),Darwin)
PLATFORM_OS=OSX
- LIBPATH=osx
- endif
endif
endif
endif
-
ifeq ($(PLATFORM),PLATFORM_RPI)
- # RPI cross-compiler
- RPI_CROSS_COMPILE ?= NO
+ UNAMEOS=$(shell uname)
+ ifeq ($(UNAMEOS),Linux)
+ PLATFORM_OS=LINUX
+ endif
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
# Emscripten required variables
EMSDK_PATH = C:/emsdk
- EMSCRIPTEN_VERSION = 1.37.21
- CLANG_VERSION=e1.37.21_64bit
+ EMSCRIPTEN_VERSION = 1.37.28
+ CLANG_VERSION=e1.37.28_64bit
PYTHON_VERSION=2.7.5.3_64bit
NODE_VERSION=4.1.1_64bit
export PATH=$(EMSDK_PATH);$(EMSDK_PATH)\clang\$(CLANG_VERSION);$(EMSDK_PATH)\node\$(NODE_VERSION)\bin;$(EMSDK_PATH)\python\$(PYTHON_VERSION);$(EMSDK_PATH)\emscripten\$(EMSCRIPTEN_VERSION);C:\raylib\MinGW\bin:$$(PATH)
EMSCRIPTEN=$(EMSDK_PATH)\emscripten\$(EMSCRIPTEN_VERSION)
endif
+RAYLIB_RELEASE_PATH ?= $(RAYLIB_PATH)/release/libs
+
# Define raylib release directory for compiled library
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),WINDOWS)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/win32/mingw32
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/win32/mingw32
endif
ifeq ($(PLATFORM_OS),LINUX)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/linux
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/linux
endif
ifeq ($(PLATFORM_OS),OSX)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/osx
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/osx
+ endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/freebsd
endif
endif
-ifeq ($(PLATFORM),PLATFORM_WEB)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/html5
-endif
ifeq ($(PLATFORM),PLATFORM_RPI)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/rpi
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/rpi
+endif
+ifeq ($(PLATFORM),PLATFORM_WEB)
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/html5
endif
# Define default C compiler: gcc
+# NOTE: define g++ compiler if using C++
CC = gcc
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
@@ -102,11 +117,16 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
# OSX default compiler
CC = clang
endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ # FreeBSD default compiler
+ CC = clang
+ endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
- ifeq ($(RPI_CROSS_COMPILE),YES)
- # RPI cross-compiler
- CC = armv6j-hardfloat-linux-gnueabi-gcc
+ ifeq ($(USE_RPI_CROSS_COMPILER),TRUE)
+ # Define RPI cross-compiler
+ #CC = armv6j-hardfloat-linux-gnueabi-gcc
+ CC = $(RPI_TOOLCHAIN)/bin/arm-linux-gnueabihf-gcc
endif
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
@@ -125,19 +145,23 @@ endif
# Define compiler flags:
# -O1 defines optimization level
-# -Og enable debugging
+# -g enable debugging
# -s strip unnecessary data from build
# -Wall turns on most, but not all, compiler warnings
# -std=c99 defines C language mode (standard C from 1999 revision)
# -std=gnu99 defines C language mode (GNU C from 1999 revision)
-# -fgnu89-inline declaring inline functions support (GCC optimized)
# -Wno-missing-braces ignore invalid warning (GCC bug 53119)
# -D_DEFAULT_SOURCE use with -std=c99 on Linux and PLATFORM_WEB, required for timespec
-CFLAGS += -O1 -s -Wall -std=c99 -D_DEFAULT_SOURCE -fgnu89-inline -Wno-missing-braces
+CFLAGS += -O1 -s -Wall -std=c99 -D_DEFAULT_SOURCE -Wno-missing-braces
# Additional flags for compiler (if desired)
#CFLAGS += -Wextra -Wmissing-prototypes -Wstrict-prototypes
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ ifeq ($(PLATFORM_OS),WINDOWS)
+ # resources file contains windows exe icon
+ # -Wl,--subsystem,windows hides the console window
+ CFLAGS += $(RAYLIB_PATH)/src/resources -Wl,--subsystem,windows
+ endif
ifeq ($(PLATFORM_OS),LINUX)
CFLAGS += -no-pie -D_DEFAULT_SOURCE
endif
@@ -151,7 +175,13 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
# -s ALLOW_MEMORY_GROWTH=1 # to allow memory resizing
# -s TOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB)
# -s USE_PTHREADS=1 # multithreading support
- CFLAGS += -s USE_GLFW=3 -s ASSERTIONS=1 --profiling -s TOTAL_MEMORY=16777216 --preload-file resources
+ # -s WASM=1 # support Web Assembly (https://github.com/kripken/emscripten/wiki/WebAssembly)
+ # --preload-file resources # specify a resources folder for data compilation
+ CFLAGS += -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 --profiling --preload-file resources
+
+ # Define a custom shell .html and output extension
+ CFLAGS += --shell-file $(RAYLIB_PATH)\templates\web_shell\shell.html
+ EXT = .html
endif
# Define include paths for required headers
@@ -167,7 +197,14 @@ ifeq ($(PLATFORM),PLATFORM_RPI)
endif
# Define library paths containing required libs
-LDFLAGS = -L. -L$(RAYLIB_RELEASE) -L$(RAYLIB_PATH)/src
+LDFLAGS = -L. -L$(RAYLIB_RELEASE_PATH) -L$(RAYLIB_PATH)/src
+
+ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ INCLUDE_PATHS += -I/usr/local/include
+ LDFLAGS += -L. -Lsrc -L/usr/local/lib
+ endif
+endif
ifeq ($(PLATFORM),PLATFORM_RPI)
LDFLAGS += -L/opt/vc/lib
@@ -177,54 +214,50 @@ endif
# if you want to link libraries (libname.so or libname.a), use the -lname
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),WINDOWS)
- # Libraries for Windows desktop compiling
- # NOTE: GLFW3 and OpenAL Soft libraries should be installed
- LDLIBS = -lraylib -lglfw3 -lopengl32 -lgdi32
-
- # Define required flags and libs for OpenAL Soft STATIC/SHARED usage
- # NOTE: ALLIBS flag only required for raylib Win32 SHARED library building
- ifeq ($(OPENAL_LIBTYPE),STATIC)
- LDLIBS += -lopenal32 -lwinmm
- CFLAGS += -DAL_LIBTYPE_STATIC -Wl,-allow-multiple-definition
- else
- LDLIBS += -lopenal32dll
- endif
+ # Libraries for Windows desktop compilation
+ LDLIBS = -lraylib -lopengl32 -lgdi32
endif
ifeq ($(PLATFORM_OS),LINUX)
# Libraries for Debian GNU/Linux desktop compiling
- # NOTE: Required packages: libglfw3-dev libopenal-dev libegl1-mesa-dev
- LDLIBS = -lraylib -lglfw3 -lGL -lopenal -lm -lpthread -ldl
+ # NOTE: Required packages: libegl1-mesa-dev
+ LDLIBS = -lraylib -lGL -lm -lpthread -ldl -lrt
- # On XWindow requires also below libraries
- LDLIBS += -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
+ # On X11 requires also below libraries
+ LDLIBS += -lX11
+ # NOTE: It seems additional libraries are not required any more, latest GLFW just dlopen them
+ #LDLIBS += -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
+
+ # On Wayland windowing system, additional libraries requires
+ ifeq ($(USE_WAYLAND_DISPLAY),TRUE)
+ LDLIBS += -lwayland-client -lwayland-cursor -lwayland-egl -lxkbcommon
+ endif
endif
ifeq ($(PLATFORM_OS),OSX)
# Libraries for OSX 10.9 desktop compiling
- # NOTE: Required packages: libglfw3-dev libopenal-dev libegl1-mesa-dev
- LDLIBS = -lraylib -lglfw -framework OpenGL -framework OpenAL -framework Cocoa
+ # NOTE: Required packages: libopenal-dev libegl1-mesa-dev
+ LDLIBS = -lraylib -framework OpenGL -framework OpenAL -framework Cocoa
+ endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ # Libraries for FreeBSD desktop compiling
+ # NOTE: Required packages: mesa-libs
+ LDLIBS = -lraylib -lGL -lpthread -lm
+
+ # On XWindow requires also below libraries
+ LDLIBS += -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
+ endif
+ ifeq ($(USE_EXTERNAL_GLFW),TRUE)
+ # NOTE: It could require additional packages installed: libglfw3-dev
+ LDLIBS += -lglfw
endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
# Libraries for Raspberry Pi compiling
- # NOTE: Required packages: libopenal1
- LDLIBS = -lraylib -lGLESv2 -lEGL -lpthread -lrt -lm -lbcm_host -lopenal
+ # NOTE: Required packages: libasound2-dev (ALSA)
+ LDLIBS = -lraylib -lbrcmGLESv2 -lbrcmEGL -lpthread -lrt -lm -lbcm_host -ldl
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
# Libraries for web (HTML5) compiling
- LDLIBS = $(RAYLIB_RELEASE)/libraylib.bc
-endif
-
-# Define additional parameters and flags for windows
-ifeq ($(PLATFORM_OS),WINDOWS)
- # resources file contains raylib icon for windows .exe
- # -Wl,--subsystem,windows hides the console window
- CFLAGS += $(RAYLIB_PATH)/src/resources -Wl,--subsystem,windows
-endif
-
-# Define output extension to generate a .html file using provided shell
-ifeq ($(PLATFORM),PLATFORM_WEB)
- EXT = .html
- WEB_SHELL = --shell-file $(RAYLIB_PATH)\templates\web_shell\shell.html
+ LDLIBS = $(RAYLIB_RELEASE_PATH)/libraylib.bc
endif
# Define all source files required
diff --git a/games/just_do/Makefile.Android b/games/just_do/Makefile.Android
index 1c8684544..f082ab230 100644
--- a/games/just_do/Makefile.Android
+++ b/games/just_do/Makefile.Android
@@ -53,26 +53,21 @@ APP_COMPANY_NAME ?= raylib
APP_PRODUCT_NAME ?= rgame
APP_VERSION_CODE ?= 1
APP_VERSION_NAME ?= 1.0
-APP_ICON_LDPI ?= $(RAYLIB_PATH)\logo\logo36x36.png
-APP_ICON_MDPI ?= $(RAYLIB_PATH)\logo\logo48x48.png
-APP_ICON_HDPI ?= $(RAYLIB_PATH)\logo\logo72x72.png
+APP_ICON_LDPI ?= $(RAYLIB_PATH)\logo\raylib_36x36.png
+APP_ICON_MDPI ?= $(RAYLIB_PATH)\logo\raylib_48x48.png
+APP_ICON_HDPI ?= $(RAYLIB_PATH)\logo\raylib_72x72.png
APP_SCREEN_ORIENTATION ?= landscape
APP_KEYSTORE_PASS ?= raylib
-# Library type used for raylib and OpenAL Soft: STATIC (.a) or SHARED (.so/.dll)
+# Library type used for raylib: STATIC (.a) or SHARED (.so/.dll)
RAYLIB_LIBTYPE ?= STATIC
-OPENAL_LIBTYPE ?= STATIC
RAYLIB_LIB_PATH = $(RAYLIB_PATH)\release\libs\android\armeabi-v7a
-OPENAL_LIB_PATH = $(RAYLIB_PATH)\release\libs\android\armeabi-v7a
# Shared libs must be added to APK if required
# NOTE: Generated NativeLoader.java automatically load those libraries
ifeq ($(RAYLIB_LIBTYPE),SHARED)
PROJECT_SHARED_LIBS = lib/armeabi-v7a/libraylib.so
endif
-ifeq ($(OPENAL_LIBTYPE),SHARED)
- PROJECT_SHARED_LIBS += lib/armeabi-v7a/libopenal.so
-endif
# Compiler and archiver
# NOTE: GCC is being deprectated in Android NDK r16
@@ -101,7 +96,7 @@ LDFLAGS += -L. -L$(PROJECT_BUILD_PATH)/obj -L$(PROJECT_BUILD_PATH)/lib/armeabi-v
# Define any libraries to link into executable
# if you want to link libraries (libname.so or libname.a), use the -lname
-LDLIBS = -lraylib -lnative_app_glue -lopenal -llog -landroid -lEGL -lGLESv2 -lOpenSLES -latomic -lc -lm -ldl
+LDLIBS = -lraylib -lnative_app_glue -llog -landroid -lEGL -lGLESv2 -lOpenSLES -latomic -lc -lm -ldl
# Generate target objects list from PROJECT_SOURCE_FILES
OBJS = $(patsubst %.c, $(PROJECT_BUILD_PATH)/obj/%.o, $(PROJECT_SOURCE_FILES))
@@ -154,15 +149,9 @@ copy_project_required_libs:
ifeq ($(RAYLIB_LIBTYPE),SHARED)
copy /Y $(RAYLIB_LIB_PATH)\libraylib.so $(PROJECT_BUILD_PATH)\lib\armeabi-v7a\libraylib.so
endif
-ifeq ($(OPENAL_LIBTYPE),SHARED)
- copy /Y $(OPENAL_LIB_PATH)\libopenal.so $(PROJECT_BUILD_PATH)\lib\armeabi-v7a\libopenal.so
-endif
ifeq ($(RAYLIB_LIBTYPE),STATIC)
copy /Y $(RAYLIB_LIB_PATH)\libraylib.a $(PROJECT_BUILD_PATH)\lib\armeabi-v7a\libraylib.a
endif
-ifeq ($(OPENAL_LIBTYPE),STATIC)
- copy /Y $(OPENAL_LIB_PATH)\libopenal.a $(PROJECT_BUILD_PATH)\lib\armeabi-v7a\libopenal.a
-endif
# Copy project required resources: strings.xml, icon.png, assets
# NOTE: Required strings.xml is generated and game resources are copied to assets folder
@@ -182,9 +171,6 @@ generate_loader_script:
@echo. >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
@echo public class NativeLoader extends android.app.NativeActivity { >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
@echo static { >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
-ifeq ($(OPENAL_LIBTYPE),SHARED)
- @echo System.loadLibrary("openal"); >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
-endif
ifeq ($(RAYLIB_LIBTYPE),SHARED)
@echo System.loadLibrary("raylib"); >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
endif
diff --git a/games/just_do/just_do.c b/games/just_do/just_do.c
index a9fef18cb..c7c76af96 100644
--- a/games/just_do/just_do.c
+++ b/games/just_do/just_do.c
@@ -16,10 +16,6 @@
#include "raylib.h"
#include "screens/screens.h" // NOTE: Defines currentScreen
-#if defined(PLATFORM_ANDROID)
- #include "android_native_app_glue.h"
-#endif
-
#if defined(PLATFORM_WEB)
#include
#endif
@@ -53,19 +49,11 @@ void UpdateDrawFrame(void); // Update and Draw one frame
//----------------------------------------------------------------------------------
// Main entry point
//----------------------------------------------------------------------------------
-#if defined(PLATFORM_ANDROID)
-void android_main(struct android_app *app)
-#else
int main(void)
-#endif
{
- // Initialization
+ // Initialization (Note windowTitle is unused on Android)
//---------------------------------------------------------
-#if defined(PLATFORM_ANDROID)
- InitWindow(screenWidth, screenHeight, app);
-#else
InitWindow(screenWidth, screenHeight, "GGJ15 - JUST DO");
-#endif
// Load global data here (assets that must be available in all screens, i.e. fonts)
InitAudioDevice();
@@ -104,9 +92,8 @@ int main(void)
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
-#if !defined(PLATFORM_ANDROID)
+
return 0;
-#endif
}
//----------------------------------------------------------------------------------
@@ -370,4 +357,4 @@ void UpdateDrawFrame(void)
EndDrawing();
//----------------------------------------------------------------------------------
-}
\ No newline at end of file
+}
diff --git a/games/koala_seasons/Makefile b/games/koala_seasons/Makefile
index 90676e356..3f1e4561b 100644
--- a/games/koala_seasons/Makefile
+++ b/games/koala_seasons/Makefile
@@ -2,7 +2,7 @@
#
# raylib makefile for Desktop platforms, Raspberry Pi, Android and HTML5
#
-# Copyright (c) 2013-2017 Ramon Santamaria (@raysan5)
+# Copyright (c) 2013-2018 Ramon Santamaria (@raysan5)
#
# This software is provided "as-is", without any express or implied warranty. In no event
# will the authors be held liable for any damages arising from the use of this software.
@@ -29,72 +29,87 @@ PLATFORM ?= PLATFORM_DESKTOP
RAYLIB_PATH ?= ..\..
PROJECT_NAME ?= koala_seasons
-# Library type used for raylib and OpenAL Soft: STATIC (.a) or SHARED (.so/.dll)
-# NOTE: Libraries should be provided in the selected form
-RAYLIB_LIBTYPE ?= STATIC
-OPENAL_LIBTYPE ?= STATIC
-
-# On PLATFORM_WEB force OpenAL Soft shared library
-ifeq ($(PLATFORM),PLATFORM_WEB)
- OPENAL_LIBTYPE = SHARED
+# Default path for raylib on Raspberry Pi, if installed in different path, update it!
+ifeq ($(PLATFORM),PLATFORM_RPI)
+ RAYLIB_PATH ?= /home/pi/raylib
endif
+# Library type used for raylib: STATIC (.a) or SHARED (.so/.dll)
+RAYLIB_LIBTYPE ?= STATIC
+
+# Use external GLFW library instead of rglfw module
+USE_EXTERNAL_GLFW ?= FALSE
+
+# Use Wayland display server protocol on Linux desktop
+# by default it uses X11 windowing system
+USE_WAYLAND_DISPLAY ?= FALSE
+
+# NOTE: On PLATFORM_WEB OpenAL Soft backend is used by default (check raylib/src/Makefile)
+
+
# Determine PLATFORM_OS in case PLATFORM_DESKTOP selected
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
- # No uname.exe on MinGW!, but OS=Windows_NT on Windows! ifeq ($(UNAME),Msys) -> Windows
+ # No uname.exe on MinGW!, but OS=Windows_NT on Windows!
+ # ifeq ($(UNAME),Msys) -> Windows
ifeq ($(OS),Windows_NT)
PLATFORM_OS=WINDOWS
- LIBPATH=win32
else
UNAMEOS=$(shell uname)
ifeq ($(UNAMEOS),Linux)
PLATFORM_OS=LINUX
- LIBPATH=linux
- else
+ endif
+ ifeq ($(UNAMEOS),FreeBSD)
+ PLATFORM_OS=FREEBSD
+ endif
ifeq ($(UNAMEOS),Darwin)
PLATFORM_OS=OSX
- LIBPATH=osx
- endif
endif
endif
endif
-
ifeq ($(PLATFORM),PLATFORM_RPI)
- # RPI cross-compiler
- RPI_CROSS_COMPILE ?= NO
+ UNAMEOS=$(shell uname)
+ ifeq ($(UNAMEOS),Linux)
+ PLATFORM_OS=LINUX
+ endif
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
# Emscripten required variables
EMSDK_PATH = C:/emsdk
- EMSCRIPTEN_VERSION = 1.37.21
- CLANG_VERSION=e1.37.21_64bit
+ EMSCRIPTEN_VERSION = 1.37.28
+ CLANG_VERSION=e1.37.28_64bit
PYTHON_VERSION=2.7.5.3_64bit
NODE_VERSION=4.1.1_64bit
export PATH=$(EMSDK_PATH);$(EMSDK_PATH)\clang\$(CLANG_VERSION);$(EMSDK_PATH)\node\$(NODE_VERSION)\bin;$(EMSDK_PATH)\python\$(PYTHON_VERSION);$(EMSDK_PATH)\emscripten\$(EMSCRIPTEN_VERSION);C:\raylib\MinGW\bin:$$(PATH)
EMSCRIPTEN=$(EMSDK_PATH)\emscripten\$(EMSCRIPTEN_VERSION)
endif
+RAYLIB_RELEASE_PATH ?= $(RAYLIB_PATH)/release/libs
+
# Define raylib release directory for compiled library
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),WINDOWS)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/win32/mingw32
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/win32/mingw32
endif
ifeq ($(PLATFORM_OS),LINUX)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/linux
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/linux
endif
ifeq ($(PLATFORM_OS),OSX)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/osx
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/osx
+ endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/freebsd
endif
endif
-ifeq ($(PLATFORM),PLATFORM_WEB)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/html5
-endif
ifeq ($(PLATFORM),PLATFORM_RPI)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/rpi
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/rpi
+endif
+ifeq ($(PLATFORM),PLATFORM_WEB)
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/html5
endif
# Define default C compiler: gcc
+# NOTE: define g++ compiler if using C++
CC = gcc
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
@@ -102,11 +117,16 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
# OSX default compiler
CC = clang
endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ # FreeBSD default compiler
+ CC = clang
+ endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
- ifeq ($(RPI_CROSS_COMPILE),YES)
- # RPI cross-compiler
- CC = armv6j-hardfloat-linux-gnueabi-gcc
+ ifeq ($(USE_RPI_CROSS_COMPILER),TRUE)
+ # Define RPI cross-compiler
+ #CC = armv6j-hardfloat-linux-gnueabi-gcc
+ CC = $(RPI_TOOLCHAIN)/bin/arm-linux-gnueabihf-gcc
endif
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
@@ -125,19 +145,23 @@ endif
# Define compiler flags:
# -O1 defines optimization level
-# -Og enable debugging
+# -g enable debugging
# -s strip unnecessary data from build
# -Wall turns on most, but not all, compiler warnings
# -std=c99 defines C language mode (standard C from 1999 revision)
# -std=gnu99 defines C language mode (GNU C from 1999 revision)
-# -fgnu89-inline declaring inline functions support (GCC optimized)
# -Wno-missing-braces ignore invalid warning (GCC bug 53119)
# -D_DEFAULT_SOURCE use with -std=c99 on Linux and PLATFORM_WEB, required for timespec
-CFLAGS += -O1 -s -Wall -std=c99 -D_DEFAULT_SOURCE -fgnu89-inline -Wno-missing-braces
+CFLAGS += -O1 -s -Wall -std=c99 -D_DEFAULT_SOURCE -Wno-missing-braces
# Additional flags for compiler (if desired)
#CFLAGS += -Wextra -Wmissing-prototypes -Wstrict-prototypes
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ ifeq ($(PLATFORM_OS),WINDOWS)
+ # resources file contains windows exe icon
+ # -Wl,--subsystem,windows hides the console window
+ CFLAGS += $(RAYLIB_PATH)/src/resources -Wl,--subsystem,windows
+ endif
ifeq ($(PLATFORM_OS),LINUX)
CFLAGS += -no-pie -D_DEFAULT_SOURCE
endif
@@ -151,7 +175,13 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
# -s ALLOW_MEMORY_GROWTH=1 # to allow memory resizing
# -s TOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB)
# -s USE_PTHREADS=1 # multithreading support
- CFLAGS += -s USE_GLFW=3 -s ASSERTIONS=1 --profiling -s TOTAL_MEMORY=16777216 --preload-file resources
+ # -s WASM=1 # support Web Assembly (https://github.com/kripken/emscripten/wiki/WebAssembly)
+ # --preload-file resources # specify a resources folder for data compilation
+ CFLAGS += -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 --profiling --preload-file resources
+
+ # Define a custom shell .html and output extension
+ CFLAGS += --shell-file $(RAYLIB_PATH)\templates\web_shell\shell.html
+ EXT = .html
endif
# Define include paths for required headers
@@ -167,7 +197,14 @@ ifeq ($(PLATFORM),PLATFORM_RPI)
endif
# Define library paths containing required libs
-LDFLAGS = -L. -L$(RAYLIB_RELEASE) -L$(RAYLIB_PATH)/src
+LDFLAGS = -L. -L$(RAYLIB_RELEASE_PATH) -L$(RAYLIB_PATH)/src
+
+ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ INCLUDE_PATHS += -I/usr/local/include
+ LDFLAGS += -L. -Lsrc -L/usr/local/lib
+ endif
+endif
ifeq ($(PLATFORM),PLATFORM_RPI)
LDFLAGS += -L/opt/vc/lib
@@ -177,54 +214,50 @@ endif
# if you want to link libraries (libname.so or libname.a), use the -lname
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),WINDOWS)
- # Libraries for Windows desktop compiling
- # NOTE: GLFW3 and OpenAL Soft libraries should be installed
- LDLIBS = -lraylib -lglfw3 -lopengl32 -lgdi32
-
- # Define required flags and libs for OpenAL Soft STATIC/SHARED usage
- # NOTE: ALLIBS flag only required for raylib Win32 SHARED library building
- ifeq ($(OPENAL_LIBTYPE),STATIC)
- LDLIBS += -lopenal32 -lwinmm
- CFLAGS += -DAL_LIBTYPE_STATIC -Wl,-allow-multiple-definition
- else
- LDLIBS += -lopenal32dll
- endif
+ # Libraries for Windows desktop compilation
+ LDLIBS = -lraylib -lopengl32 -lgdi32
endif
ifeq ($(PLATFORM_OS),LINUX)
# Libraries for Debian GNU/Linux desktop compiling
- # NOTE: Required packages: libglfw3-dev libopenal-dev libegl1-mesa-dev
- LDLIBS = -lraylib -lglfw3 -lGL -lopenal -lm -lpthread -ldl
+ # NOTE: Required packages: libegl1-mesa-dev
+ LDLIBS = -lraylib -lGL -lm -lpthread -ldl -lrt
- # On XWindow requires also below libraries
- LDLIBS += -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
+ # On X11 requires also below libraries
+ LDLIBS += -lX11
+ # NOTE: It seems additional libraries are not required any more, latest GLFW just dlopen them
+ #LDLIBS += -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
+
+ # On Wayland windowing system, additional libraries requires
+ ifeq ($(USE_WAYLAND_DISPLAY),TRUE)
+ LDLIBS += -lwayland-client -lwayland-cursor -lwayland-egl -lxkbcommon
+ endif
endif
ifeq ($(PLATFORM_OS),OSX)
# Libraries for OSX 10.9 desktop compiling
- # NOTE: Required packages: libglfw3-dev libopenal-dev libegl1-mesa-dev
- LDLIBS = -lraylib -lglfw -framework OpenGL -framework OpenAL -framework Cocoa
+ # NOTE: Required packages: libopenal-dev libegl1-mesa-dev
+ LDLIBS = -lraylib -framework OpenGL -framework OpenAL -framework Cocoa
+ endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ # Libraries for FreeBSD desktop compiling
+ # NOTE: Required packages: mesa-libs
+ LDLIBS = -lraylib -lGL -lpthread -lm
+
+ # On XWindow requires also below libraries
+ LDLIBS += -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
+ endif
+ ifeq ($(USE_EXTERNAL_GLFW),TRUE)
+ # NOTE: It could require additional packages installed: libglfw3-dev
+ LDLIBS += -lglfw
endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
# Libraries for Raspberry Pi compiling
- # NOTE: Required packages: libopenal1
- LDLIBS = -lraylib -lGLESv2 -lEGL -lpthread -lrt -lm -lbcm_host -lopenal
+ # NOTE: Required packages: libasound2-dev (ALSA)
+ LDLIBS = -lraylib -lbrcmGLESv2 -lbrcmEGL -lpthread -lrt -lm -lbcm_host -ldl
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
# Libraries for web (HTML5) compiling
- LDLIBS = $(RAYLIB_RELEASE)/libraylib.bc
-endif
-
-# Define additional parameters and flags for windows
-ifeq ($(PLATFORM_OS),WINDOWS)
- # resources file contains raylib icon for windows .exe
- # -Wl,--subsystem,windows hides the console window
- CFLAGS += $(RAYLIB_PATH)/src/resources -Wl,--subsystem,windows
-endif
-
-# Define output extension to generate a .html file using provided shell
-ifeq ($(PLATFORM),PLATFORM_WEB)
- EXT = .html
- WEB_SHELL = --shell-file $(RAYLIB_PATH)\templates\web_shell\shell.html
+ LDLIBS = $(RAYLIB_RELEASE_PATH)/libraylib.bc
endif
# Define all source files required
diff --git a/games/koala_seasons/Makefile.Android b/games/koala_seasons/Makefile.Android
index 1c8684544..f082ab230 100644
--- a/games/koala_seasons/Makefile.Android
+++ b/games/koala_seasons/Makefile.Android
@@ -53,26 +53,21 @@ APP_COMPANY_NAME ?= raylib
APP_PRODUCT_NAME ?= rgame
APP_VERSION_CODE ?= 1
APP_VERSION_NAME ?= 1.0
-APP_ICON_LDPI ?= $(RAYLIB_PATH)\logo\logo36x36.png
-APP_ICON_MDPI ?= $(RAYLIB_PATH)\logo\logo48x48.png
-APP_ICON_HDPI ?= $(RAYLIB_PATH)\logo\logo72x72.png
+APP_ICON_LDPI ?= $(RAYLIB_PATH)\logo\raylib_36x36.png
+APP_ICON_MDPI ?= $(RAYLIB_PATH)\logo\raylib_48x48.png
+APP_ICON_HDPI ?= $(RAYLIB_PATH)\logo\raylib_72x72.png
APP_SCREEN_ORIENTATION ?= landscape
APP_KEYSTORE_PASS ?= raylib
-# Library type used for raylib and OpenAL Soft: STATIC (.a) or SHARED (.so/.dll)
+# Library type used for raylib: STATIC (.a) or SHARED (.so/.dll)
RAYLIB_LIBTYPE ?= STATIC
-OPENAL_LIBTYPE ?= STATIC
RAYLIB_LIB_PATH = $(RAYLIB_PATH)\release\libs\android\armeabi-v7a
-OPENAL_LIB_PATH = $(RAYLIB_PATH)\release\libs\android\armeabi-v7a
# Shared libs must be added to APK if required
# NOTE: Generated NativeLoader.java automatically load those libraries
ifeq ($(RAYLIB_LIBTYPE),SHARED)
PROJECT_SHARED_LIBS = lib/armeabi-v7a/libraylib.so
endif
-ifeq ($(OPENAL_LIBTYPE),SHARED)
- PROJECT_SHARED_LIBS += lib/armeabi-v7a/libopenal.so
-endif
# Compiler and archiver
# NOTE: GCC is being deprectated in Android NDK r16
@@ -101,7 +96,7 @@ LDFLAGS += -L. -L$(PROJECT_BUILD_PATH)/obj -L$(PROJECT_BUILD_PATH)/lib/armeabi-v
# Define any libraries to link into executable
# if you want to link libraries (libname.so or libname.a), use the -lname
-LDLIBS = -lraylib -lnative_app_glue -lopenal -llog -landroid -lEGL -lGLESv2 -lOpenSLES -latomic -lc -lm -ldl
+LDLIBS = -lraylib -lnative_app_glue -llog -landroid -lEGL -lGLESv2 -lOpenSLES -latomic -lc -lm -ldl
# Generate target objects list from PROJECT_SOURCE_FILES
OBJS = $(patsubst %.c, $(PROJECT_BUILD_PATH)/obj/%.o, $(PROJECT_SOURCE_FILES))
@@ -154,15 +149,9 @@ copy_project_required_libs:
ifeq ($(RAYLIB_LIBTYPE),SHARED)
copy /Y $(RAYLIB_LIB_PATH)\libraylib.so $(PROJECT_BUILD_PATH)\lib\armeabi-v7a\libraylib.so
endif
-ifeq ($(OPENAL_LIBTYPE),SHARED)
- copy /Y $(OPENAL_LIB_PATH)\libopenal.so $(PROJECT_BUILD_PATH)\lib\armeabi-v7a\libopenal.so
-endif
ifeq ($(RAYLIB_LIBTYPE),STATIC)
copy /Y $(RAYLIB_LIB_PATH)\libraylib.a $(PROJECT_BUILD_PATH)\lib\armeabi-v7a\libraylib.a
endif
-ifeq ($(OPENAL_LIBTYPE),STATIC)
- copy /Y $(OPENAL_LIB_PATH)\libopenal.a $(PROJECT_BUILD_PATH)\lib\armeabi-v7a\libopenal.a
-endif
# Copy project required resources: strings.xml, icon.png, assets
# NOTE: Required strings.xml is generated and game resources are copied to assets folder
@@ -182,9 +171,6 @@ generate_loader_script:
@echo. >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
@echo public class NativeLoader extends android.app.NativeActivity { >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
@echo static { >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
-ifeq ($(OPENAL_LIBTYPE),SHARED)
- @echo System.loadLibrary("openal"); >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
-endif
ifeq ($(RAYLIB_LIBTYPE),SHARED)
@echo System.loadLibrary("raylib"); >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
endif
diff --git a/games/koala_seasons/koala_seasons.c b/games/koala_seasons/koala_seasons.c
index 770cf3ded..8657d3d56 100644
--- a/games/koala_seasons/koala_seasons.c
+++ b/games/koala_seasons/koala_seasons.c
@@ -15,10 +15,6 @@
#include "raylib.h"
#include "screens/screens.h" // NOTE: Defines currentScreen
-#if defined(PLATFORM_ANDROID)
- #include "android_native_app_glue.h"
-#endif
-
#if defined(PLATFORM_WEB)
#include
#endif
@@ -47,12 +43,7 @@ void UpdateDrawFrame(void); // Update and Draw one frame
//----------------------------------------------------------------------------------
// Main entry point
//----------------------------------------------------------------------------------
-#if defined(PLATFORM_ANDROID)
-void android_main(struct android_app *app)
-#else
-int main(void)
-#endif
-{
+int main(void) {
// Initialization
//---------------------------------------------------------
const int screenWidth = 1280;
@@ -62,11 +53,8 @@ int main(void)
//ShowLogo();
//SetConfigFlags(FLAG_FULLSCREEN_MODE);
-#if defined(PLATFORM_ANDROID)
- InitWindow(screenWidth, screenHeight, app);
-#else
+ // Note that windowTitle is ignored on Android
InitWindow(screenWidth, screenHeight, windowTitle);
-#endif
// Load global data here (assets that must be available in all screens, i.e. fonts)
font = LoadSpriteFont("resources/graphics/mainfont.png");
@@ -145,9 +133,8 @@ int main(void)
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
-#if !defined(PLATFORM_ANDROID)
+
return 0;
-#endif
}
void TransitionToScreen(int screen)
@@ -282,4 +269,4 @@ void UpdateDrawFrame(void)
EndDrawing();
//----------------------------------------------------------------------------------
-}
\ No newline at end of file
+}
diff --git a/games/koala_seasons/resources/graphics/atlas02.png b/games/koala_seasons/resources/graphics/atlas02.png
index c9c96d2d2..c94370590 100644
Binary files a/games/koala_seasons/resources/graphics/atlas02.png and b/games/koala_seasons/resources/graphics/atlas02.png differ
diff --git a/games/koala_seasons/resources/shaders/glsl100/base.vs b/games/koala_seasons/resources/shaders/glsl100/base.vs
index b05d3463f..93e8c8609 100644
--- a/games/koala_seasons/resources/shaders/glsl100/base.vs
+++ b/games/koala_seasons/resources/shaders/glsl100/base.vs
@@ -6,7 +6,7 @@ attribute vec2 vertexTexCoord;
attribute vec4 vertexColor;
// Input uniform values
-uniform mat4 mvpMatrix;
+uniform mat4 mvp;
// Output vertex attributes (to fragment shader)
varying vec2 fragTexCoord;
@@ -21,5 +21,5 @@ void main()
fragColor = vertexColor;
// Calculate final vertex position
- gl_Position = mvpMatrix*vec4(vertexPosition, 1.0);
+ gl_Position = mvp*vec4(vertexPosition, 1.0);
}
\ No newline at end of file
diff --git a/games/koala_seasons/screens/screen_title.c b/games/koala_seasons/screens/screen_title.c
index fd1661963..0459906dc 100644
--- a/games/koala_seasons/screens/screen_title.c
+++ b/games/koala_seasons/screens/screen_title.c
@@ -858,8 +858,8 @@ void DrawTitleScreen(void)
DrawTexturePro(atlas02, gameplay_background, (Rectangle){0, 0, gameplay_background.width*2, gameplay_background.height*2}, (Vector2){0, 0}, 0, color02);
// Draw parallax
- //DrawParallaxBack();
- //DrawParallaxMiddle();
+ DrawParallaxBack();
+ DrawParallaxMiddle();
for (int i = 0; i < MAX_particle; i++)
{
@@ -984,8 +984,6 @@ void DrawTitleScreen(void)
if (musicActive)DrawTexturePro(atlas01, title_speaker_on, (Rectangle){speakerButton.x, speakerButton.y, title_speaker_on.width, title_speaker_on.height}, (Vector2){0,0}, 0, WHITE);
else DrawTexturePro(atlas01, title_speaker_off, (Rectangle){speakerButton.x, speakerButton.y, title_speaker_off.width, title_speaker_off.height}, (Vector2){0,0}, 0, WHITE);
*/
-
- DrawParallaxFront();
}
// Title Screen Unload logic
@@ -1003,10 +1001,7 @@ int FinishTitleScreen(void)
static void DrawParallaxFront(void)
{
Rectangle ground01 = gameplay_back_ground01;
-
- DrawTexturePro(atlas02, gameplay_back_tree01_layer01, (Rectangle){0, 0, gameplay_back_tree01_layer01.width*2, gameplay_back_tree01_layer01.height*2}, (Vector2){0,0}, 0, WHITE);
- /*
//DrawTexturePro(atlas02, gameplay_back_tree01_layer03, (Rectangle){0, 21, gameplay_back_tree01_layer03.width*2, gameplay_back_tree01_layer03.height*2}, (Vector2){0,0}, 0, color02);
DrawTexturePro(atlas02, gameplay_back_tree01_layer01, (Rectangle){(int)parallaxFrontOffset, 60, gameplay_back_tree01_layer01.width*2, gameplay_back_tree01_layer01.height*2}, (Vector2){0,0}, 0, color02);
DrawTexturePro(atlas02, gameplay_back_tree02_layer01, (Rectangle){(int)parallaxFrontOffset + 140, 60, gameplay_back_tree02_layer01.width*2, gameplay_back_tree02_layer01.height*2}, (Vector2){0,0}, 0, color02);
@@ -1018,7 +1013,6 @@ static void DrawParallaxFront(void)
DrawTexturePro(atlas02, gameplay_back_tree08_layer01, (Rectangle){(int)parallaxFrontOffset + 140*7, 60, gameplay_back_tree08_layer01.width*2, gameplay_back_tree08_layer01.height*2}, (Vector2){0,0}, 0, color02);
DrawTexturePro(atlas02, gameplay_back_ground01, (Rectangle){0, 559, ground01.width*2, ground01.height*2}, (Vector2){0,0}, 0, color01);
DrawTexturePro(atlas02, (Rectangle){ground01.x, ground01.y + ground01.height, ground01.width, -ground01.height}, (Rectangle){0, -33, ground01.width*2, ground01.height*2}, (Vector2){0,0}, 0, color01);
- */
}
static void DrawParallaxMiddle(void)
diff --git a/games/light_my_ritual/Makefile b/games/light_my_ritual/Makefile
index 394c7be59..43738ac02 100644
--- a/games/light_my_ritual/Makefile
+++ b/games/light_my_ritual/Makefile
@@ -2,7 +2,7 @@
#
# raylib makefile for Desktop platforms, Raspberry Pi, Android and HTML5
#
-# Copyright (c) 2013-2017 Ramon Santamaria (@raysan5)
+# Copyright (c) 2013-2018 Ramon Santamaria (@raysan5)
#
# This software is provided "as-is", without any express or implied warranty. In no event
# will the authors be held liable for any damages arising from the use of this software.
@@ -29,72 +29,87 @@ PLATFORM ?= PLATFORM_DESKTOP
RAYLIB_PATH ?= ..\..
PROJECT_NAME ?= light_my_ritual
-# Library type used for raylib and OpenAL Soft: STATIC (.a) or SHARED (.so/.dll)
-# NOTE: Libraries should be provided in the selected form
-RAYLIB_LIBTYPE ?= STATIC
-OPENAL_LIBTYPE ?= STATIC
-
-# On PLATFORM_WEB force OpenAL Soft shared library
-ifeq ($(PLATFORM),PLATFORM_WEB)
- OPENAL_LIBTYPE = SHARED
+# Default path for raylib on Raspberry Pi, if installed in different path, update it!
+ifeq ($(PLATFORM),PLATFORM_RPI)
+ RAYLIB_PATH ?= /home/pi/raylib
endif
+# Library type used for raylib: STATIC (.a) or SHARED (.so/.dll)
+RAYLIB_LIBTYPE ?= STATIC
+
+# Use external GLFW library instead of rglfw module
+USE_EXTERNAL_GLFW ?= FALSE
+
+# Use Wayland display server protocol on Linux desktop
+# by default it uses X11 windowing system
+USE_WAYLAND_DISPLAY ?= FALSE
+
+# NOTE: On PLATFORM_WEB OpenAL Soft backend is used by default (check raylib/src/Makefile)
+
+
# Determine PLATFORM_OS in case PLATFORM_DESKTOP selected
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
- # No uname.exe on MinGW!, but OS=Windows_NT on Windows! ifeq ($(UNAME),Msys) -> Windows
+ # No uname.exe on MinGW!, but OS=Windows_NT on Windows!
+ # ifeq ($(UNAME),Msys) -> Windows
ifeq ($(OS),Windows_NT)
PLATFORM_OS=WINDOWS
- LIBPATH=win32
else
UNAMEOS=$(shell uname)
ifeq ($(UNAMEOS),Linux)
PLATFORM_OS=LINUX
- LIBPATH=linux
- else
+ endif
+ ifeq ($(UNAMEOS),FreeBSD)
+ PLATFORM_OS=FREEBSD
+ endif
ifeq ($(UNAMEOS),Darwin)
PLATFORM_OS=OSX
- LIBPATH=osx
- endif
endif
endif
endif
-
ifeq ($(PLATFORM),PLATFORM_RPI)
- # RPI cross-compiler
- RPI_CROSS_COMPILE ?= NO
+ UNAMEOS=$(shell uname)
+ ifeq ($(UNAMEOS),Linux)
+ PLATFORM_OS=LINUX
+ endif
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
# Emscripten required variables
EMSDK_PATH = C:/emsdk
- EMSCRIPTEN_VERSION = 1.37.21
- CLANG_VERSION=e1.37.21_64bit
+ EMSCRIPTEN_VERSION = 1.37.28
+ CLANG_VERSION=e1.37.28_64bit
PYTHON_VERSION=2.7.5.3_64bit
NODE_VERSION=4.1.1_64bit
export PATH=$(EMSDK_PATH);$(EMSDK_PATH)\clang\$(CLANG_VERSION);$(EMSDK_PATH)\node\$(NODE_VERSION)\bin;$(EMSDK_PATH)\python\$(PYTHON_VERSION);$(EMSDK_PATH)\emscripten\$(EMSCRIPTEN_VERSION);C:\raylib\MinGW\bin:$$(PATH)
EMSCRIPTEN=$(EMSDK_PATH)\emscripten\$(EMSCRIPTEN_VERSION)
endif
+RAYLIB_RELEASE_PATH ?= $(RAYLIB_PATH)/release/libs
+
# Define raylib release directory for compiled library
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),WINDOWS)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/win32/mingw32
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/win32/mingw32
endif
ifeq ($(PLATFORM_OS),LINUX)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/linux
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/linux
endif
ifeq ($(PLATFORM_OS),OSX)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/osx
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/osx
+ endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/freebsd
endif
endif
-ifeq ($(PLATFORM),PLATFORM_WEB)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/html5
-endif
ifeq ($(PLATFORM),PLATFORM_RPI)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/rpi
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/rpi
+endif
+ifeq ($(PLATFORM),PLATFORM_WEB)
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/html5
endif
# Define default C compiler: gcc
+# NOTE: define g++ compiler if using C++
CC = gcc
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
@@ -102,11 +117,16 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
# OSX default compiler
CC = clang
endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ # FreeBSD default compiler
+ CC = clang
+ endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
- ifeq ($(RPI_CROSS_COMPILE),YES)
- # RPI cross-compiler
- CC = armv6j-hardfloat-linux-gnueabi-gcc
+ ifeq ($(USE_RPI_CROSS_COMPILER),TRUE)
+ # Define RPI cross-compiler
+ #CC = armv6j-hardfloat-linux-gnueabi-gcc
+ CC = $(RPI_TOOLCHAIN)/bin/arm-linux-gnueabihf-gcc
endif
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
@@ -125,19 +145,23 @@ endif
# Define compiler flags:
# -O1 defines optimization level
-# -Og enable debugging
+# -g enable debugging
# -s strip unnecessary data from build
# -Wall turns on most, but not all, compiler warnings
# -std=c99 defines C language mode (standard C from 1999 revision)
# -std=gnu99 defines C language mode (GNU C from 1999 revision)
-# -fgnu89-inline declaring inline functions support (GCC optimized)
# -Wno-missing-braces ignore invalid warning (GCC bug 53119)
# -D_DEFAULT_SOURCE use with -std=c99 on Linux and PLATFORM_WEB, required for timespec
-CFLAGS += -O1 -s -Wall -std=c99 -D_DEFAULT_SOURCE -fgnu89-inline -Wno-missing-braces
+CFLAGS += -O1 -s -Wall -std=c99 -D_DEFAULT_SOURCE -Wno-missing-braces
# Additional flags for compiler (if desired)
#CFLAGS += -Wextra -Wmissing-prototypes -Wstrict-prototypes
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ ifeq ($(PLATFORM_OS),WINDOWS)
+ # resources file contains windows exe icon
+ # -Wl,--subsystem,windows hides the console window
+ CFLAGS += $(RAYLIB_PATH)/src/resources -Wl,--subsystem,windows
+ endif
ifeq ($(PLATFORM_OS),LINUX)
CFLAGS += -no-pie -D_DEFAULT_SOURCE
endif
@@ -151,7 +175,13 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
# -s ALLOW_MEMORY_GROWTH=1 # to allow memory resizing
# -s TOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB)
# -s USE_PTHREADS=1 # multithreading support
- CFLAGS += -s USE_GLFW=3 -s ASSERTIONS=1 --profiling -s TOTAL_MEMORY=16777216 --preload-file resources
+ # -s WASM=1 # support Web Assembly (https://github.com/kripken/emscripten/wiki/WebAssembly)
+ # --preload-file resources # specify a resources folder for data compilation
+ CFLAGS += -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 --profiling --preload-file resources
+
+ # Define a custom shell .html and output extension
+ CFLAGS += --shell-file $(RAYLIB_PATH)\templates\web_shell\shell.html
+ EXT = .html
endif
# Define include paths for required headers
@@ -167,7 +197,14 @@ ifeq ($(PLATFORM),PLATFORM_RPI)
endif
# Define library paths containing required libs
-LDFLAGS = -L. -L$(RAYLIB_RELEASE) -L$(RAYLIB_PATH)/src
+LDFLAGS = -L. -L$(RAYLIB_RELEASE_PATH) -L$(RAYLIB_PATH)/src
+
+ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ INCLUDE_PATHS += -I/usr/local/include
+ LDFLAGS += -L. -Lsrc -L/usr/local/lib
+ endif
+endif
ifeq ($(PLATFORM),PLATFORM_RPI)
LDFLAGS += -L/opt/vc/lib
@@ -177,54 +214,50 @@ endif
# if you want to link libraries (libname.so or libname.a), use the -lname
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),WINDOWS)
- # Libraries for Windows desktop compiling
- # NOTE: GLFW3 and OpenAL Soft libraries should be installed
- LDLIBS = -lraylib -lglfw3 -lopengl32 -lgdi32
-
- # Define required flags and libs for OpenAL Soft STATIC/SHARED usage
- # NOTE: ALLIBS flag only required for raylib Win32 SHARED library building
- ifeq ($(OPENAL_LIBTYPE),STATIC)
- LDLIBS += -lopenal32 -lwinmm
- CFLAGS += -DAL_LIBTYPE_STATIC -Wl,-allow-multiple-definition
- else
- LDLIBS += -lopenal32dll
- endif
+ # Libraries for Windows desktop compilation
+ LDLIBS = -lraylib -lopengl32 -lgdi32
endif
ifeq ($(PLATFORM_OS),LINUX)
# Libraries for Debian GNU/Linux desktop compiling
- # NOTE: Required packages: libglfw3-dev libopenal-dev libegl1-mesa-dev
- LDLIBS = -lraylib -lglfw3 -lGL -lopenal -lm -lpthread -ldl
+ # NOTE: Required packages: libegl1-mesa-dev
+ LDLIBS = -lraylib -lGL -lm -lpthread -ldl -lrt
- # On XWindow requires also below libraries
- LDLIBS += -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
+ # On X11 requires also below libraries
+ LDLIBS += -lX11
+ # NOTE: It seems additional libraries are not required any more, latest GLFW just dlopen them
+ #LDLIBS += -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
+
+ # On Wayland windowing system, additional libraries requires
+ ifeq ($(USE_WAYLAND_DISPLAY),TRUE)
+ LDLIBS += -lwayland-client -lwayland-cursor -lwayland-egl -lxkbcommon
+ endif
endif
ifeq ($(PLATFORM_OS),OSX)
# Libraries for OSX 10.9 desktop compiling
- # NOTE: Required packages: libglfw3-dev libopenal-dev libegl1-mesa-dev
- LDLIBS = -lraylib -lglfw -framework OpenGL -framework OpenAL -framework Cocoa
+ # NOTE: Required packages: libopenal-dev libegl1-mesa-dev
+ LDLIBS = -lraylib -framework OpenGL -framework OpenAL -framework Cocoa
+ endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ # Libraries for FreeBSD desktop compiling
+ # NOTE: Required packages: mesa-libs
+ LDLIBS = -lraylib -lGL -lpthread -lm
+
+ # On XWindow requires also below libraries
+ LDLIBS += -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
+ endif
+ ifeq ($(USE_EXTERNAL_GLFW),TRUE)
+ # NOTE: It could require additional packages installed: libglfw3-dev
+ LDLIBS += -lglfw
endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
# Libraries for Raspberry Pi compiling
- # NOTE: Required packages: libopenal1
- LDLIBS = -lraylib -lGLESv2 -lEGL -lpthread -lrt -lm -lbcm_host -lopenal
+ # NOTE: Required packages: libasound2-dev (ALSA)
+ LDLIBS = -lraylib -lbrcmGLESv2 -lbrcmEGL -lpthread -lrt -lm -lbcm_host -ldl
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
# Libraries for web (HTML5) compiling
- LDLIBS = $(RAYLIB_RELEASE)/libraylib.bc
-endif
-
-# Define additional parameters and flags for windows
-ifeq ($(PLATFORM_OS),WINDOWS)
- # resources file contains raylib icon for windows .exe
- # -Wl,--subsystem,windows hides the console window
- CFLAGS += $(RAYLIB_PATH)/src/resources -Wl,--subsystem,windows
-endif
-
-# Define output extension to generate a .html file using provided shell
-ifeq ($(PLATFORM),PLATFORM_WEB)
- EXT = .html
- WEB_SHELL = --shell-file $(RAYLIB_PATH)\templates\web_shell\shell.html
+ LDLIBS = $(RAYLIB_RELEASE_PATH)/libraylib.bc
endif
# Define all source files required
diff --git a/games/light_my_ritual/Makefile.Android b/games/light_my_ritual/Makefile.Android
index 1c8684544..f082ab230 100644
--- a/games/light_my_ritual/Makefile.Android
+++ b/games/light_my_ritual/Makefile.Android
@@ -53,26 +53,21 @@ APP_COMPANY_NAME ?= raylib
APP_PRODUCT_NAME ?= rgame
APP_VERSION_CODE ?= 1
APP_VERSION_NAME ?= 1.0
-APP_ICON_LDPI ?= $(RAYLIB_PATH)\logo\logo36x36.png
-APP_ICON_MDPI ?= $(RAYLIB_PATH)\logo\logo48x48.png
-APP_ICON_HDPI ?= $(RAYLIB_PATH)\logo\logo72x72.png
+APP_ICON_LDPI ?= $(RAYLIB_PATH)\logo\raylib_36x36.png
+APP_ICON_MDPI ?= $(RAYLIB_PATH)\logo\raylib_48x48.png
+APP_ICON_HDPI ?= $(RAYLIB_PATH)\logo\raylib_72x72.png
APP_SCREEN_ORIENTATION ?= landscape
APP_KEYSTORE_PASS ?= raylib
-# Library type used for raylib and OpenAL Soft: STATIC (.a) or SHARED (.so/.dll)
+# Library type used for raylib: STATIC (.a) or SHARED (.so/.dll)
RAYLIB_LIBTYPE ?= STATIC
-OPENAL_LIBTYPE ?= STATIC
RAYLIB_LIB_PATH = $(RAYLIB_PATH)\release\libs\android\armeabi-v7a
-OPENAL_LIB_PATH = $(RAYLIB_PATH)\release\libs\android\armeabi-v7a
# Shared libs must be added to APK if required
# NOTE: Generated NativeLoader.java automatically load those libraries
ifeq ($(RAYLIB_LIBTYPE),SHARED)
PROJECT_SHARED_LIBS = lib/armeabi-v7a/libraylib.so
endif
-ifeq ($(OPENAL_LIBTYPE),SHARED)
- PROJECT_SHARED_LIBS += lib/armeabi-v7a/libopenal.so
-endif
# Compiler and archiver
# NOTE: GCC is being deprectated in Android NDK r16
@@ -101,7 +96,7 @@ LDFLAGS += -L. -L$(PROJECT_BUILD_PATH)/obj -L$(PROJECT_BUILD_PATH)/lib/armeabi-v
# Define any libraries to link into executable
# if you want to link libraries (libname.so or libname.a), use the -lname
-LDLIBS = -lraylib -lnative_app_glue -lopenal -llog -landroid -lEGL -lGLESv2 -lOpenSLES -latomic -lc -lm -ldl
+LDLIBS = -lraylib -lnative_app_glue -llog -landroid -lEGL -lGLESv2 -lOpenSLES -latomic -lc -lm -ldl
# Generate target objects list from PROJECT_SOURCE_FILES
OBJS = $(patsubst %.c, $(PROJECT_BUILD_PATH)/obj/%.o, $(PROJECT_SOURCE_FILES))
@@ -154,15 +149,9 @@ copy_project_required_libs:
ifeq ($(RAYLIB_LIBTYPE),SHARED)
copy /Y $(RAYLIB_LIB_PATH)\libraylib.so $(PROJECT_BUILD_PATH)\lib\armeabi-v7a\libraylib.so
endif
-ifeq ($(OPENAL_LIBTYPE),SHARED)
- copy /Y $(OPENAL_LIB_PATH)\libopenal.so $(PROJECT_BUILD_PATH)\lib\armeabi-v7a\libopenal.so
-endif
ifeq ($(RAYLIB_LIBTYPE),STATIC)
copy /Y $(RAYLIB_LIB_PATH)\libraylib.a $(PROJECT_BUILD_PATH)\lib\armeabi-v7a\libraylib.a
endif
-ifeq ($(OPENAL_LIBTYPE),STATIC)
- copy /Y $(OPENAL_LIB_PATH)\libopenal.a $(PROJECT_BUILD_PATH)\lib\armeabi-v7a\libopenal.a
-endif
# Copy project required resources: strings.xml, icon.png, assets
# NOTE: Required strings.xml is generated and game resources are copied to assets folder
@@ -182,9 +171,6 @@ generate_loader_script:
@echo. >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
@echo public class NativeLoader extends android.app.NativeActivity { >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
@echo static { >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
-ifeq ($(OPENAL_LIBTYPE),SHARED)
- @echo System.loadLibrary("openal"); >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
-endif
ifeq ($(RAYLIB_LIBTYPE),SHARED)
@echo System.loadLibrary("raylib"); >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
endif
diff --git a/games/light_my_ritual/light_my_ritual.c b/games/light_my_ritual/light_my_ritual.c
index bc5a46238..985baa049 100644
--- a/games/light_my_ritual/light_my_ritual.c
+++ b/games/light_my_ritual/light_my_ritual.c
@@ -19,10 +19,6 @@
#include
-#if defined(PLATFORM_ANDROID)
- #include "android_native_app_glue.h"
-#endif
-
#if defined(PLATFORM_WEB)
#include
#endif
@@ -55,19 +51,11 @@ void UpdateDrawFrame(void); // Update and Draw one frame
//----------------------------------------------------------------------------------
// Main entry point
//----------------------------------------------------------------------------------
-#if defined(PLATFORM_ANDROID)
-void android_main(struct android_app *app)
-#else
int main(void)
-#endif
{
- // Initialization
+ // Initialization (Note windowTitle is unused on Android)
//---------------------------------------------------------
-#if defined(PLATFORM_ANDROID)
- InitWindow(screenWidth, screenHeight, app);
-#else
InitWindow(screenWidth, screenHeight, "GGJ16 - LIGHT MY RITUAL!");
-#endif
// Global data loading (assets that must be available in all screens, i.e. fonts)
InitAudioDevice();
@@ -129,9 +117,8 @@ int main(void)
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
-#if !defined(PLATFORM_ANDROID)
+
return 0;
-#endif
}
void TransitionToScreen(int screen)
diff --git a/games/missile_commander.c b/games/missile_commander.c
index 245cefd13..15e06f6d5 100644
--- a/games/missile_commander.c
+++ b/games/missile_commander.c
@@ -18,10 +18,6 @@
#include
#include
-#if defined(PLATFORM_ANDROID)
- #include "android_native_app_glue.h"
-#endif
-
#if defined(PLATFORM_WEB)
#include
#endif
@@ -119,19 +115,11 @@ static void UpdateIncomingFire();
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
-#if defined(PLATFORM_ANDROID)
-void android_main(struct android_app *app)
-#else
int main(void)
-#endif
{
- // Initialization
+ // Initialization (Note windowTitle is unused on Android)
//---------------------------------------------------------
-#if defined(PLATFORM_ANDROID)
- InitWindow(screenWidth, screenHeight, app);
-#else
InitWindow(screenWidth, screenHeight, "sample game: missile commander");
-#endif
InitGame();
@@ -158,9 +146,8 @@ int main(void)
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
-#if !defined(PLATFORM_ANDROID)
+
return 0;
-#endif
}
//--------------------------------------------------------------------------------------
@@ -544,4 +531,4 @@ static void UpdateIncomingFire()
missileIndex++;
if (missileIndex == MAX_MISSILES) missileIndex = 0;
}
-}
\ No newline at end of file
+}
diff --git a/games/pang.c b/games/pang.c
index 731234ae5..a81f32f01 100644
--- a/games/pang.c
+++ b/games/pang.c
@@ -15,10 +15,6 @@
#include
-#if defined(PLATFORM_ANDROID)
- #include "android_native_app_glue.h"
-#endif
-
#if defined(PLATFORM_WEB)
#include
#endif
@@ -110,19 +106,11 @@ static void UpdateDrawFrame(void); // Update and Draw (one frame)
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
-#if defined(PLATFORM_ANDROID)
-void android_main(struct android_app *app)
-#else
int main(void)
-#endif
{
- // Initialization
+ // Initialization (Note windowTitle is unused on Android)
//---------------------------------------------------------
-#if defined(PLATFORM_ANDROID)
- InitWindow(screenWidth, screenHeight, app);
-#else
InitWindow(screenWidth, screenHeight, "sample game: pang");
-#endif
InitGame();
@@ -149,9 +137,8 @@ int main(void)
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
-#if !defined(PLATFORM_ANDROID)
+
return 0;
-#endif
}
//------------------------------------------------------------------------------------
@@ -637,4 +624,4 @@ void UpdateDrawFrame(void)
{
UpdateGame();
DrawGame();
-}
\ No newline at end of file
+}
diff --git a/games/skully_escape/Makefile b/games/skully_escape/Makefile
index 7baf82e8a..2191114b4 100644
--- a/games/skully_escape/Makefile
+++ b/games/skully_escape/Makefile
@@ -2,7 +2,7 @@
#
# raylib makefile for Desktop platforms, Raspberry Pi, Android and HTML5
#
-# Copyright (c) 2013-2017 Ramon Santamaria (@raysan5)
+# Copyright (c) 2013-2018 Ramon Santamaria (@raysan5)
#
# This software is provided "as-is", without any express or implied warranty. In no event
# will the authors be held liable for any damages arising from the use of this software.
@@ -29,72 +29,87 @@ PLATFORM ?= PLATFORM_DESKTOP
RAYLIB_PATH ?= ..\..
PROJECT_NAME ?= skully_escape
-# Library type used for raylib and OpenAL Soft: STATIC (.a) or SHARED (.so/.dll)
-# NOTE: Libraries should be provided in the selected form
-RAYLIB_LIBTYPE ?= STATIC
-OPENAL_LIBTYPE ?= STATIC
-
-# On PLATFORM_WEB force OpenAL Soft shared library
-ifeq ($(PLATFORM),PLATFORM_WEB)
- OPENAL_LIBTYPE = SHARED
+# Default path for raylib on Raspberry Pi, if installed in different path, update it!
+ifeq ($(PLATFORM),PLATFORM_RPI)
+ RAYLIB_PATH ?= /home/pi/raylib
endif
+# Library type used for raylib: STATIC (.a) or SHARED (.so/.dll)
+RAYLIB_LIBTYPE ?= STATIC
+
+# Use external GLFW library instead of rglfw module
+USE_EXTERNAL_GLFW ?= FALSE
+
+# Use Wayland display server protocol on Linux desktop
+# by default it uses X11 windowing system
+USE_WAYLAND_DISPLAY ?= FALSE
+
+# NOTE: On PLATFORM_WEB OpenAL Soft backend is used by default (check raylib/src/Makefile)
+
+
# Determine PLATFORM_OS in case PLATFORM_DESKTOP selected
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
- # No uname.exe on MinGW!, but OS=Windows_NT on Windows! ifeq ($(UNAME),Msys) -> Windows
+ # No uname.exe on MinGW!, but OS=Windows_NT on Windows!
+ # ifeq ($(UNAME),Msys) -> Windows
ifeq ($(OS),Windows_NT)
PLATFORM_OS=WINDOWS
- LIBPATH=win32
else
UNAMEOS=$(shell uname)
ifeq ($(UNAMEOS),Linux)
PLATFORM_OS=LINUX
- LIBPATH=linux
- else
+ endif
+ ifeq ($(UNAMEOS),FreeBSD)
+ PLATFORM_OS=FREEBSD
+ endif
ifeq ($(UNAMEOS),Darwin)
PLATFORM_OS=OSX
- LIBPATH=osx
- endif
endif
endif
endif
-
ifeq ($(PLATFORM),PLATFORM_RPI)
- # RPI cross-compiler
- RPI_CROSS_COMPILE ?= NO
+ UNAMEOS=$(shell uname)
+ ifeq ($(UNAMEOS),Linux)
+ PLATFORM_OS=LINUX
+ endif
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
# Emscripten required variables
EMSDK_PATH = C:/emsdk
- EMSCRIPTEN_VERSION = 1.37.21
- CLANG_VERSION=e1.37.21_64bit
+ EMSCRIPTEN_VERSION = 1.37.28
+ CLANG_VERSION=e1.37.28_64bit
PYTHON_VERSION=2.7.5.3_64bit
NODE_VERSION=4.1.1_64bit
export PATH=$(EMSDK_PATH);$(EMSDK_PATH)\clang\$(CLANG_VERSION);$(EMSDK_PATH)\node\$(NODE_VERSION)\bin;$(EMSDK_PATH)\python\$(PYTHON_VERSION);$(EMSDK_PATH)\emscripten\$(EMSCRIPTEN_VERSION);C:\raylib\MinGW\bin:$$(PATH)
EMSCRIPTEN=$(EMSDK_PATH)\emscripten\$(EMSCRIPTEN_VERSION)
endif
+RAYLIB_RELEASE_PATH ?= $(RAYLIB_PATH)/release/libs
+
# Define raylib release directory for compiled library
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),WINDOWS)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/win32/mingw32
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/win32/mingw32
endif
ifeq ($(PLATFORM_OS),LINUX)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/linux
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/linux
endif
ifeq ($(PLATFORM_OS),OSX)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/osx
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/osx
+ endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/freebsd
endif
endif
-ifeq ($(PLATFORM),PLATFORM_WEB)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/html5
-endif
ifeq ($(PLATFORM),PLATFORM_RPI)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/rpi
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/rpi
+endif
+ifeq ($(PLATFORM),PLATFORM_WEB)
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/html5
endif
# Define default C compiler: gcc
+# NOTE: define g++ compiler if using C++
CC = gcc
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
@@ -102,11 +117,16 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
# OSX default compiler
CC = clang
endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ # FreeBSD default compiler
+ CC = clang
+ endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
- ifeq ($(RPI_CROSS_COMPILE),YES)
- # RPI cross-compiler
- CC = armv6j-hardfloat-linux-gnueabi-gcc
+ ifeq ($(USE_RPI_CROSS_COMPILER),TRUE)
+ # Define RPI cross-compiler
+ #CC = armv6j-hardfloat-linux-gnueabi-gcc
+ CC = $(RPI_TOOLCHAIN)/bin/arm-linux-gnueabihf-gcc
endif
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
@@ -125,19 +145,23 @@ endif
# Define compiler flags:
# -O1 defines optimization level
-# -Og enable debugging
+# -g enable debugging
# -s strip unnecessary data from build
# -Wall turns on most, but not all, compiler warnings
# -std=c99 defines C language mode (standard C from 1999 revision)
# -std=gnu99 defines C language mode (GNU C from 1999 revision)
-# -fgnu89-inline declaring inline functions support (GCC optimized)
# -Wno-missing-braces ignore invalid warning (GCC bug 53119)
# -D_DEFAULT_SOURCE use with -std=c99 on Linux and PLATFORM_WEB, required for timespec
-CFLAGS += -O1 -s -Wall -std=c99 -D_DEFAULT_SOURCE -fgnu89-inline -Wno-missing-braces
+CFLAGS += -O1 -s -Wall -std=c99 -D_DEFAULT_SOURCE -Wno-missing-braces
# Additional flags for compiler (if desired)
#CFLAGS += -Wextra -Wmissing-prototypes -Wstrict-prototypes
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ ifeq ($(PLATFORM_OS),WINDOWS)
+ # resources file contains windows exe icon
+ # -Wl,--subsystem,windows hides the console window
+ CFLAGS += $(RAYLIB_PATH)/src/resources -Wl,--subsystem,windows
+ endif
ifeq ($(PLATFORM_OS),LINUX)
CFLAGS += -no-pie -D_DEFAULT_SOURCE
endif
@@ -151,7 +175,13 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
# -s ALLOW_MEMORY_GROWTH=1 # to allow memory resizing
# -s TOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB)
# -s USE_PTHREADS=1 # multithreading support
- CFLAGS += -s USE_GLFW=3 -s ASSERTIONS=1 --profiling -s TOTAL_MEMORY=16777216 --preload-file resources
+ # -s WASM=1 # support Web Assembly (https://github.com/kripken/emscripten/wiki/WebAssembly)
+ # --preload-file resources # specify a resources folder for data compilation
+ CFLAGS += -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 --profiling --preload-file resources
+
+ # Define a custom shell .html and output extension
+ CFLAGS += --shell-file $(RAYLIB_PATH)\templates\web_shell\shell.html
+ EXT = .html
endif
# Define include paths for required headers
@@ -167,7 +197,14 @@ ifeq ($(PLATFORM),PLATFORM_RPI)
endif
# Define library paths containing required libs
-LDFLAGS = -L. -L$(RAYLIB_RELEASE) -L$(RAYLIB_PATH)/src
+LDFLAGS = -L. -L$(RAYLIB_RELEASE_PATH) -L$(RAYLIB_PATH)/src
+
+ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ INCLUDE_PATHS += -I/usr/local/include
+ LDFLAGS += -L. -Lsrc -L/usr/local/lib
+ endif
+endif
ifeq ($(PLATFORM),PLATFORM_RPI)
LDFLAGS += -L/opt/vc/lib
@@ -177,54 +214,50 @@ endif
# if you want to link libraries (libname.so or libname.a), use the -lname
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),WINDOWS)
- # Libraries for Windows desktop compiling
- # NOTE: GLFW3 and OpenAL Soft libraries should be installed
- LDLIBS = -lraylib -lglfw3 -lopengl32 -lgdi32
-
- # Define required flags and libs for OpenAL Soft STATIC/SHARED usage
- # NOTE: ALLIBS flag only required for raylib Win32 SHARED library building
- ifeq ($(OPENAL_LIBTYPE),STATIC)
- LDLIBS += -lopenal32 -lwinmm
- CFLAGS += -DAL_LIBTYPE_STATIC -Wl,-allow-multiple-definition
- else
- LDLIBS += -lopenal32dll
- endif
+ # Libraries for Windows desktop compilation
+ LDLIBS = -lraylib -lopengl32 -lgdi32
endif
ifeq ($(PLATFORM_OS),LINUX)
# Libraries for Debian GNU/Linux desktop compiling
- # NOTE: Required packages: libglfw3-dev libopenal-dev libegl1-mesa-dev
- LDLIBS = -lraylib -lglfw3 -lGL -lopenal -lm -lpthread -ldl
+ # NOTE: Required packages: libegl1-mesa-dev
+ LDLIBS = -lraylib -lGL -lm -lpthread -ldl -lrt
- # On XWindow requires also below libraries
- LDLIBS += -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
+ # On X11 requires also below libraries
+ LDLIBS += -lX11
+ # NOTE: It seems additional libraries are not required any more, latest GLFW just dlopen them
+ #LDLIBS += -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
+
+ # On Wayland windowing system, additional libraries requires
+ ifeq ($(USE_WAYLAND_DISPLAY),TRUE)
+ LDLIBS += -lwayland-client -lwayland-cursor -lwayland-egl -lxkbcommon
+ endif
endif
ifeq ($(PLATFORM_OS),OSX)
# Libraries for OSX 10.9 desktop compiling
- # NOTE: Required packages: libglfw3-dev libopenal-dev libegl1-mesa-dev
- LDLIBS = -lraylib -lglfw -framework OpenGL -framework OpenAL -framework Cocoa
+ # NOTE: Required packages: libopenal-dev libegl1-mesa-dev
+ LDLIBS = -lraylib -framework OpenGL -framework OpenAL -framework Cocoa
+ endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ # Libraries for FreeBSD desktop compiling
+ # NOTE: Required packages: mesa-libs
+ LDLIBS = -lraylib -lGL -lpthread -lm
+
+ # On XWindow requires also below libraries
+ LDLIBS += -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
+ endif
+ ifeq ($(USE_EXTERNAL_GLFW),TRUE)
+ # NOTE: It could require additional packages installed: libglfw3-dev
+ LDLIBS += -lglfw
endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
# Libraries for Raspberry Pi compiling
- # NOTE: Required packages: libopenal1
- LDLIBS = -lraylib -lGLESv2 -lEGL -lpthread -lrt -lm -lbcm_host -lopenal
+ # NOTE: Required packages: libasound2-dev (ALSA)
+ LDLIBS = -lraylib -lbrcmGLESv2 -lbrcmEGL -lpthread -lrt -lm -lbcm_host -ldl
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
# Libraries for web (HTML5) compiling
- LDLIBS = $(RAYLIB_RELEASE)/libraylib.bc
-endif
-
-# Define additional parameters and flags for windows
-ifeq ($(PLATFORM_OS),WINDOWS)
- # resources file contains raylib icon for windows .exe
- # -Wl,--subsystem,windows hides the console window
- CFLAGS += $(RAYLIB_PATH)/src/resources -Wl,--subsystem,windows
-endif
-
-# Define output extension to generate a .html file using provided shell
-ifeq ($(PLATFORM),PLATFORM_WEB)
- EXT = .html
- WEB_SHELL = --shell-file $(RAYLIB_PATH)\templates\web_shell\shell.html
+ LDLIBS = $(RAYLIB_RELEASE_PATH)/libraylib.bc
endif
# Define all source files required
diff --git a/games/skully_escape/Makefile.Android b/games/skully_escape/Makefile.Android
index 1c8684544..f082ab230 100644
--- a/games/skully_escape/Makefile.Android
+++ b/games/skully_escape/Makefile.Android
@@ -53,26 +53,21 @@ APP_COMPANY_NAME ?= raylib
APP_PRODUCT_NAME ?= rgame
APP_VERSION_CODE ?= 1
APP_VERSION_NAME ?= 1.0
-APP_ICON_LDPI ?= $(RAYLIB_PATH)\logo\logo36x36.png
-APP_ICON_MDPI ?= $(RAYLIB_PATH)\logo\logo48x48.png
-APP_ICON_HDPI ?= $(RAYLIB_PATH)\logo\logo72x72.png
+APP_ICON_LDPI ?= $(RAYLIB_PATH)\logo\raylib_36x36.png
+APP_ICON_MDPI ?= $(RAYLIB_PATH)\logo\raylib_48x48.png
+APP_ICON_HDPI ?= $(RAYLIB_PATH)\logo\raylib_72x72.png
APP_SCREEN_ORIENTATION ?= landscape
APP_KEYSTORE_PASS ?= raylib
-# Library type used for raylib and OpenAL Soft: STATIC (.a) or SHARED (.so/.dll)
+# Library type used for raylib: STATIC (.a) or SHARED (.so/.dll)
RAYLIB_LIBTYPE ?= STATIC
-OPENAL_LIBTYPE ?= STATIC
RAYLIB_LIB_PATH = $(RAYLIB_PATH)\release\libs\android\armeabi-v7a
-OPENAL_LIB_PATH = $(RAYLIB_PATH)\release\libs\android\armeabi-v7a
# Shared libs must be added to APK if required
# NOTE: Generated NativeLoader.java automatically load those libraries
ifeq ($(RAYLIB_LIBTYPE),SHARED)
PROJECT_SHARED_LIBS = lib/armeabi-v7a/libraylib.so
endif
-ifeq ($(OPENAL_LIBTYPE),SHARED)
- PROJECT_SHARED_LIBS += lib/armeabi-v7a/libopenal.so
-endif
# Compiler and archiver
# NOTE: GCC is being deprectated in Android NDK r16
@@ -101,7 +96,7 @@ LDFLAGS += -L. -L$(PROJECT_BUILD_PATH)/obj -L$(PROJECT_BUILD_PATH)/lib/armeabi-v
# Define any libraries to link into executable
# if you want to link libraries (libname.so or libname.a), use the -lname
-LDLIBS = -lraylib -lnative_app_glue -lopenal -llog -landroid -lEGL -lGLESv2 -lOpenSLES -latomic -lc -lm -ldl
+LDLIBS = -lraylib -lnative_app_glue -llog -landroid -lEGL -lGLESv2 -lOpenSLES -latomic -lc -lm -ldl
# Generate target objects list from PROJECT_SOURCE_FILES
OBJS = $(patsubst %.c, $(PROJECT_BUILD_PATH)/obj/%.o, $(PROJECT_SOURCE_FILES))
@@ -154,15 +149,9 @@ copy_project_required_libs:
ifeq ($(RAYLIB_LIBTYPE),SHARED)
copy /Y $(RAYLIB_LIB_PATH)\libraylib.so $(PROJECT_BUILD_PATH)\lib\armeabi-v7a\libraylib.so
endif
-ifeq ($(OPENAL_LIBTYPE),SHARED)
- copy /Y $(OPENAL_LIB_PATH)\libopenal.so $(PROJECT_BUILD_PATH)\lib\armeabi-v7a\libopenal.so
-endif
ifeq ($(RAYLIB_LIBTYPE),STATIC)
copy /Y $(RAYLIB_LIB_PATH)\libraylib.a $(PROJECT_BUILD_PATH)\lib\armeabi-v7a\libraylib.a
endif
-ifeq ($(OPENAL_LIBTYPE),STATIC)
- copy /Y $(OPENAL_LIB_PATH)\libopenal.a $(PROJECT_BUILD_PATH)\lib\armeabi-v7a\libopenal.a
-endif
# Copy project required resources: strings.xml, icon.png, assets
# NOTE: Required strings.xml is generated and game resources are copied to assets folder
@@ -182,9 +171,6 @@ generate_loader_script:
@echo. >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
@echo public class NativeLoader extends android.app.NativeActivity { >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
@echo static { >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
-ifeq ($(OPENAL_LIBTYPE),SHARED)
- @echo System.loadLibrary("openal"); >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
-endif
ifeq ($(RAYLIB_LIBTYPE),SHARED)
@echo System.loadLibrary("raylib"); >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
endif
diff --git a/games/skully_escape/skully_escape.c b/games/skully_escape/skully_escape.c
index 3a0e4cb01..dc545117f 100644
--- a/games/skully_escape/skully_escape.c
+++ b/games/skully_escape/skully_escape.c
@@ -14,10 +14,6 @@
#include "player.h"
-#if defined(PLATFORM_ANDROID)
- #include "android_native_app_glue.h"
-#endif
-
#if defined(PLATFORM_WEB)
#include
#endif
@@ -52,19 +48,11 @@ void UpdateDrawFrame(void); // Update and Draw one frame
//----------------------------------------------------------------------------------
// Main entry point
//----------------------------------------------------------------------------------
-#if defined(PLATFORM_ANDROID)
-void android_main(struct android_app *app)
-#else
int main(void)
-#endif
{
- // Initialization
+ // Initialization (Note windowTitle is unused on Android)
//---------------------------------------------------------
-#if defined(PLATFORM_ANDROID)
- InitWindow(screenWidth, screenHeight, app);
-#else
InitWindow(screenWidth, screenHeight, "SKULLY ESCAPE [KING GAMEJAM]");
-#endif
// Global data loading (assets that must be available in all screens, i.e. fonts)
InitAudioDevice();
@@ -112,9 +100,8 @@ int main(void)
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
-#if !defined(PLATFORM_ANDROID)
+
return 0;
-#endif
}
void TransitionToScreen(int screen)
diff --git a/games/snake.c b/games/snake.c
index c971ce153..40d66da86 100644
--- a/games/snake.c
+++ b/games/snake.c
@@ -13,10 +13,6 @@
#include "raylib.h"
-#if defined(PLATFORM_ANDROID)
- #include "android_native_app_glue.h"
-#endif
-
#if defined(PLATFORM_WEB)
#include
#endif
@@ -73,19 +69,11 @@ static void UpdateDrawFrame(void); // Update and Draw (one frame)
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
-#if defined(PLATFORM_ANDROID)
-void android_main(struct android_app *app)
-#else
int main(void)
-#endif
{
- // Initialization
+ // Initialization (Note windowTitle is unused on Android)
//---------------------------------------------------------
-#if defined(PLATFORM_ANDROID)
- InitWindow(screenWidth, screenHeight, app);
-#else
InitWindow(screenWidth, screenHeight, "sample game: snake");
-#endif
InitGame();
@@ -112,9 +100,8 @@ int main(void)
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
-#if !defined(PLATFORM_ANDROID)
+
return 0;
-#endif
}
//------------------------------------------------------------------------------------
@@ -298,4 +285,4 @@ void UpdateDrawFrame(void)
{
UpdateGame();
DrawGame();
-}
\ No newline at end of file
+}
diff --git a/games/space_invaders.c b/games/space_invaders.c
index b80de050b..97f145473 100644
--- a/games/space_invaders.c
+++ b/games/space_invaders.c
@@ -13,10 +13,6 @@
#include "raylib.h"
-#if defined(PLATFORM_ANDROID)
- #include "android_native_app_glue.h"
-#endif
-
#if defined(PLATFORM_WEB)
#include
#endif
@@ -90,19 +86,11 @@ static void UpdateDrawFrame(void); // Update and Draw (one frame)
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
-#if defined(PLATFORM_ANDROID)
-void android_main(struct android_app *app)
-#else
int main(void)
-#endif
{
- // Initialization
+ // Initialization (Note windowTitle is unused on Android)
//---------------------------------------------------------
-#if defined(PLATFORM_ANDROID)
- InitWindow(screenWidth, screenHeight, app);
-#else
InitWindow(screenWidth, screenHeight, "sample game: space invaders");
-#endif
InitGame();
@@ -129,9 +117,8 @@ int main(void)
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
-#if !defined(PLATFORM_ANDROID)
+
return 0;
-#endif
}
//------------------------------------------------------------------------------------
@@ -410,4 +397,4 @@ void UpdateDrawFrame(void)
{
UpdateGame();
DrawGame();
-}
\ No newline at end of file
+}
diff --git a/games/tetris.c b/games/tetris.c
index e02d7f185..3c9d5c5c6 100644
--- a/games/tetris.c
+++ b/games/tetris.c
@@ -18,10 +18,6 @@
#include
#include
-#if defined(PLATFORM_ANDROID)
- #include "android_native_app_glue.h"
-#endif
-
#if defined(PLATFORM_WEB)
#include
#endif
@@ -109,19 +105,11 @@ static void DeleteCompleteLines();
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
-#if defined(PLATFORM_ANDROID)
-void android_main(struct android_app *app)
-#else
int main(void)
-#endif
{
- // Initialization
+ // Initialization (Note windowTitle is unused on Android)
//---------------------------------------------------------
-#if defined(PLATFORM_ANDROID)
- InitWindow(screenWidth, screenHeight, app);
-#else
InitWindow(screenWidth, screenHeight, "sample game: tetris");
-#endif
InitGame();
@@ -148,9 +136,8 @@ int main(void)
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
-#if !defined(PLATFORM_ANDROID)
+
return 0;
-#endif
}
//--------------------------------------------------------------------------------------
@@ -841,4 +828,4 @@ static void DeleteCompleteLines()
}
}
}
-}
\ No newline at end of file
+}
diff --git a/games/transmission/Makefile b/games/transmission/Makefile
new file mode 100644
index 000000000..60ab1d0a8
--- /dev/null
+++ b/games/transmission/Makefile
@@ -0,0 +1,319 @@
+#**************************************************************************************************
+#
+# raylib makefile for Desktop platforms, Raspberry Pi, Android and HTML5
+#
+# Copyright (c) 2013-2018 Ramon Santamaria (@raysan5)
+#
+# This software is provided "as-is", without any express or implied warranty. In no event
+# will the authors be held liable for any damages arising from the use of this software.
+#
+# Permission is granted to anyone to use this software for any purpose, including commercial
+# applications, and to alter it and redistribute it freely, subject to the following restrictions:
+#
+# 1. The origin of this software must not be misrepresented; you must not claim that you
+# wrote the original software. If you use this software in a product, an acknowledgment
+# in the product documentation would be appreciated but is not required.
+#
+# 2. Altered source versions must be plainly marked as such, and must not be misrepresented
+# as being the original software.
+#
+# 3. This notice may not be removed or altered from any source distribution.
+#
+#**************************************************************************************************
+
+.PHONY: all clean
+
+# Define required raylib variables
+# WARNING: To compile to HTML5, code must be redesigned to use emscripten.h and emscripten_set_main_loop()
+PLATFORM ?= PLATFORM_DESKTOP
+RAYLIB_PATH ?= ..\..
+PROJECT_NAME ?= transmission
+
+# Default path for raylib on Raspberry Pi, if installed in different path, update it!
+ifeq ($(PLATFORM),PLATFORM_RPI)
+ RAYLIB_PATH ?= /home/pi/raylib
+endif
+
+# Library type used for raylib: STATIC (.a) or SHARED (.so/.dll)
+RAYLIB_LIBTYPE ?= STATIC
+
+# Use external GLFW library instead of rglfw module
+USE_EXTERNAL_GLFW ?= FALSE
+
+# Use Wayland display server protocol on Linux desktop
+# by default it uses X11 windowing system
+USE_WAYLAND_DISPLAY ?= FALSE
+
+# NOTE: On PLATFORM_WEB OpenAL Soft backend is used by default (check raylib/src/Makefile)
+
+
+# Determine PLATFORM_OS in case PLATFORM_DESKTOP selected
+ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ # No uname.exe on MinGW!, but OS=Windows_NT on Windows!
+ # ifeq ($(UNAME),Msys) -> Windows
+ ifeq ($(OS),Windows_NT)
+ PLATFORM_OS=WINDOWS
+ else
+ UNAMEOS=$(shell uname)
+ ifeq ($(UNAMEOS),Linux)
+ PLATFORM_OS=LINUX
+ endif
+ ifeq ($(UNAMEOS),FreeBSD)
+ PLATFORM_OS=FREEBSD
+ endif
+ ifeq ($(UNAMEOS),Darwin)
+ PLATFORM_OS=OSX
+ endif
+ endif
+endif
+ifeq ($(PLATFORM),PLATFORM_RPI)
+ UNAMEOS=$(shell uname)
+ ifeq ($(UNAMEOS),Linux)
+ PLATFORM_OS=LINUX
+ endif
+endif
+
+ifeq ($(PLATFORM),PLATFORM_WEB)
+ # Emscripten required variables
+ EMSDK_PATH = C:/emsdk
+ EMSCRIPTEN_VERSION = 1.37.28
+ CLANG_VERSION=e1.37.28_64bit
+ PYTHON_VERSION=2.7.5.3_64bit
+ NODE_VERSION=4.1.1_64bit
+ export PATH=$(EMSDK_PATH);$(EMSDK_PATH)\clang\$(CLANG_VERSION);$(EMSDK_PATH)\node\$(NODE_VERSION)\bin;$(EMSDK_PATH)\python\$(PYTHON_VERSION);$(EMSDK_PATH)\emscripten\$(EMSCRIPTEN_VERSION);C:\raylib\MinGW\bin:$$(PATH)
+ EMSCRIPTEN=$(EMSDK_PATH)\emscripten\$(EMSCRIPTEN_VERSION)
+endif
+
+RAYLIB_RELEASE_PATH ?= $(RAYLIB_PATH)/release/libs
+
+# Define raylib release directory for compiled library
+ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ ifeq ($(PLATFORM_OS),WINDOWS)
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/win32/mingw32
+ endif
+ ifeq ($(PLATFORM_OS),LINUX)
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/linux
+ endif
+ ifeq ($(PLATFORM_OS),OSX)
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/osx
+ endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/freebsd
+ endif
+endif
+ifeq ($(PLATFORM),PLATFORM_RPI)
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/rpi
+endif
+ifeq ($(PLATFORM),PLATFORM_WEB)
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/html5
+endif
+
+# Define default C compiler: gcc
+# NOTE: define g++ compiler if using C++
+CC = gcc
+
+ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ ifeq ($(PLATFORM_OS),OSX)
+ # OSX default compiler
+ CC = clang
+ endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ # FreeBSD default compiler
+ CC = clang
+ endif
+endif
+ifeq ($(PLATFORM),PLATFORM_RPI)
+ ifeq ($(USE_RPI_CROSS_COMPILER),TRUE)
+ # Define RPI cross-compiler
+ #CC = armv6j-hardfloat-linux-gnueabi-gcc
+ CC = $(RPI_TOOLCHAIN)/bin/arm-linux-gnueabihf-gcc
+ endif
+endif
+ifeq ($(PLATFORM),PLATFORM_WEB)
+ # HTML5 emscripten compiler
+ CC = emcc
+endif
+
+# Define default make program: Mingw32-make
+MAKE = mingw32-make
+
+ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ ifeq ($(PLATFORM_OS),LINUX)
+ MAKE = make
+ endif
+endif
+
+# Define compiler flags:
+# -O1 defines optimization level
+# -g enable debugging
+# -s strip unnecessary data from build
+# -Wall turns on most, but not all, compiler warnings
+# -std=c99 defines C language mode (standard C from 1999 revision)
+# -std=gnu99 defines C language mode (GNU C from 1999 revision)
+# -Wno-missing-braces ignore invalid warning (GCC bug 53119)
+# -D_DEFAULT_SOURCE use with -std=c99 on Linux and PLATFORM_WEB, required for timespec
+CFLAGS += -O1 -s -Wall -std=c99 -D_DEFAULT_SOURCE -Wno-missing-braces
+
+# Additional flags for compiler (if desired)
+#CFLAGS += -Wextra -Wmissing-prototypes -Wstrict-prototypes
+ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ ifeq ($(PLATFORM_OS),WINDOWS)
+ # resources file contains windows exe icon
+ # -Wl,--subsystem,windows hides the console window
+ CFLAGS += $(RAYLIB_PATH)/src/resources -Wl,--subsystem,windows
+ endif
+ ifeq ($(PLATFORM_OS),LINUX)
+ CFLAGS += -no-pie -D_DEFAULT_SOURCE
+ endif
+endif
+ifeq ($(PLATFORM),PLATFORM_RPI)
+ CFLAGS += -std=gnu99
+endif
+ifeq ($(PLATFORM),PLATFORM_WEB)
+ # -O2 # if used, also set --memory-init-file 0
+ # --memory-init-file 0 # to avoid an external memory initialization code file (.mem)
+ # -s ALLOW_MEMORY_GROWTH=1 # to allow memory resizing
+ # -s TOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB)
+ # -s USE_PTHREADS=1 # multithreading support
+ # -s WASM=1 # support Web Assembly (https://github.com/kripken/emscripten/wiki/WebAssembly)
+ # --preload-file resources # specify a resources folder for data compilation
+ CFLAGS += -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 --profiling --preload-file resources -s TOTAL_MEMORY=67108864
+
+ # Define a custom shell .html and output extension
+ CFLAGS += --shell-file $(RAYLIB_PATH)\templates\web_shell\shell.html
+ EXT = .html
+endif
+
+# Define include paths for required headers
+# NOTE: Several external required libraries (stb and others)
+INCLUDE_PATHS = -I. -I$(RAYLIB_PATH)/release/include -I$(RAYLIB_PATH)/src -I$(RAYLIB_PATH)/src/external
+
+# Define additional directories containing required header files
+ifeq ($(PLATFORM),PLATFORM_RPI)
+ # RPI requried libraries
+ INCLUDE_PATHS += -I/opt/vc/include
+ INCLUDE_PATHS += -I/opt/vc/include/interface/vmcs_host/linux
+ INCLUDE_PATHS += -I/opt/vc/include/interface/vcos/pthreads
+endif
+
+# Define library paths containing required libs
+LDFLAGS = -L. -L$(RAYLIB_RELEASE_PATH) -L$(RAYLIB_PATH)/src
+
+ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ INCLUDE_PATHS += -I/usr/local/include
+ LDFLAGS += -L. -Lsrc -L/usr/local/lib
+ endif
+endif
+
+ifeq ($(PLATFORM),PLATFORM_RPI)
+ LDFLAGS += -L/opt/vc/lib
+endif
+
+# Define any libraries required on linking
+# if you want to link libraries (libname.so or libname.a), use the -lname
+ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ ifeq ($(PLATFORM_OS),WINDOWS)
+ # Libraries for Windows desktop compilation
+ LDLIBS = -lraylib -lopengl32 -lgdi32
+ endif
+ ifeq ($(PLATFORM_OS),LINUX)
+ # Libraries for Debian GNU/Linux desktop compiling
+ # NOTE: Required packages: libegl1-mesa-dev
+ LDLIBS = -lraylib -lGL -lm -lpthread -ldl -lrt
+
+ # On X11 requires also below libraries
+ LDLIBS += -lX11
+ # NOTE: It seems additional libraries are not required any more, latest GLFW just dlopen them
+ #LDLIBS += -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
+
+ # On Wayland windowing system, additional libraries requires
+ ifeq ($(USE_WAYLAND_DISPLAY),TRUE)
+ LDLIBS += -lwayland-client -lwayland-cursor -lwayland-egl -lxkbcommon
+ endif
+ endif
+ ifeq ($(PLATFORM_OS),OSX)
+ # Libraries for OSX 10.9 desktop compiling
+ # NOTE: Required packages: libopenal-dev libegl1-mesa-dev
+ LDLIBS = -lraylib -framework OpenGL -framework OpenAL -framework Cocoa
+ endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ # Libraries for FreeBSD desktop compiling
+ # NOTE: Required packages: mesa-libs
+ LDLIBS = -lraylib -lGL -lpthread -lm
+
+ # On XWindow requires also below libraries
+ LDLIBS += -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
+ endif
+ ifeq ($(USE_EXTERNAL_GLFW),TRUE)
+ # NOTE: It could require additional packages installed: libglfw3-dev
+ LDLIBS += -lglfw
+ endif
+endif
+ifeq ($(PLATFORM),PLATFORM_RPI)
+ # Libraries for Raspberry Pi compiling
+ # NOTE: Required packages: libasound2-dev (ALSA)
+ LDLIBS = -lraylib -lbrcmGLESv2 -lbrcmEGL -lpthread -lrt -lm -lbcm_host -ldl
+endif
+ifeq ($(PLATFORM),PLATFORM_WEB)
+ # Libraries for web (HTML5) compiling
+ LDLIBS = $(RAYLIB_RELEASE_PATH)/libraylib.bc
+endif
+
+# Define all source files required
+PROJECT_SOURCE_FILES ?= transmission.c \
+ screens/screen_logo.c \
+ screens/screen_title.c \
+ screens/screen_mission.c \
+ screens/screen_gameplay.c \
+ screens/screen_ending.c
+
+# Define all object files from source files
+OBJS = $(patsubst %.c, %.o, $(PROJECT_SOURCE_FILES))
+
+# For Android platform we call a custom Makefile.Android
+ifeq ($(PLATFORM),PLATFORM_ANDROID)
+ MAKEFILE_PARAMS = -f Makefile.Android
+ export PROJECT_NAME
+ export PROJECT_SOURCE_FILES
+else
+ MAKEFILE_PARAMS = $(PROJECT_NAME)
+endif
+
+# Default target entry
+# NOTE: We call this Makefile target or Makefile.Android target
+all:
+ $(MAKE) $(MAKEFILE_PARAMS)
+
+# Project target defined by PROJECT_NAME
+$(PROJECT_NAME): $(OBJS)
+ $(CC) -o $(PROJECT_NAME)$(EXT) $(OBJS) $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+
+# Compile source files
+# NOTE: This pattern will compile every module defined on $(OBJS)
+%.o: %.c
+ $(CC) -c $< -o $@ $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM)
+
+# Clean everything
+clean:
+ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ ifeq ($(PLATFORM_OS),WINDOWS)
+ del *.o *.exe /s
+ endif
+ ifeq ($(PLATFORM_OS),LINUX)
+ find -type f -executable | xargs file -i | grep -E 'x-object|x-archive|x-sharedlib|x-executable' | rev | cut -d ':' -f 2- | rev | xargs rm -f
+ endif
+ ifeq ($(PLATFORM_OS),OSX)
+ find . -type f -perm +ugo+x -delete
+ rm -f *.o
+ endif
+endif
+ifeq ($(PLATFORM),PLATFORM_RPI)
+ find . -type f -executable -delete
+ rm -f *.o
+endif
+ifeq ($(PLATFORM),PLATFORM_WEB)
+ del *.o *.html *.js
+endif
+ @echo Cleaning done
+
diff --git a/games/transmission/Makefile.Android b/games/transmission/Makefile.Android
new file mode 100644
index 000000000..f082ab230
--- /dev/null
+++ b/games/transmission/Makefile.Android
@@ -0,0 +1,275 @@
+#**************************************************************************************************
+#
+# raylib makefile for Android project (APK building)
+#
+# Copyright (c) 2017 Ramon Santamaria (@raysan5)
+#
+# This software is provided "as-is", without any express or implied warranty. In no event
+# will the authors be held liable for any damages arising from the use of this software.
+#
+# Permission is granted to anyone to use this software for any purpose, including commercial
+# applications, and to alter it and redistribute it freely, subject to the following restrictions:
+#
+# 1. The origin of this software must not be misrepresented; you must not claim that you
+# wrote the original software. If you use this software in a product, an acknowledgment
+# in the product documentation would be appreciated but is not required.
+#
+# 2. Altered source versions must be plainly marked as such, and must not be misrepresented
+# as being the original software.
+#
+# 3. This notice may not be removed or altered from any source distribution.
+#
+#**************************************************************************************************
+
+# Define required raylib variables
+PLATFORM ?= PLATFORM_ANDROID
+RAYLIB_PATH ?= ..\..
+
+# Required path variables
+# NOTE: JAVA_HOME must be set to JDK
+ANDROID_HOME = C:/android-sdk
+ANDROID_NDK = C:/android-ndk
+ANDROID_TOOLCHAIN = C:/android_toolchain_arm_api16
+ANDROID_BUILD_TOOLS = $(ANDROID_HOME)/build-tools/26.0.2
+ANDROID_PLATFORM_TOOLS = $(ANDROID_HOME)/platform-tools
+JAVA_HOME = C:/PROGRA~1/Java/jdk1.8.0_144
+
+# Android project configuration variables
+PROJECT_NAME ?= raylib_game
+PROJECT_LIBRARY_NAME ?= main
+PROJECT_BUILD_PATH ?= android.$(PROJECT_NAME)
+PROJECT_RESOURCES_PATH ?= resources
+PROJECT_SOURCE_FILES ?= raylib_game.c
+
+# Some source files are placed in directories, when compiling to some
+# output directory other than source, that directory must pre-exist.
+# Here we get a list of required folders that need to be created on
+# code output folder $(PROJECT_BUILD_PATH)\obj to avoid GCC errors.
+PROJECT_SOURCE_DIRS = $(sort $(dir $(PROJECT_SOURCE_FILES)))
+
+# Android app configuration variables
+APP_LABEL_NAME ?= rGame
+APP_COMPANY_NAME ?= raylib
+APP_PRODUCT_NAME ?= rgame
+APP_VERSION_CODE ?= 1
+APP_VERSION_NAME ?= 1.0
+APP_ICON_LDPI ?= $(RAYLIB_PATH)\logo\raylib_36x36.png
+APP_ICON_MDPI ?= $(RAYLIB_PATH)\logo\raylib_48x48.png
+APP_ICON_HDPI ?= $(RAYLIB_PATH)\logo\raylib_72x72.png
+APP_SCREEN_ORIENTATION ?= landscape
+APP_KEYSTORE_PASS ?= raylib
+
+# Library type used for raylib: STATIC (.a) or SHARED (.so/.dll)
+RAYLIB_LIBTYPE ?= STATIC
+RAYLIB_LIB_PATH = $(RAYLIB_PATH)\release\libs\android\armeabi-v7a
+
+# Shared libs must be added to APK if required
+# NOTE: Generated NativeLoader.java automatically load those libraries
+ifeq ($(RAYLIB_LIBTYPE),SHARED)
+ PROJECT_SHARED_LIBS = lib/armeabi-v7a/libraylib.so
+endif
+
+# Compiler and archiver
+# NOTE: GCC is being deprectated in Android NDK r16
+CC = $(ANDROID_TOOLCHAIN)/bin/arm-linux-androideabi-gcc
+AR = $(ANDROID_TOOLCHAIN)/bin/arm-linux-androideabi-ar
+
+# Compiler flags for arquitecture
+CFLAGS = -std=c99 -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16
+# Compilation functions attributes options
+CFLAGS += -ffunction-sections -funwind-tables -fstack-protector-strong -fPIC
+# Compiler options for the linker
+CFLAGS += -Wall -Wa,--noexecstack -Wformat -Werror=format-security -no-canonical-prefixes
+# Preprocessor macro definitions
+CFLAGS += -DANDROID -DPLATFORM_ANDROID -D__ANDROID_API__=16
+
+# Paths containing required header files
+INCLUDE_PATHS = -I. -I$(RAYLIB_PATH)/release/include -I$(RAYLIB_PATH)/src/external/android/native_app_glue
+
+# Linker options
+LDFLAGS = -Wl,-soname,lib$(PROJECT_LIBRARY_NAME).so -Wl,--exclude-libs,libatomic.a
+LDFLAGS += -Wl,--build-id -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel -Wl,--fatal-warnings
+# Force linking of library module to define symbol
+LDFLAGS += -u ANativeActivity_onCreate
+# Library paths containing required libs
+LDFLAGS += -L. -L$(PROJECT_BUILD_PATH)/obj -L$(PROJECT_BUILD_PATH)/lib/armeabi-v7a
+
+# Define any libraries to link into executable
+# if you want to link libraries (libname.so or libname.a), use the -lname
+LDLIBS = -lraylib -lnative_app_glue -llog -landroid -lEGL -lGLESv2 -lOpenSLES -latomic -lc -lm -ldl
+
+# Generate target objects list from PROJECT_SOURCE_FILES
+OBJS = $(patsubst %.c, $(PROJECT_BUILD_PATH)/obj/%.o, $(PROJECT_SOURCE_FILES))
+
+# Android APK building process... some steps required...
+# NOTE: typing 'make' will invoke the default target entry called 'all',
+all: create_temp_project_dirs \
+ copy_project_required_libs \
+ copy_project_resources \
+ generate_loader_script \
+ generate_android_manifest \
+ generate_apk_keystore \
+ config_project_package \
+ compile_native_app_glue \
+ compile_project_code \
+ compile_project_class \
+ compile_project_class_dex \
+ create_project_apk_package \
+ sign_project_apk_package \
+ zipalign_project_apk_package
+
+# Create required temp directories for APK building
+create_temp_project_dirs:
+ if not exist $(PROJECT_BUILD_PATH) mkdir $(PROJECT_BUILD_PATH)
+ if not exist $(PROJECT_BUILD_PATH)\obj mkdir $(PROJECT_BUILD_PATH)\obj
+ if not exist $(PROJECT_BUILD_PATH)\src mkdir $(PROJECT_BUILD_PATH)\src
+ if not exist $(PROJECT_BUILD_PATH)\src\com mkdir $(PROJECT_BUILD_PATH)\src\com
+ if not exist $(PROJECT_BUILD_PATH)\src\com\$(APP_COMPANY_NAME) mkdir $(PROJECT_BUILD_PATH)\src\com\$(APP_COMPANY_NAME)
+ if not exist $(PROJECT_BUILD_PATH)\src\com\$(APP_COMPANY_NAME)\$(APP_PRODUCT_NAME) mkdir $(PROJECT_BUILD_PATH)\src\com\$(APP_COMPANY_NAME)\$(APP_PRODUCT_NAME)
+ if not exist $(PROJECT_BUILD_PATH)\lib mkdir $(PROJECT_BUILD_PATH)\lib
+ if not exist $(PROJECT_BUILD_PATH)\lib\armeabi-v7a mkdir $(PROJECT_BUILD_PATH)\lib\armeabi-v7a
+ if not exist $(PROJECT_BUILD_PATH)\bin mkdir $(PROJECT_BUILD_PATH)\bin
+ if not exist $(PROJECT_BUILD_PATH)\res mkdir $(PROJECT_BUILD_PATH)\res
+ if not exist $(PROJECT_BUILD_PATH)\res\drawable-ldpi mkdir $(PROJECT_BUILD_PATH)\res\drawable-ldpi
+ if not exist $(PROJECT_BUILD_PATH)\res\drawable-mdpi mkdir $(PROJECT_BUILD_PATH)\res\drawable-mdpi
+ if not exist $(PROJECT_BUILD_PATH)\res\drawable-hdpi mkdir $(PROJECT_BUILD_PATH)\res\drawable-hdpi
+ if not exist $(PROJECT_BUILD_PATH)\res\values mkdir $(PROJECT_BUILD_PATH)\res\values
+ if not exist $(PROJECT_BUILD_PATH)\assets mkdir $(PROJECT_BUILD_PATH)\assets
+ if not exist $(PROJECT_BUILD_PATH)\assets\$(PROJECT_RESOURCES_PATH) mkdir $(PROJECT_BUILD_PATH)\assets\$(PROJECT_RESOURCES_PATH)
+ if not exist $(PROJECT_BUILD_PATH)\obj\screens mkdir $(PROJECT_BUILD_PATH)\obj\screens
+ $(foreach dir, $(PROJECT_SOURCE_DIRS), $(call create_dir, $(dir)))
+
+define create_dir
+ if not exist $(PROJECT_BUILD_PATH)\obj\$(1) mkdir $(PROJECT_BUILD_PATH)\obj\$(1)
+endef
+
+# Copy required shared libs for integration into APK
+# NOTE: If using shared libs they are loaded by generated NativeLoader.java
+copy_project_required_libs:
+ifeq ($(RAYLIB_LIBTYPE),SHARED)
+ copy /Y $(RAYLIB_LIB_PATH)\libraylib.so $(PROJECT_BUILD_PATH)\lib\armeabi-v7a\libraylib.so
+endif
+ifeq ($(RAYLIB_LIBTYPE),STATIC)
+ copy /Y $(RAYLIB_LIB_PATH)\libraylib.a $(PROJECT_BUILD_PATH)\lib\armeabi-v7a\libraylib.a
+endif
+
+# Copy project required resources: strings.xml, icon.png, assets
+# NOTE: Required strings.xml is generated and game resources are copied to assets folder
+# TODO: Review xcopy usage, it can not be found in some systems!
+copy_project_resources:
+ copy $(APP_ICON_LDPI) $(PROJECT_BUILD_PATH)\res\drawable-ldpi\icon.png /Y
+ copy $(APP_ICON_MDPI) $(PROJECT_BUILD_PATH)\res\drawable-mdpi\icon.png /Y
+ copy $(APP_ICON_HDPI) $(PROJECT_BUILD_PATH)\res\drawable-hdpi\icon.png /Y
+ @echo ^ > $(PROJECT_BUILD_PATH)/res/values/strings.xml
+ @echo ^^$(APP_LABEL_NAME)^^ >> $(PROJECT_BUILD_PATH)/res/values/strings.xml
+ if exist $(PROJECT_RESOURCES_PATH) C:\Windows\System32\xcopy $(PROJECT_RESOURCES_PATH) $(PROJECT_BUILD_PATH)\assets\$(PROJECT_RESOURCES_PATH) /Y /E /F
+
+# Generate NativeLoader.java to load required shared libraries
+# NOTE: Probably not the bet way to generate this file... but it works.
+generate_loader_script:
+ @echo package com.$(APP_COMPANY_NAME).$(APP_PRODUCT_NAME); > $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
+ @echo. >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
+ @echo public class NativeLoader extends android.app.NativeActivity { >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
+ @echo static { >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
+ifeq ($(RAYLIB_LIBTYPE),SHARED)
+ @echo System.loadLibrary("raylib"); >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
+endif
+ @echo System.loadLibrary("$(PROJECT_LIBRARY_NAME)"); >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
+ @echo } >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
+ @echo } >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
+
+# Generate AndroidManifest.xml with all the required options
+# NOTE: Probably not the bet way to generate this file... but it works.
+generate_android_manifest:
+ @echo ^ > $(PROJECT_BUILD_PATH)/AndroidManifest.xml
+ @echo ^> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
+ @echo package="com.$(APP_COMPANY_NAME).$(APP_PRODUCT_NAME)" >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
+ @echo android:versionCode="$(APP_VERSION_CODE)" android:versionName="$(APP_VERSION_NAME)" ^> >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
+ @echo ^ >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
+ @echo ^ >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
+ @echo ^ >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
+ @echo ^> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
+ @echo android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
+ @echo android:configChanges="orientation|keyboardHidden|screenSize" >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
+ @echo android:screenOrientation="$(APP_SCREEN_ORIENTATION)" android:launchMode="singleTask" >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
+ @echo android:clearTaskOnLaunch="true"^> >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
+ @echo ^ >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
+ @echo ^ >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
+ @echo ^ >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
+ @echo ^ >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
+ @echo ^ >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
+ @echo ^ >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
+ @echo ^ >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
+ @echo ^ >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
+
+# Generate storekey for APK signing: $(PROJECT_NAME).keystore
+# NOTE: Configure here your Distinguished Names (-dname) if required!
+generate_apk_keystore:
+ if not exist $(PROJECT_BUILD_PATH)/$(PROJECT_NAME).keystore $(JAVA_HOME)/bin/keytool -genkeypair -validity 1000 -dname "CN=$(APP_COMPANY_NAME),O=Android,C=ES" -keystore $(PROJECT_BUILD_PATH)/$(PROJECT_NAME).keystore -storepass $(APP_KEYSTORE_PASS) -keypass $(APP_KEYSTORE_PASS) -alias $(PROJECT_NAME)Key -keyalg RSA
+
+# Config project package and resource using AndroidManifest.xml and res/values/strings.xml
+# NOTE: Generates resources file: src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/R.java
+config_project_package:
+ $(ANDROID_BUILD_TOOLS)/aapt package -f -m -S $(PROJECT_BUILD_PATH)/res -J $(PROJECT_BUILD_PATH)/src -M $(PROJECT_BUILD_PATH)/AndroidManifest.xml -I $(ANDROID_HOME)/platforms/android-16/android.jar
+
+# Compile native_app_glue code as static library: obj/libnative_app_glue.a
+compile_native_app_glue:
+ $(CC) -c $(RAYLIB_PATH)/src/external/android/native_app_glue/android_native_app_glue.c -o $(PROJECT_BUILD_PATH)/obj/native_app_glue.o $(CFLAGS)
+ $(AR) rcs $(PROJECT_BUILD_PATH)/obj/libnative_app_glue.a $(PROJECT_BUILD_PATH)/obj/native_app_glue.o
+
+# Compile project code into a shared library: lib/lib$(PROJECT_LIBRARY_NAME).so
+compile_project_code: $(OBJS)
+ $(CC) -o $(PROJECT_BUILD_PATH)/lib/armeabi-v7a/lib$(PROJECT_LIBRARY_NAME).so $(OBJS) -shared $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS)
+
+# Compile all .c files required into object (.o) files
+# NOTE: Those files will be linked into a shared library
+$(PROJECT_BUILD_PATH)/obj/%.o:%.c
+ $(CC) -c $^ -o $@ $(INCLUDE_PATHS) $(CFLAGS) --sysroot=$(ANDROID_TOOLCHAIN)/sysroot
+
+# Compile project .java code into .class (Java bytecode)
+compile_project_class:
+ $(JAVA_HOME)/bin/javac -verbose -source 1.7 -target 1.7 -d $(PROJECT_BUILD_PATH)/obj -bootclasspath $(JAVA_HOME)/jre/lib/rt.jar -classpath $(ANDROID_HOME)/platforms/android-16/android.jar;$(PROJECT_BUILD_PATH)/obj -sourcepath $(PROJECT_BUILD_PATH)/src $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/R.java $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
+
+# Compile .class files into Dalvik executable bytecode (.dex)
+# NOTE: Since Android 5.0, Dalvik interpreter (JIT) has been replaced by ART (AOT)
+compile_project_class_dex:
+ $(ANDROID_BUILD_TOOLS)/dx --verbose --dex --output=$(PROJECT_BUILD_PATH)/bin/classes.dex $(PROJECT_BUILD_PATH)/obj
+
+# Create Android APK package: bin/$(PROJECT_NAME).unsigned.apk
+# NOTE: Requires compiled classes.dex and lib$(PROJECT_LIBRARY_NAME).so
+# NOTE: Use -A resources to define additional directory in which to find raw asset files
+create_project_apk_package:
+ $(ANDROID_BUILD_TOOLS)/aapt package -f -M $(PROJECT_BUILD_PATH)/AndroidManifest.xml -S $(PROJECT_BUILD_PATH)/res -A $(PROJECT_BUILD_PATH)/assets -I $(ANDROID_HOME)/platforms/android-16/android.jar -F $(PROJECT_BUILD_PATH)/bin/$(PROJECT_NAME).unsigned.apk $(PROJECT_BUILD_PATH)/bin
+ cd $(PROJECT_BUILD_PATH) && $(ANDROID_BUILD_TOOLS)/aapt add bin/$(PROJECT_NAME).unsigned.apk lib/armeabi-v7a/lib$(PROJECT_LIBRARY_NAME).so $(PROJECT_SHARED_LIBS)
+
+# Create signed APK package using generated Key: bin/$(PROJECT_NAME).signed.apk
+sign_project_apk_package:
+ $(JAVA_HOME)/bin/jarsigner -keystore $(PROJECT_BUILD_PATH)/$(PROJECT_NAME).keystore -storepass $(APP_KEYSTORE_PASS) -keypass $(APP_KEYSTORE_PASS) -signedjar $(PROJECT_BUILD_PATH)/bin/$(PROJECT_NAME).signed.apk $(PROJECT_BUILD_PATH)/bin/$(PROJECT_NAME).unsigned.apk $(PROJECT_NAME)Key
+
+# Create zip-aligned APK package: $(PROJECT_NAME).apk
+zipalign_project_apk_package:
+ $(ANDROID_BUILD_TOOLS)/zipalign -f 4 $(PROJECT_BUILD_PATH)/bin/$(PROJECT_NAME).signed.apk $(PROJECT_NAME).apk
+
+# Install $(PROJECT_NAME).apk to default emulator/device
+# NOTE: Use -e (emulator) or -d (device) parameters if required
+install:
+ $(ANDROID_PLATFORM_TOOLS)/adb install -r $(PROJECT_NAME).apk
+
+# Monitorize output log coming from device, only raylib tag
+logcat:
+ $(ANDROID_PLATFORM_TOOLS)/adb logcat -c
+ $(ANDROID_PLATFORM_TOOLS)/adb logcat raylib:V *:S
+
+# Install and monitorize $(PROJECT_NAME).apk to default emulator/device
+deploy:
+ $(ANDROID_PLATFORM_TOOLS)/adb install -r $(PROJECT_NAME).apk
+ $(ANDROID_PLATFORM_TOOLS)/adb logcat -c
+ $(ANDROID_PLATFORM_TOOLS)/adb logcat raylib:V *:S
+
+#$(ANDROID_PLATFORM_TOOLS)/adb logcat *:W
+
+# Clean everything
+clean:
+ del $(PROJECT_BUILD_PATH)\* /f /s /q
+ rmdir $(PROJECT_BUILD_PATH) /s /q
+ @echo Cleaning done
diff --git a/games/transmission/resources/audio/fx_batman.ogg b/games/transmission/resources/audio/fx_batman.ogg
new file mode 100644
index 000000000..d3e25ae29
Binary files /dev/null and b/games/transmission/resources/audio/fx_batman.ogg differ
diff --git a/games/transmission/resources/audio/fx_button.ogg b/games/transmission/resources/audio/fx_button.ogg
new file mode 100644
index 000000000..8d0747cad
Binary files /dev/null and b/games/transmission/resources/audio/fx_button.ogg differ
diff --git a/games/transmission/resources/audio/fx_grab.ogg b/games/transmission/resources/audio/fx_grab.ogg
new file mode 100644
index 000000000..b78e13157
Binary files /dev/null and b/games/transmission/resources/audio/fx_grab.ogg differ
diff --git a/games/transmission/resources/audio/fx_leave.ogg b/games/transmission/resources/audio/fx_leave.ogg
new file mode 100644
index 000000000..24abdbeef
Binary files /dev/null and b/games/transmission/resources/audio/fx_leave.ogg differ
diff --git a/games/transmission/resources/audio/fx_message.ogg b/games/transmission/resources/audio/fx_message.ogg
new file mode 100644
index 000000000..60de66552
Binary files /dev/null and b/games/transmission/resources/audio/fx_message.ogg differ
diff --git a/games/transmission/resources/audio/fx_newspaper.ogg b/games/transmission/resources/audio/fx_newspaper.ogg
new file mode 100644
index 000000000..bcc548418
Binary files /dev/null and b/games/transmission/resources/audio/fx_newspaper.ogg differ
diff --git a/games/transmission/resources/audio/fx_place.ogg b/games/transmission/resources/audio/fx_place.ogg
new file mode 100644
index 000000000..a300a9683
Binary files /dev/null and b/games/transmission/resources/audio/fx_place.ogg differ
diff --git a/games/transmission/resources/audio/fx_typing.ogg b/games/transmission/resources/audio/fx_typing.ogg
new file mode 100644
index 000000000..89a09dafc
Binary files /dev/null and b/games/transmission/resources/audio/fx_typing.ogg differ
diff --git a/games/transmission/resources/audio/music_mission.ogg b/games/transmission/resources/audio/music_mission.ogg
new file mode 100644
index 000000000..2de719bbc
Binary files /dev/null and b/games/transmission/resources/audio/music_mission.ogg differ
diff --git a/games/transmission/resources/audio/music_title.ogg b/games/transmission/resources/audio/music_title.ogg
new file mode 100644
index 000000000..d75b1ddc8
Binary files /dev/null and b/games/transmission/resources/audio/music_title.ogg differ
diff --git a/games/transmission/resources/audio/s_p_y.xm b/games/transmission/resources/audio/s_p_y.xm
new file mode 100644
index 000000000..ebbdbf93d
Binary files /dev/null and b/games/transmission/resources/audio/s_p_y.xm differ
diff --git a/games/transmission/resources/audio/spy_versus_spy.xm b/games/transmission/resources/audio/spy_versus_spy.xm
new file mode 100644
index 000000000..11602adc4
Binary files /dev/null and b/games/transmission/resources/audio/spy_versus_spy.xm differ
diff --git a/games/transmission/resources/fonts/Lora-Bold.ttf b/games/transmission/resources/fonts/Lora-Bold.ttf
new file mode 100644
index 000000000..e48c4262e
Binary files /dev/null and b/games/transmission/resources/fonts/Lora-Bold.ttf differ
diff --git a/games/transmission/resources/fonts/mom_typewritter.ttf b/games/transmission/resources/fonts/mom_typewritter.ttf
new file mode 100644
index 000000000..13f5dc7dd
Binary files /dev/null and b/games/transmission/resources/fonts/mom_typewritter.ttf differ
diff --git a/games/transmission/resources/fonts/traveling_typewriter.ttf b/games/transmission/resources/fonts/traveling_typewriter.ttf
new file mode 100644
index 000000000..5d9d7c9ba
Binary files /dev/null and b/games/transmission/resources/fonts/traveling_typewriter.ttf differ
diff --git a/games/transmission/resources/missions.txt b/games/transmission/resources/missions.txt
new file mode 100644
index 000000000..635696081
--- /dev/null
+++ b/games/transmission/resources/missions.txt
@@ -0,0 +1,65 @@
+# Total missions
+# NOTE: Missions follow the order of this file
+t 4
+# -----------------------------------------------------------------
+# Briefing of the mission
+b Se ha visto al Presidente en actitud cariñosa con una persona que no es la Primera Dama. Una situación comprometida que definirá el curso de la historia... Especialmente en campaña electoral y siendo del partido conservador... ¡El pueblo debe saber!
+#
+# Mission keyword
+k oviparo
+#
+# Message to be coded
+# NOTE: Sensible words must be noted using @
+m El @presidente es visto en un @hotel acompañado de su @amante.
+#
+# Solution to mission
+# NOTE: Provide the correct solution nums, according to above words
+# WARNING: Always provide 8 values, use -1 for not used ones
+# Coding Words: POLLO = 0, CONEJO, HUEVO, NIDO, AIRE, ARMARIO, AGUJERO, PLATANO, PASTEL, MERCADO, RATON, MELON
+s 0 3 2 -1 -1 -1 -1 -1
+# -----------------------------------------------------------------
+# Briefing of the mission
+b Se ha visto un ovni sobrevolando la ciudad, al parecer se prevee un ataque alienÃgena inminente que definirá el curso de la historia... ¡El pueblo debe saber!
+#
+# Mission keyword
+k roedor
+#
+# Message to be coded
+# NOTE: Sensible words must be noted using @
+m Un @ovni ha sido detectado en el @cielo del @pais . Preparaos para el ataque de un @alien.
+#
+# NOTE: Provide the correct solution nums, according to above words
+# WARNING: Always provide 8 values, use -1 for not used ones
+# Coding Words: POLLO = 0, CONEJO, HUEVO, NIDO, AIRE, ARMARIO, AGUJERO, PLATANO, PASTEL, MERCADO, RATON, MELON
+s 1 6 5 10 -1 -1 -1 -1
+# -----------------------------------------------------------------
+# Briefing of the mission
+b Se ha filtrado una inminente subida del precio de un producto básico para todo el mundo: el ajo. Le evolución de su precio de mercado definirá el curso de la historia... ¡El pueblo debe saber!
+#
+# Mission keyword
+k comida
+#
+# Message to be coded
+# NOTE: Sensible words must be noted using @
+m Sube el @precio del @ajo. ¡Un @desastre inminente!
+#
+# NOTE: Provide the correct solution nums, according to above words
+# WARNING: Always provide 8 values, use -1 for not used ones
+# Coding Words: POLLO = 0, CONEJO, HUEVO, NIDO, AIRE, ARMARIO, AGUJERO, PLATANO, PASTEL, MERCADO, RATON, MELON
+s 9 7 2 -1 -1 -1 -1 -1
+# -----------------------------------------------------------------
+# Briefing of the mission
+b Se ha visto a un famoso presentador de TV deshaciéndose del cuerpo de un rival de otra cadena. Una pérdida que definirá el curso de la historia... Especialmente cuando su programa podrÃa no continuar... ¡El pueblo debe saber!
+#
+# Mission keyword
+k postre
+#
+# Message to be coded
+# NOTE: Sensible words must be noted using @
+m Un @presentador se deshace del @cuerpo de su rival. ¡Peligra el @programa del Prime Time!
+#
+# NOTE: Provide the correct solution nums, according to above words
+# WARNING: Always provide 8 values, use -1 for not used ones
+# Coding Words: POLLO = 0, CONEJO, HUEVO, NIDO, AIRE, ARMARIO, AGUJERO, PLATANO, PASTEL, MERCADO, RATON, MELON
+s 7 11 8 -1 -1 -1 -1 -1
+# -----------------------------------------------------------------
\ No newline at end of file
diff --git a/games/transmission/resources/textures/cw_logo.png b/games/transmission/resources/textures/cw_logo.png
new file mode 100644
index 000000000..bc4011d84
Binary files /dev/null and b/games/transmission/resources/textures/cw_logo.png differ
diff --git a/games/transmission/resources/textures/ending_background.png b/games/transmission/resources/textures/ending_background.png
new file mode 100644
index 000000000..6577be63b
Binary files /dev/null and b/games/transmission/resources/textures/ending_background.png differ
diff --git a/games/transmission/resources/textures/ending_newspaper.png b/games/transmission/resources/textures/ending_newspaper.png
new file mode 100644
index 000000000..f44e646d4
Binary files /dev/null and b/games/transmission/resources/textures/ending_newspaper.png differ
diff --git a/games/transmission/resources/textures/message_background.png b/games/transmission/resources/textures/message_background.png
new file mode 100644
index 000000000..78c00a597
Binary files /dev/null and b/games/transmission/resources/textures/message_background.png differ
diff --git a/games/transmission/resources/textures/message_vignette.png b/games/transmission/resources/textures/message_vignette.png
new file mode 100644
index 000000000..72234c594
Binary files /dev/null and b/games/transmission/resources/textures/message_vignette.png differ
diff --git a/games/transmission/resources/textures/mission_background.png b/games/transmission/resources/textures/mission_background.png
new file mode 100644
index 000000000..4efe58155
Binary files /dev/null and b/games/transmission/resources/textures/mission_background.png differ
diff --git a/games/transmission/resources/textures/mission_backline.png b/games/transmission/resources/textures/mission_backline.png
new file mode 100644
index 000000000..2a89d80a6
Binary files /dev/null and b/games/transmission/resources/textures/mission_backline.png differ
diff --git a/games/transmission/resources/textures/mission_words.png b/games/transmission/resources/textures/mission_words.png
new file mode 100644
index 000000000..4e4e9d936
Binary files /dev/null and b/games/transmission/resources/textures/mission_words.png differ
diff --git a/games/transmission/resources/textures/title_background.png b/games/transmission/resources/textures/title_background.png
new file mode 100644
index 000000000..c90d880d5
Binary files /dev/null and b/games/transmission/resources/textures/title_background.png differ
diff --git a/games/transmission/resources/textures/title_ribbon.png b/games/transmission/resources/textures/title_ribbon.png
new file mode 100644
index 000000000..1526eba17
Binary files /dev/null and b/games/transmission/resources/textures/title_ribbon.png differ
diff --git a/games/transmission/resources/textures/words_base.png b/games/transmission/resources/textures/words_base.png
new file mode 100644
index 000000000..a21390301
Binary files /dev/null and b/games/transmission/resources/textures/words_base.png differ
diff --git a/games/transmission/screens/screen_ending.c b/games/transmission/screens/screen_ending.c
new file mode 100644
index 000000000..e6ab3518c
--- /dev/null
+++ b/games/transmission/screens/screen_ending.c
@@ -0,0 +1,248 @@
+/**********************************************************************************************
+*
+* raylib - Advance Game template
+*
+* Ending Screen Functions Definitions (Init, Update, Draw, Unload)
+*
+* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
+*
+* This software is provided "as-is", without any express or implied warranty. In no event
+* will the authors be held liable for any damages arising from the use of this software.
+*
+* Permission is granted to anyone to use this software for any purpose, including commercial
+* applications, and to alter it and redistribute it freely, subject to the following restrictions:
+*
+* 1. The origin of this software must not be misrepresented; you must not claim that you
+* wrote the original software. If you use this software in a product, an acknowledgment
+* in the product documentation would be appreciated but is not required.
+*
+* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
+* as being the original software.
+*
+* 3. This notice may not be removed or altered from any source distribution.
+*
+**********************************************************************************************/
+
+#include "raylib.h"
+#include "screens.h"
+
+#include
+#include
+
+#define MAX_TITLE_CHAR 256
+#define MAX_SUBTITLE_CHAR 256
+
+//----------------------------------------------------------------------------------
+// Global Variables Definition (local to this module)
+//----------------------------------------------------------------------------------
+static char *codingWords[MAX_CODING_WORDS] = {
+ "pollo\0",
+ "conejo\0",
+ "huevo\0",
+ "nido\0",
+ "aire\0",
+ "armario\0",
+ "agujero\0",
+ "platano\0",
+ "pastel\0",
+ "mercado\0",
+ "raton\0",
+ "melon\0",
+};
+
+// Ending screen global variables
+static int framesCounter;
+static int finishScreen;
+
+static Texture2D texBackground;
+static Texture2D texNewspaper;
+static Texture2D texVignette;
+
+static Sound fxNews;
+
+static float rotation = 0.1f;
+static float scale = 0.05f;
+static int state = 0;
+
+static Mission *missions = NULL;
+
+static char headline[MAX_TITLE_CHAR] = "\0";
+
+SpriteFont fontNews;
+
+// String (const char *) replacement function
+static char *StringReplace(char *orig, char *rep, char *with);
+
+//----------------------------------------------------------------------------------
+// Ending Screen Functions Definition
+//----------------------------------------------------------------------------------
+
+// Ending Screen Initialization logic
+void InitEndingScreen(void)
+{
+ framesCounter = 0;
+ finishScreen = 0;
+
+ rotation = 0.1f;
+ scale = 0.05f;
+ state = 0;
+
+ texBackground = LoadTexture("resources/textures/ending_background.png");
+ texVignette = LoadTexture("resources/textures/message_vignette.png");
+ fxNews = LoadSound("resources/audio/fx_batman.ogg");
+
+ missions = LoadMissions("resources/missions.txt");
+ int wordsCount = missions[currentMission].wordsCount;
+
+ strcpy(headline, missions[currentMission].msg); // Base headline
+ int len = strlen(headline);
+
+ // Remove @ from headline
+ // TODO: Also remove additional spaces
+ for (int i = 0; i < len; i++)
+ {
+ if (headline[i] == '@') headline[i] = ' ';
+ }
+
+ for (int i = 0; i < wordsCount; i++)
+ {
+ if (messageWords[i].id != missions[currentMission].sols[i])
+ {
+ // WARNING: It fails if the last sentence word has a '.' after space
+ char *title = StringReplace(headline, messageWords[i].text, codingWords[messageWords[i].id]);
+
+ strcpy(headline, title); // Base headline updated
+
+ if (title != NULL) free(title);
+ }
+ }
+
+ TraceLog(LOG_WARNING, "Titular: %s", headline);
+
+ // Generate newspaper with title and subtitle
+ Image imNewspaper = LoadImage("resources/textures/ending_newspaper.png");
+ fontNews = LoadSpriteFontEx("resources/fonts/Lora-Bold.ttf", 32, 250, 0);
+ ImageDrawTextEx(&imNewspaper, (Vector2){ 50, 220 }, fontNews, headline, fontNews.baseSize, 0, DARKGRAY);
+
+ texNewspaper = LoadTextureFromImage(imNewspaper);
+ //UnloadSpriteFont(fontNews);
+ UnloadImage(imNewspaper);
+}
+
+// Ending Screen Update logic
+void UpdateEndingScreen(void)
+{
+ framesCounter++;
+
+ if (framesCounter == 10) PlaySound(fxNews);
+
+ if (state == 0)
+ {
+ rotation += 18.0f;
+ scale += 0.0096f;
+
+ if (scale >= 1.0f)
+ {
+ scale = 1.0f;
+ state = 1;
+ }
+ }
+
+ if ((state == 1) && (IsKeyPressed(KEY_ENTER) || IsButtonPressed()))
+ {
+ currentMission++;
+
+ if (currentMission >= totalMissions) finishScreen = 2;
+ else finishScreen = 1;
+ }
+}
+
+// Ending Screen Draw logic
+void DrawEndingScreen(void)
+{
+ DrawTexture(texBackground, 0, 0, WHITE);
+
+ DrawTexturePro(texNewspaper, (Rectangle){ 0, 0, texNewspaper.width, texNewspaper.height },
+ (Rectangle){ GetScreenWidth()/2, GetScreenHeight()/2, texNewspaper.width*scale, texNewspaper.height*scale },
+ (Vector2){ (float)texNewspaper.width*scale/2, (float)texNewspaper.height*scale/2 }, rotation, WHITE);
+
+ DrawTextureEx(texVignette, (Vector2){ 0, 0 }, 0.0f, 2.0f, WHITE);
+
+ // Draw debug information
+ DrawTextEx(fontNews, headline, (Vector2){ 10, 10 }, fontNews.baseSize, 0, RAYWHITE);
+
+ for (int i = 0; i < missions[currentMission].wordsCount; i++)
+ {
+ DrawText(codingWords[messageWords[i].id], 10, 60 + 30*i, 20, (messageWords[i].id == missions[currentMission].sols[i]) ? GREEN : RED);
+ }
+
+ if (state == 1) DrawButton("continuar");
+}
+
+// Ending Screen Unload logic
+void UnloadEndingScreen(void)
+{
+ UnloadTexture(texBackground);
+ UnloadTexture(texNewspaper);
+ UnloadTexture(texVignette);
+
+ UnloadSound(fxNews);
+ free(missions);
+}
+
+// Ending Screen should finish?
+int FinishEndingScreen(void)
+{
+ return finishScreen;
+}
+
+// String (const char *) replacement function
+// NOTE: Internally allocated memory must be freed by the user (if return != NULL)
+// https://stackoverflow.com/questions/779875/what-is-the-function-to-replace-string-in-c
+static char *StringReplace(char *orig, char *rep, char *with)
+{
+ char *result; // the return string
+ char *ins; // the next insert point
+ char *tmp; // varies
+ int len_rep; // length of rep (the string to remove)
+ int len_with; // length of with (the string to replace rep with)
+ int len_front; // distance between rep and end of last rep
+ int count; // number of replacements
+
+ // Sanity checks and initialization
+ if (!orig || !rep) return NULL;
+
+ len_rep = strlen(rep);
+ if (len_rep == 0) return NULL; // Empty rep causes infinite loop during count
+
+ if (!with) with = ""; // Replace with nothing if not provided
+ len_with = strlen(with);
+
+ // Count the number of replacements needed
+ ins = orig;
+ for (count = 0; tmp = strstr(ins, rep); ++count)
+ {
+ ins = tmp + len_rep;
+ }
+
+ tmp = result = malloc(strlen(orig) + (len_with - len_rep)*count + 1);
+
+ if (!result) return NULL; // Memory could not be allocated
+
+ // First time through the loop, all the variable are set correctly from here on,
+ // tmp points to the end of the result string
+ // ins points to the next occurrence of rep in orig
+ // orig points to the remainder of orig after "end of rep"
+ while (count--)
+ {
+ ins = strstr(orig, rep);
+ len_front = ins - orig;
+ tmp = strncpy(tmp, orig, len_front) + len_front;
+ tmp = strcpy(tmp, with) + len_with;
+ orig += len_front + len_rep; // move to next "end of rep"
+ }
+
+ strcpy(tmp, orig);
+
+ return result;
+}
diff --git a/games/transmission/screens/screen_gameplay.c b/games/transmission/screens/screen_gameplay.c
new file mode 100644
index 000000000..00c451fc8
--- /dev/null
+++ b/games/transmission/screens/screen_gameplay.c
@@ -0,0 +1,423 @@
+/**********************************************************************************************
+*
+* raylib - Advance Game template
+*
+* Gameplay Screen Functions Definitions (Init, Update, Draw, Unload)
+*
+* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
+*
+* This software is provided "as-is", without any express or implied warranty. In no event
+* will the authors be held liable for any damages arising from the use of this software.
+*
+* Permission is granted to anyone to use this software for any purpose, including commercial
+* applications, and to alter it and redistribute it freely, subject to the following restrictions:
+*
+* 1. The origin of this software must not be misrepresented; you must not claim that you
+* wrote the original software. If you use this software in a product, an acknowledgment
+* in the product documentation would be appreciated but is not required.
+*
+* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
+* as being the original software.
+*
+* 3. This notice may not be removed or altered from any source distribution.
+*
+**********************************************************************************************/
+
+#include "raylib.h"
+#include "screens.h"
+
+#include
+#include
+#include
+
+//#define MAX_CODING_WORDS 12
+//#define MAX_MISSION_WORDS 8
+#define MAX_LINE_CHAR 30
+
+/*
+// NOTE: Coding words are generic and the same words
+// are used for all missions,
+typedef enum CodingWords {
+ POLLO = 0,
+ CONEJO,
+ HUEVO,
+ NIDO,
+ AIRE,
+ ARMARIO,
+ AGUJERO,
+ COSA,
+ WORD,
+} CodingWords;
+*/
+
+static char *codingWords[MAX_CODING_WORDS] = {
+ "pollo\0",
+ "conejo\0",
+ "huevo\0",
+ "nido\0",
+ "aire\0",
+ "armario\0",
+ "agujero\0",
+ "platano\0",
+ "pastel\0",
+ "mercado\0",
+ "raton\0",
+ "melon\0"
+};
+
+// Words to be coded or coding words
+/*typedef struct Word {
+ int id;
+ Rectangle rec;
+ Rectangle iniRec;
+ bool hover;
+ bool picked;
+ char text[32]; // text
+} Word;*/
+
+/*
+// Mission information
+typedef struct Mission {
+ int id;
+ char brief[512]; // Mission briefing
+ char key[32]; // Mission keyword
+ char msg[256]; // Message to be coded
+ int wordsCount; // Number of words to coded
+ int sols[8]; // Solution code, depends on wordsCount
+} Mission;
+*/
+//----------------------------------------------------------------------------------
+// Global Variables Definition (local to this module)
+//----------------------------------------------------------------------------------
+
+// Gameplay screen global variables
+static int framesCounter;
+static int finishScreen;
+
+static Texture2D texBackground;
+static SpriteFont fontMessage;
+static Texture2D texWordsAtlas;
+static Texture2D texVignette;
+
+static Sound fxGrab;
+static Sound fxPlace;
+static Sound fxLeave;
+
+static Music musSpy;
+
+static Word words[MAX_CODING_WORDS] = { 0 };
+
+// Hay que hacerlo global, para poder consultar el resultado desde la endingscreen
+//static Word messageWords[MAX_MISSION_WORDS] = { 0 };
+
+static Mission *missions = NULL;
+
+static bool canSend = false;
+
+Vector2 msgOffset = { 430, 300 };
+
+//----------------------------------------------------------------------------------
+// Gameplay Screen Functions Definition
+//----------------------------------------------------------------------------------
+
+// Gameplay Screen Initialization logic
+void InitGameplayScreen(void)
+{
+ framesCounter = 0;
+ finishScreen = 0;
+
+ fontMessage = LoadSpriteFontEx("resources/fonts/traveling_typewriter.ttf", 30, 250, 0);
+
+ texBackground = LoadTexture("resources/textures/message_background.png");
+ texVignette = LoadTexture("resources/textures/message_vignette.png");
+
+ fxGrab = LoadSound("resources/audio/fx_grab.ogg");
+ fxPlace = LoadSound("resources/audio/fx_place.ogg");
+ fxLeave = LoadSound("resources/audio/fx_leave.ogg");
+
+ musSpy = LoadMusicStream("resources/audio/s_p_y.xm");
+ PlayMusicStream(musSpy);
+
+#if defined(PLATFORM_WEB)
+ #define WORD_ATLAS_FROM_FILE
+#endif
+#if defined(WORD_ATLAS_FROM_FILE)
+ texWordsAtlas = LoadTexture("resources/textures/mission_words.png");
+#else
+ // Generate coding words atlas directly from text
+ Image imWordsBase = LoadImage("resources/textures/words_base.png");
+ Image imWords = GenImageColor(imWordsBase.width, imWordsBase.height*MAX_CODING_WORDS, WHITE);
+
+ for (int i = 0; i < MAX_CODING_WORDS; i++)
+ {
+ ImageDraw(&imWords, imWordsBase,
+ (Rectangle){ 0, 0, imWordsBase.width, imWordsBase.height },
+ (Rectangle){ 0, imWordsBase.height*i, imWordsBase.width, imWordsBase.height });
+
+ ImageDrawTextEx(&imWords,(Vector2){ imWordsBase.width/2 - MeasureTextEx(fontMessage, codingWords[i],
+ fontMessage.baseSize, 0).x/2, imWordsBase.height*i }, fontMessage, codingWords[i],
+ fontMessage.baseSize, 0, BLACK);
+ }
+
+ texWordsAtlas = LoadTextureFromImage(imWords);
+
+ UnloadImage(imWordsBase);
+ UnloadImage(imWords);
+#endif
+
+ // Initialize missions
+ // WARNING: Some problem with imWords image generation (memory leak?) could cause
+ // that loading missions before/after generation breaks game, on web is the other way round... :(
+ missions = LoadMissions("resources/missions.txt");
+ TraceLog(LOG_WARNING, "Words count %i", missions[currentMission].wordsCount);
+
+ // Initialize coding words
+ for (int i = 0; i < MAX_CODING_WORDS; i++)
+ {
+ words[i].id = -1; // Not placed anywhere
+
+ words[i].rec.x = 110 + 940*(i/(MAX_CODING_WORDS/2));
+ words[i].rec.y = 200 + 60*(i%(MAX_CODING_WORDS/2));
+ words[i].rec.width = 140; // texWordsAtlas.width/MAX_MISSIONS
+ words[i].rec.height = 35; // texWordsAtlas.height/MAX_MISSION_WORDS
+ words[i].iniRec = words[i].rec;
+ words[i].hover = false; // Mouse hover detected
+ words[i].picked = false; // Mouse picked
+
+ //words[i].text = ''; //codingWords[i]; // Fill text if required...
+ }
+
+ // Analize missions[currentMission].msg string for words!
+ int msgLen = strlen(missions[currentMission].msg);
+
+ // Add '/' each MAX_LINE_CHAR chars
+ int currentLine = 1;
+ int i = currentLine * MAX_LINE_CHAR;
+
+ while (i < msgLen - 1)
+ {
+ if (missions[currentMission].msg[i] == ' ')
+ {
+ missions[currentMission].msg[i] = '/';
+ currentLine++;
+ i = currentLine*MAX_LINE_CHAR;
+ }
+ else i++;
+ }
+
+ int currentWord = 0;
+ int offsetX = 0;
+ int offsetY = 0;
+ bool foundWord = false;
+ int wordInitPosX = 0;
+ int wordInitPosY = 0;
+
+ // TODO: messageWords should be reseted every mission
+ //memcpy(messageWords, 0, sizeof(Word)*MAX_MISSION_WORDS);
+
+ for (int i = 0; i < msgLen; i++)
+ {
+ char c = missions[currentMission].msg[i];
+ if (foundWord && (c == ' ' || c == '.'))
+ {
+ foundWord = false;
+
+ messageWords[currentWord - 1].rec.width = (int)MeasureTextEx(fontMessage, SubText(missions[currentMission].msg, wordInitPosX, (i - wordInitPosX)), 30, 0).x;
+ messageWords[currentWord - 1].rec.height = fontMessage.baseSize;
+
+ //TODO: Guardar en message
+ strncpy(messageWords[currentWord - 1].text, SubText(missions[currentMission].msg, wordInitPosX, (i - wordInitPosX)), i - wordInitPosX);
+ }
+
+ if (c == '@') // One word to change
+ {
+ foundWord = true;
+ missions[currentMission].msg[i] = ' ';
+
+ offsetX = (int)MeasureTextEx(fontMessage, SubText(missions[currentMission].msg, wordInitPosY, (i + 1) - wordInitPosY), 30, 0).x;
+
+ messageWords[currentWord].rec.x = offsetX;
+ messageWords[currentWord].rec.y = offsetY;
+
+ wordInitPosX = i + 1;
+
+ currentWord++;
+ }
+ else if (c == '/')
+ {
+ missions[currentMission].msg[i] = '\n';
+ wordInitPosY = i;
+ offsetY += (fontMessage.baseSize + fontMessage.baseSize/2); // raylib internal increment on line break...
+ }
+ }
+
+ for (int i = 0; i < missions[currentMission].wordsCount; i++)
+ {
+ messageWords[i].id = -1; // Not required for message words, id is the array position
+
+ // Recalculate words rectangles considering text offset on screen
+ messageWords[i].rec.x += msgOffset.x;
+ messageWords[i].rec.y += msgOffset.y;
+
+ // Recalculate words rectangle considering new width height
+ messageWords[i].rec.x -= (texWordsAtlas.width - messageWords[i].rec.width)/2;
+ messageWords[i].rec.y -= ((texWordsAtlas.height / MAX_CODING_WORDS) - messageWords[i].rec.height)/2;
+
+ //Recalculate width height
+ messageWords[i].rec.width = texWordsAtlas.width;
+ messageWords[i].rec.height = texWordsAtlas.height / MAX_CODING_WORDS;
+
+ messageWords[i].hover = false; // Mouse hover detected
+ messageWords[i].picked = false; // Mouse picked
+ }
+}
+
+// Gameplay Screen Update logic
+void UpdateGameplayScreen(void)
+{
+ UpdateMusicStream(musSpy);
+
+ for (int i = 0; i < MAX_CODING_WORDS; i++)
+ {
+ if (CheckCollisionPointRec(GetMousePosition(), words[i].rec))
+ {
+ words[i].hover = true;
+
+ if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
+ {
+ words[i].picked = true;
+ PlaySound(fxGrab);
+ }
+ }
+ else words[i].hover = false;
+
+
+ if (words[i].picked)
+ {
+ for (int j = 0; j < missions[currentMission].wordsCount; j++)
+ {
+ if (CheckCollisionPointRec(GetMousePosition(), messageWords[j].rec)) messageWords[j].hover = true;
+ else messageWords[j].hover = false;
+ }
+
+ if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON))
+ {
+ words[i].picked = false;
+
+ for (int j = 0; j < missions[currentMission].wordsCount; j++)
+ {
+ messageWords[j].hover = false;
+
+ if (CheckCollisionPointRec(GetMousePosition(), messageWords[j].rec))
+ {
+ PlaySound(fxPlace);
+
+ words[i].rec.x = messageWords[j].rec.x;
+ words[i].rec.y = messageWords[j].rec.y;
+
+ if (messageWords[j].id != -1)
+ {
+ int id = messageWords[j].id;
+ words[id].rec = words[id].iniRec;
+ }
+
+ messageWords[j].id = i;
+ for (int k = 0; k < missions[currentMission].wordsCount; k++)
+ {
+ if (j != k && messageWords[j].id == messageWords[k].id)
+ {
+ messageWords[k].id = -1;
+ break;
+ }
+ }
+ break;
+ }
+ else
+ {
+ PlaySound(fxLeave);
+
+ words[i].rec = words[i].iniRec;
+ if (i == messageWords[j].id) messageWords[j].id = -1;
+ }
+ }
+ }
+ }
+
+ // TODO: Move word picked with mouse
+ if (words[i].picked)
+ {
+ words[i].rec.x = GetMouseX() - words[i].rec.width/2;
+ words[i].rec.y = GetMouseY() - words[i].rec.height/2;
+
+ // TODO: Check if label is placed in some mission word position
+ //if (CheckCollisionRecs(words[i].rec))
+ }
+ else
+ {
+ //if (words[i].id != -1)
+ }
+ }
+
+ canSend = true;
+ for(int j = 0; j < missions[currentMission].wordsCount; j++)
+ {
+ if(messageWords[j].id == -1)
+ {
+ canSend = false;
+ break;
+ }
+ }
+
+ if (canSend && (IsKeyPressed(KEY_ENTER) || IsButtonPressed()))
+ {
+ finishScreen = true;
+ }
+}
+
+// Gameplay Screen Draw logic
+void DrawGameplayScreen(void)
+{
+ DrawTexture(texBackground, 0, 0, WHITE);
+
+ DrawTextEx(fontMessage, missions[currentMission].msg, msgOffset, fontMessage.baseSize, 0, BLACK);
+
+ for (int i = 0; i < missions[currentMission].wordsCount; i++)
+ {
+ Rectangle recLines = messageWords[i].rec;
+ DrawRectangleLines(recLines.x, recLines.y, recLines.width, recLines.height, Fade(RED, 0.35f));
+ if(messageWords[i].hover) DrawRectangleRec(messageWords[i].rec, Fade(RED, 0.30f));
+ DrawText(FormatText("%i", messageWords[i].id), i*25, 0, 30, RED);
+ }
+ for (int i = 0; i < MAX_CODING_WORDS; i++)
+ {
+ if (words[i].picked) DrawTextureRec(texWordsAtlas, (Rectangle){ 0, i*35, 140, 35 }, (Vector2){ words[i].rec.x, words[i].rec.y }, MAROON);
+ else if (words[i].hover) DrawTextureRec(texWordsAtlas, (Rectangle){ 0, i*35, 140, 35 }, (Vector2){ words[i].rec.x, words[i].rec.y }, RED);
+ else DrawTextureRec(texWordsAtlas, (Rectangle){ 0, i*35, 140, 35 }, (Vector2){ words[i].rec.x, words[i].rec.y }, WHITE);
+ }
+
+ DrawTexturePro(texVignette, (Rectangle){0,0,texVignette.width, texVignette.height}, (Rectangle){0,0,GetScreenWidth(), GetScreenHeight()}, (Vector2){0,0}, 0, WHITE);
+
+ if (canSend) DrawButton("enviar");
+}
+
+// Gameplay Screen Unload logic
+void UnloadGameplayScreen(void)
+{
+ UnloadTexture(texBackground);
+ UnloadTexture(texVignette);
+ UnloadTexture(texWordsAtlas);
+
+ UnloadSound(fxGrab);
+ UnloadSound(fxLeave);
+ UnloadSound(fxPlace);
+
+ UnloadMusicStream(musSpy);
+
+ free(missions);
+}
+
+// Gameplay Screen should finish?
+int FinishGameplayScreen(void)
+{
+ return finishScreen;
+}
diff --git a/games/transmission/screens/screen_logo.c b/games/transmission/screens/screen_logo.c
new file mode 100644
index 000000000..30271ba6d
--- /dev/null
+++ b/games/transmission/screens/screen_logo.c
@@ -0,0 +1,102 @@
+/**********************************************************************************************
+*
+* raylib - Advance Game template
+*
+* Logo Screen Functions Definitions (Init, Update, Draw, Unload)
+*
+* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
+*
+* This software is provided "as-is", without any express or implied warranty. In no event
+* will the authors be held liable for any damages arising from the use of this software.
+*
+* Permission is granted to anyone to use this software for any purpose, including commercial
+* applications, and to alter it and redistribute it freely, subject to the following restrictions:
+*
+* 1. The origin of this software must not be misrepresented; you must not claim that you
+* wrote the original software. If you use this software in a product, an acknowledgment
+* in the product documentation would be appreciated but is not required.
+*
+* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
+* as being the original software.
+*
+* 3. This notice may not be removed or altered from any source distribution.
+*
+**********************************************************************************************/
+
+#include "raylib.h"
+#include "screens.h"
+
+//----------------------------------------------------------------------------------
+// Global Variables Definition (local to this module)
+//----------------------------------------------------------------------------------
+
+// Logo screen global variables
+static int framesCounter;
+static int finishScreen;
+
+static Texture2D logoCW;
+
+static float fadeValue;
+static int showLogoFrames;
+static bool fadeOut;
+
+//----------------------------------------------------------------------------------
+// Logo Screen Functions Definition
+//----------------------------------------------------------------------------------
+
+// Logo Screen Initialization logic
+void InitLogoScreen(void)
+{
+ framesCounter = 0;
+ finishScreen = 0;
+
+ logoCW = LoadTexture("resources/textures/cw_logo.png");
+
+ showLogoFrames = 60;
+ fadeValue = 0;
+
+ fadeOut = false;
+}
+
+// Logo Screen Update logic
+void UpdateLogoScreen(void)
+{
+ if(!fadeOut)
+ {
+ fadeValue += 0.02f;
+ if(fadeValue > 1.01f)
+ {
+ fadeValue = 1.0f;
+ framesCounter++;
+
+ if(framesCounter % showLogoFrames == 0)
+ {
+ fadeOut = true;
+ finishScreen = true;
+ }
+ }
+ }
+
+ if(IsKeyPressed(KEY_ENTER))
+ {
+ finishScreen = true;
+ }
+}
+
+// Logo Screen Draw logic
+void DrawLogoScreen(void)
+{
+ DrawTexture(logoCW, GetScreenWidth()/2 - logoCW.width/2, GetScreenHeight()/2 - logoCW.height/2, Fade(WHITE, fadeValue));
+}
+
+// Logo Screen Unload logic
+void UnloadLogoScreen(void)
+{
+ UnloadTexture(logoCW);
+}
+
+// Logo Screen should finish?
+int FinishLogoScreen(void)
+{
+ return finishScreen;
+}
\ No newline at end of file
diff --git a/games/transmission/screens/screen_mission.c b/games/transmission/screens/screen_mission.c
new file mode 100644
index 000000000..0f996502f
--- /dev/null
+++ b/games/transmission/screens/screen_mission.c
@@ -0,0 +1,293 @@
+/**********************************************************************************************
+*
+* raylib - transmission mission
+*
+*
+* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
+*
+* This software is provided "as-is", without any express or implied warranty. In no event
+* will the authors be held liable for any damages arising from the use of this software.
+*
+* Permission is granted to anyone to use this software for any purpose, including commercial
+* applications, and to alter it and redistribute it freely, subject to the following restrictions:
+*
+* 1. The origin of this software must not be misrepresented; you must not claim that you
+* wrote the original software. If you use this software in a product, an acknowledgment
+* in the product documentation would be appreciated but is not required.
+*
+* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
+* as being the original software.
+*
+* 3. This notice may not be removed or altered from any source distribution.
+*
+**********************************************************************************************/
+
+#include "raylib.h"
+#include "screens.h"
+
+#include
+#include
+
+#define MISSION_MAX_LENGTH 256
+#define KEYWORD_MAX_LENGTH 32
+#define MAX_LINE_CHAR 75
+
+//----------------------------------------------------------------------------------
+// Global Variables Definition (local to this module)
+//----------------------------------------------------------------------------------
+
+// Mission screen global variables
+static int framesCounter;
+static int finishScreen;
+
+static Texture2D texBackground;
+
+static Texture2D texBackline; //mission_backline
+static Rectangle sourceRecBackLine;
+static Rectangle destRecBackLine;
+static float fadeBackLine;
+
+static Vector2 numberPosition;
+static Color numberColor;
+
+//static char textMission[MISSION_MAX_LENGTH];
+static Vector2 missionPosition;
+static int missionSize;
+static Color missionColor;
+static int missionLenght;
+static bool missionMaxLength;
+static int missionSpeed;
+
+//static char textKeyword[KEYWORD_MAX_LENGTH];
+static Vector2 keywordPosition;
+static Color keywordColor;
+
+static int showMissionWaitFrames;
+static int showNumberWaitFrames;
+static int showKeywordWaitFrames;
+
+static bool startWritting;
+static bool writeMission;
+static bool writeNumber;
+static bool writeKeyword;
+static bool writeEnd;
+
+static bool writtingMission;
+
+static int blinkFrames;
+static bool blinkKeyWord = true;
+
+static bool showButton = false;
+
+static Mission *missions = NULL;
+
+static Sound fxTransmit;
+static Music musMission;
+
+//----------------------------------------------------------------------------------
+// Mission Screen Functions Definition
+//----------------------------------------------------------------------------------
+static void WriteMissionText();
+static void EndWritting();
+static void BlinkKeyword();
+
+// Mission Screen Initialization logic
+void InitMissionScreen(void)
+{
+ framesCounter = 0;
+ finishScreen = 0;
+
+ fadeButton = 0.80f;
+
+ texBackground = LoadTexture("resources/textures/mission_background.png");
+
+ texBackline = LoadTexture("resources/textures/mission_backline.png");
+ sourceRecBackLine = (Rectangle){0,0,GetScreenWidth(), texBackline.height};
+ destRecBackLine = (Rectangle){0,0,sourceRecBackLine.width, sourceRecBackLine.height};
+ fadeBackLine = 0;
+
+ fxTransmit = LoadSound("resources/audio/fx_message.ogg");
+ musMission = LoadMusicStream("resources/audio/music_mission.ogg");
+
+ PlayMusicStream(musMission);
+
+ // Initialize missions
+ missions = LoadMissions("resources/missions.txt");
+
+ missionMaxLength = strlen(missions[currentMission].brief);
+
+ // Insert line breaks every MAX_LINE_CHAR
+ int currentLine = 1;
+ int i = currentLine * MAX_LINE_CHAR;
+
+ while (i < missionMaxLength)
+ {
+ if (missions[currentMission].brief[i] == ' ')
+ {
+ missions[currentMission].brief[i] = '\n';
+ currentLine++;
+ i = currentLine*MAX_LINE_CHAR;
+ }
+ else i++;
+ }
+
+ missionSize = 30;
+ missionLenght = 0;
+ missionSpeed = 1;
+
+ numberColor = RAYWHITE;
+ missionColor = LIGHTGRAY;
+ keywordColor = (Color){198, 49, 60, 255}; //RED
+
+ numberPosition = (Vector2){150, 185};
+ missionPosition = (Vector2){numberPosition.x, numberPosition.y + 60};
+ keywordPosition = (Vector2){missionPosition.x, missionPosition.y + MeasureTextEx(fontMission, missions[currentMission].brief, missionSize, 0).y + 60};
+
+ startWritting = false;
+ writeNumber = false;
+ writeMission = false;
+ writeKeyword = false;
+ writeEnd = false;
+
+ writtingMission = false;
+
+ showNumberWaitFrames = 30;
+ showMissionWaitFrames = 60;
+ showKeywordWaitFrames = 60;
+
+ blinkKeyWord = true;
+ blinkFrames = 15;
+
+ PlaySound(fxTransmit);
+}
+
+// Mission Screen Update logic
+void UpdateMissionScreen(void)
+{
+ UpdateMusicStream(musMission);
+
+ if (!writeEnd) WriteMissionText();
+ else BlinkKeyword();
+
+ if (showButton)
+ {
+ if (IsKeyPressed(KEY_ENTER) || IsButtonPressed())
+ {
+ if (!writeEnd) EndWritting();
+ else
+ {
+ finishScreen = true;
+ showButton = false;
+ }
+ }
+ }
+}
+
+// Mission Screen Draw logic
+void DrawMissionScreen(void)
+{
+ // TODO: Draw MISSION screen here!
+ DrawTexture(texBackground, 0,0, WHITE);
+ DrawTexturePro(texBackline, sourceRecBackLine, destRecBackLine, (Vector2){0,0},0, Fade(WHITE, fadeBackLine));
+
+ if (writeNumber) DrawTextEx(fontMission, FormatText("Filtración #%02i ", currentMission + 1), numberPosition, missionSize + 10, 0, numberColor);
+ DrawTextEx(fontMission, SubText(missions[currentMission].brief, 0, missionLenght), missionPosition, missionSize, 0, missionColor);
+ if (writeKeyword && blinkKeyWord) DrawTextEx(fontMission, FormatText("Keyword: %s", missions[currentMission].key), keywordPosition, missionSize + 10, 0, keywordColor);
+
+ if (showButton)
+ {
+ if (!writeEnd) DrawButton("saltar");
+ else DrawButton("codificar");
+ }
+}
+
+// Mission Screen Unload logic
+void UnloadMissionScreen(void)
+{
+ // TODO: Unload MISSION screen variables here!
+ UnloadTexture(texBackground);
+ UnloadTexture(texBackline);
+ UnloadSound(fxTransmit);
+ UnloadMusicStream(musMission);
+ free(missions);
+}
+
+// Mission Screen should finish?
+int FinishMissionScreen(void)
+{
+ return finishScreen;
+}
+
+static void WriteMissionText()
+{
+ if(!startWritting)
+ {
+ framesCounter++;
+ if(framesCounter % 60 == 0)
+ {
+ framesCounter = 0;
+ startWritting = true;
+ }
+ }
+ else if(!writeNumber)
+ {
+ framesCounter++;
+ fadeBackLine += 0.020f;
+ if(framesCounter % showNumberWaitFrames == 0)
+ {
+ framesCounter = 0;
+ writeNumber = true;
+ showButton = true;
+ }
+ }
+ else if(!writeMission)
+ {
+ framesCounter ++;
+ if(framesCounter % showMissionWaitFrames == 0)
+ {
+ framesCounter = 0;
+ writeMission = true;
+ writtingMission = true;
+ }
+ }
+ else if(writeMission && writtingMission)
+ {
+ framesCounter++;
+ if(framesCounter % missionSpeed == 0)
+ {
+ framesCounter = 0;
+ missionLenght++;
+
+ if(missionLenght == missionMaxLength)
+ {
+ writtingMission = false;
+ }
+ }
+ }
+ else if(!writeKeyword)
+ {
+ framesCounter++;
+ if(framesCounter % showKeywordWaitFrames == 0)
+ {
+ framesCounter = 0;
+ writeKeyword = true;
+ writeEnd = true;
+ }
+ }
+}
+static void EndWritting()
+{
+ writeEnd = true;
+ writeKeyword = true;
+ writeNumber = true;
+ missionLenght = missionMaxLength;
+}
+static void BlinkKeyword()
+{
+ framesCounter++;
+ if(framesCounter % blinkFrames == 0)
+ {
+ framesCounter = 0;
+ blinkKeyWord = !blinkKeyWord;
+ }
+}
diff --git a/games/transmission/screens/screen_title.c b/games/transmission/screens/screen_title.c
new file mode 100644
index 000000000..a5ad0a847
--- /dev/null
+++ b/games/transmission/screens/screen_title.c
@@ -0,0 +1,168 @@
+/**********************************************************************************************
+*
+* raylib - transmission mission
+*
+*
+* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
+*
+* This software is provided "as-is", without any express or implied warranty. In no event
+* will the authors be held liable for any damages arising from the use of this software.
+*
+* Permission is granted to anyone to use this software for any purpose, including commercial
+* applications, and to alter it and redistribute it freely, subject to the following restrictions:
+*
+* 1. The origin of this software must not be misrepresented; you must not claim that you
+* wrote the original software. If you use this software in a product, an acknowledgment
+* in the product documentation would be appreciated but is not required.
+*
+* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
+* as being the original software.
+*
+* 3. This notice may not be removed or altered from any source distribution.
+*
+**********************************************************************************************/
+
+#include "raylib.h"
+#include "screens.h"
+
+#include
+
+//----------------------------------------------------------------------------------
+// Global Variables Definition (local to this module)
+//----------------------------------------------------------------------------------
+
+// Title screen global variables
+static int framesCounter;
+static int finishScreen;
+
+static Texture2D texBackground;
+static SpriteFont fontTitle;
+static Sound fxTyping;
+
+static float titleSize;
+static Vector2 transmissionPosition;
+static Vector2 missionPositon;
+
+static const char textTitle[20] = "transmissionmission";
+
+static Color titleColor;
+static int speedText;
+
+static int transmissionLenght;
+static int missionLenght;
+static int transmissionMaxLenght;
+static int missionMaxLenght;
+
+static bool writeTransmission;
+static bool writeMission;
+static bool writeEnd;
+
+//----------------------------------------------------------------------------------
+// Title Screen Functions Definition
+//----------------------------------------------------------------------------------
+static void MissionScreen();
+
+// Title Screen Initialization logic
+void InitTitleScreen(void)
+{
+ // TODO: Initialize TITLE screen variables here!
+ framesCounter = 0;
+ finishScreen = 0;
+
+ texBackground = LoadTexture("resources/textures/title_background.png");
+ fxTyping = LoadSound("resources/audio/fx_typing.ogg");
+ fontTitle = LoadSpriteFontEx("resources/fonts/mom_typewritter.ttf", 96, 0, 0);
+
+ titleSize = 44;
+ transmissionPosition = (Vector2){519, 221};
+ missionPositon = (Vector2){580, 261};
+
+ titleColor = BLACK;
+ speedText = 15;
+
+ missionLenght = 0;
+ transmissionLenght = 0;
+
+ missionMaxLenght = 7;
+ transmissionMaxLenght = 12;
+
+ writeTransmission = true;
+ writeMission = false;
+ writeEnd = false;
+
+ currentMission = 0;
+}
+
+// Title Screen Update logic
+void UpdateTitleScreen(void)
+{
+ if (!writeEnd)
+ {
+ framesCounter ++;
+
+ if (framesCounter%speedText == 0)
+ {
+ framesCounter = 0;
+ if (writeTransmission)
+ {
+ transmissionLenght++;
+ if (transmissionLenght == transmissionMaxLenght)
+ {
+ writeTransmission = false;
+ writeMission = true;
+ }
+ }
+ else if (writeMission)
+ {
+ missionLenght++;
+ if (missionLenght == missionMaxLenght)
+ {
+ writeMission = false;
+ writeEnd = true;
+ }
+ }
+
+ PlaySound(fxTyping);
+ }
+ }
+
+ if(IsButtonPressed())
+ {
+ MissionScreen();
+ }
+ else if (IsKeyPressed(KEY_ENTER)) MissionScreen();
+}
+
+// Title Screen Draw logic
+void DrawTitleScreen(void)
+{
+ DrawTexture(texBackground, 0,0, WHITE);
+ DrawTextEx(fontTitle, SubText(textTitle, 0, transmissionLenght), transmissionPosition, titleSize, 0, titleColor);
+ DrawTextEx(fontTitle, SubText(textTitle, 12, missionLenght), missionPositon, titleSize, 0, titleColor);
+
+ DrawButton("start");
+}
+
+// Title Screen Unload logic
+void UnloadTitleScreen(void)
+{
+ UnloadTexture(texBackground);
+ UnloadSound(fxTyping);
+ UnloadSpriteFont(fontTitle);
+}
+
+// Title Screen should finish?
+int FinishTitleScreen(void)
+{
+ return finishScreen;
+}
+
+static void MissionScreen()
+{
+ transmissionLenght = transmissionMaxLenght;
+ missionLenght = missionMaxLenght;
+ writeEnd = true;
+ //finishScreen = 1; // OPTIONS
+ finishScreen = true; // GAMEPLAY
+ //PlaySound(fxCoin);
+}
\ No newline at end of file
diff --git a/games/transmission/screens/screens.h b/games/transmission/screens/screens.h
new file mode 100644
index 000000000..27560d8b7
--- /dev/null
+++ b/games/transmission/screens/screens.h
@@ -0,0 +1,143 @@
+/**********************************************************************************************
+*
+* raylib - transmission mission
+*
+* Screens Functions Declarations (Init, Update, Draw, Unload)
+*
+* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
+*
+* This software is provided "as-is", without any express or implied warranty. In no event
+* will the authors be held liable for any damages arising from the use of this software.
+*
+* Permission is granted to anyone to use this software for any purpose, including commercial
+* applications, and to alter it and redistribute it freely, subject to the following restrictions:
+*
+* 1. The origin of this software must not be misrepresented; you must not claim that you
+* wrote the original software. If you use this software in a product, an acknowledgment
+* in the product documentation would be appreciated but is not required.
+*
+* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
+* as being the original software.
+*
+* 3. This notice may not be removed or altered from any source distribution.
+*
+**********************************************************************************************/
+
+#ifndef SCREENS_H
+#define SCREENS_H
+
+#define MAX_CODING_WORDS 12
+#define MAX_MISSION_WORDS 8
+
+//----------------------------------------------------------------------------------
+// Types and Structures Definition
+//----------------------------------------------------------------------------------
+typedef enum GameScreen { LOGO = 0, TITLE, MISSION, GAMEPLAY, ENDING } GameScreen;
+
+// Words to be coded or coding words
+typedef struct Word {
+ int id;
+ Rectangle rec;
+ Rectangle iniRec;
+ bool hover;
+ bool picked;
+ char text[32]; // text
+} Word;
+
+// Mission information
+typedef struct Mission {
+ int id;
+ char brief[512]; // Mission briefing
+ char key[32]; // Mission keyword
+ char msg[256]; // Message to be coded
+ int wordsCount; // Number of words to coded
+ int sols[10]; // Solution code, depends on wordsCount
+} Mission;
+
+//----------------------------------------------------------------------------------
+// Global Variables Definition
+//----------------------------------------------------------------------------------
+GameScreen currentScreen;
+
+Music music;
+Sound fxButton;
+
+//Mission *missions;
+
+// UI BUTTON
+Rectangle recButton;
+float fadeButton;
+Color colorButton;
+Texture2D texButton;
+Vector2 textPositionButton;
+int fontSizeButton;
+Color textColorButton;
+
+int currentMission;
+int totalMissions;
+
+SpriteFont fontMission;
+
+Word messageWords[MAX_MISSION_WORDS];
+
+#ifdef __cplusplus
+extern "C" { // Prevents name mangling of functions
+#endif
+
+//----------------------------------------------------------------------------------
+// Transmission Functions Declaration
+//----------------------------------------------------------------------------------
+bool IsButtonPressed();
+void DrawButton(const char *text);
+Mission *LoadMissions(const char *fileName);
+
+//----------------------------------------------------------------------------------
+// Logo Screen Functions Declaration
+//----------------------------------------------------------------------------------
+void InitLogoScreen(void);
+void UpdateLogoScreen(void);
+void DrawLogoScreen(void);
+void UnloadLogoScreen(void);
+int FinishLogoScreen(void);
+
+//----------------------------------------------------------------------------------
+// Title Screen Functions Declaration
+//----------------------------------------------------------------------------------
+void InitTitleScreen(void);
+void UpdateTitleScreen(void);
+void DrawTitleScreen(void);
+void UnloadTitleScreen(void);
+int FinishTitleScreen(void);
+
+//----------------------------------------------------------------------------------
+// Mission Screen Functions Declaration
+//----------------------------------------------------------------------------------
+void InitMissionScreen(void);
+void UpdateMissionScreen(void);
+void DrawMissionScreen(void);
+void UnloadMissionScreen(void);
+int FinishMissionScreen(void);
+
+//----------------------------------------------------------------------------------
+// Gameplay Screen Functions Declaration
+//----------------------------------------------------------------------------------
+void InitGameplayScreen(void);
+void UpdateGameplayScreen(void);
+void DrawGameplayScreen(void);
+void UnloadGameplayScreen(void);
+int FinishGameplayScreen(void);
+
+//----------------------------------------------------------------------------------
+// Ending Screen Functions Declaration
+//----------------------------------------------------------------------------------
+void InitEndingScreen(void);
+void UpdateEndingScreen(void);
+void DrawEndingScreen(void);
+void UnloadEndingScreen(void);
+int FinishEndingScreen(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SCREENS_H
\ No newline at end of file
diff --git a/games/transmission/transmission.c b/games/transmission/transmission.c
new file mode 100644
index 000000000..37824a7b6
--- /dev/null
+++ b/games/transmission/transmission.c
@@ -0,0 +1,455 @@
+/*******************************************************************************************
+*
+* raylib - transmission mission
+*
+* Code and transmit the right message
+*
+* This game has been created using raylib (www.raylib.com)
+* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+*
+* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+#include "screens/screens.h" // NOTE: Defines global variable: currentScreen
+
+#include
+#include
+
+#if defined(PLATFORM_WEB)
+ #include
+#endif
+
+//----------------------------------------------------------------------------------
+// Global Variables Definition (local to this module)
+//----------------------------------------------------------------------------------
+const int screenWidth = 1280;
+const int screenHeight = 720;
+
+// Required variables to manage screen transitions (fade-in, fade-out)
+static float transAlpha = 0.0f;
+static bool onTransition = false;
+static bool transFadeOut = false;
+static int transFromScreen = -1;
+static int transToScreen = -1;
+
+// NOTE: Some global variables that require to be visible for all screens,
+// are defined in screens.h (i.e. currentScreen)
+
+//----------------------------------------------------------------------------------
+// Local Functions Declaration
+//----------------------------------------------------------------------------------
+static void ChangeToScreen(int screen); // No transition effect
+
+static void TransitionToScreen(int screen);
+static void UpdateTransition(void);
+static void DrawTransition(void);
+
+static void UpdateDrawFrame(void); // Update and Draw one frame
+
+//----------------------------------------------------------------------------------
+// Main entry point
+//----------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //---------------------------------------------------------
+#ifndef PLATFORM_ANDROID
+ SetConfigFlags(FLAG_SHOW_LOGO); // | FLAG_FULLSCREEN_MODE);
+#endif
+ // Note windowTitle is unused on Android
+ InitWindow(screenWidth, screenHeight, "raylib game - transmission mission");
+
+ // Global data loading (assets that must be available in all screens, i.e. fonts)
+ InitAudioDevice();
+
+ music = LoadMusicStream("resources/audio/music_title.ogg");
+ fxButton = LoadSound("resources/audio/fx_newspaper.ogg");
+
+ SetMusicVolume(music, 1.0f);
+ PlayMusicStream(music);
+
+ fontMission = LoadSpriteFontEx("resources/fonts/traveling_typewriter.ttf", 64, 250, 0);
+ texButton = LoadTexture("resources/textures/title_ribbon.png");
+
+ // UI BUTTON
+ recButton.width = texButton.width;
+ recButton.height = texButton.height;
+ recButton.x = screenWidth - recButton.width;
+ recButton.y = screenHeight - recButton.height - 50;
+ fadeButton = 0.8f;
+ colorButton = RED;
+ textPositionButton = (Vector2){recButton.x + recButton.width/2, recButton.y + recButton.height/2};
+ fontSizeButton = 30;
+ textColorButton = WHITE;
+
+ currentMission = 0;
+ totalMissions = 4;
+
+ // Setup and Init first screen
+ currentScreen = LOGO;
+ InitLogoScreen();
+
+#if defined(PLATFORM_WEB)
+ emscripten_set_main_loop(UpdateDrawFrame, 0, 1);
+#else
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ UpdateDrawFrame();
+ }
+#endif
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+
+ // Unload current screen data before closing
+ switch (currentScreen)
+ {
+ case LOGO: UnloadLogoScreen(); break;
+ case TITLE: UnloadTitleScreen(); break;
+ case MISSION: UnloadMissionScreen(); break;
+ case GAMEPLAY: UnloadGameplayScreen(); break;
+ case ENDING: UnloadEndingScreen(); break;
+ default: break;
+ }
+
+ // Unload all global loaded data (i.e. fonts) here!
+ UnloadMusicStream(music);
+ UnloadSound(fxButton);
+
+ UnloadSpriteFont(fontMission);
+ UnloadTexture(texButton);
+
+ CloseAudioDevice(); // Close audio context
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
+
+//----------------------------------------------------------------------------------
+// Module specific Functions Definition
+//----------------------------------------------------------------------------------
+
+// Change to next screen, no transition
+static void ChangeToScreen(int screen)
+{
+ // Unload current screen
+ switch (currentScreen)
+ {
+ case LOGO: UnloadLogoScreen(); break;
+ case TITLE: UnloadTitleScreen(); break;
+ case MISSION: UnloadMissionScreen(); break;
+ case GAMEPLAY: UnloadGameplayScreen(); break;
+ case ENDING: UnloadEndingScreen(); break;
+ default: break;
+ }
+
+ // Init next screen
+ switch (screen)
+ {
+ case LOGO: InitLogoScreen(); break;
+ case TITLE: InitTitleScreen(); break;
+ case MISSION: InitMissionScreen(); break;
+ case GAMEPLAY: InitGameplayScreen(); break;
+ case ENDING: InitEndingScreen(); break;
+ default: break;
+ }
+
+ currentScreen = screen;
+}
+
+// Define transition to next screen
+static void TransitionToScreen(int screen)
+{
+ onTransition = true;
+ transFadeOut = false;
+ transFromScreen = currentScreen;
+ transToScreen = screen;
+ transAlpha = 0.0f;
+}
+
+// Update transition effect
+static void UpdateTransition(void)
+{
+ if (!transFadeOut)
+ {
+ transAlpha += 0.02f;
+
+ // NOTE: Due to float internal representation, condition jumps on 1.0f instead of 1.05f
+ // For that reason we compare against 1.01f, to avoid last frame loading stop
+ if (transAlpha > 1.01f)
+ {
+ transAlpha = 1.0f;
+
+ // Unload current screen
+ switch (transFromScreen)
+ {
+ case LOGO: UnloadLogoScreen(); break;
+ case TITLE: UnloadTitleScreen(); break;
+ case MISSION: UnloadMissionScreen(); break;
+ case GAMEPLAY: UnloadGameplayScreen(); break;
+ case ENDING: UnloadEndingScreen(); break;
+ default: break;
+ }
+
+ // Load next screen
+ switch (transToScreen)
+ {
+ case LOGO: InitLogoScreen(); break;
+ case TITLE: InitTitleScreen(); break;
+ case MISSION: InitMissionScreen(); break;
+ case GAMEPLAY: InitGameplayScreen(); break;
+ case ENDING: InitEndingScreen(); break;
+ default: break;
+ }
+
+ currentScreen = transToScreen;
+
+ // Activate fade out effect to next loaded screen
+ transFadeOut = true;
+ }
+ }
+ else // Transition fade out logic
+ {
+ transAlpha -= 0.02f;
+
+ if (transAlpha < -0.01f)
+ {
+ transAlpha = 0.0f;
+ transFadeOut = false;
+ onTransition = false;
+ transFromScreen = -1;
+ transToScreen = -1;
+ }
+ }
+}
+
+// Draw transition effect (full-screen rectangle)
+static void DrawTransition(void)
+{
+ DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), Fade(BLACK, transAlpha));
+}
+
+// Update and draw game frame
+static void UpdateDrawFrame(void)
+{
+ // Update
+ //----------------------------------------------------------------------------------
+ UpdateMusicStream(music); // NOTE: Music keeps playing between screens
+
+ if (!onTransition)
+ {
+ switch(currentScreen)
+ {
+ case LOGO:
+ {
+ UpdateLogoScreen();
+
+ if (FinishLogoScreen()) TransitionToScreen(TITLE);
+
+ } break;
+ case TITLE:
+ {
+ UpdateTitleScreen();
+
+ if (FinishTitleScreen())
+ {
+ StopMusicStream(music);
+ TransitionToScreen(MISSION);
+ }
+
+ } break;
+ case MISSION:
+ {
+ UpdateMissionScreen();
+
+ if (FinishMissionScreen())
+ {
+ StopMusicStream(music);
+ TransitionToScreen(GAMEPLAY);
+ }
+
+ } break;
+ case GAMEPLAY:
+ {
+ UpdateGameplayScreen();
+
+ if (FinishGameplayScreen() == 1) TransitionToScreen(ENDING);
+ //else if (FinishGameplayScreen() == 2) TransitionToScreen(TITLE);
+
+ } break;
+ case ENDING:
+ {
+ UpdateEndingScreen();
+
+ if (FinishEndingScreen() == 1) // Continue to next mission
+ {
+ TransitionToScreen(MISSION);
+ }
+ else if (FinishEndingScreen() == 2) // Replay current mission
+ {
+ PlayMusicStream(music);
+ TransitionToScreen(TITLE);
+ }
+
+ } break;
+ default: break;
+ }
+ }
+ else UpdateTransition(); // Update transition (fade-in, fade-out)
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ switch(currentScreen)
+ {
+ case LOGO: DrawLogoScreen(); break;
+ case TITLE: DrawTitleScreen(); break;
+ case MISSION: DrawMissionScreen(); break;
+ case GAMEPLAY: DrawGameplayScreen(); break;
+ case ENDING: DrawEndingScreen(); break;
+ default: break;
+ }
+
+ // Draw full screen rectangle in front of everything
+ if (onTransition) DrawTransition();
+
+ //DrawFPS(10, 10);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+}
+
+// Load missions from text file
+Mission *LoadMissions(const char *fileName)
+{
+ Mission *missions = NULL;
+ char buffer[512];
+
+ int missionsCount = 0;
+
+ FILE *misFile = fopen(fileName, "rt");
+
+ if (misFile == NULL) printf("[%s] Missions file could not be opened\n", fileName);
+ else
+ {
+ // First pass to get total missions count
+ while (!feof(misFile))
+ {
+ fgets(buffer, 512, misFile);
+
+ switch (buffer[0])
+ {
+ case 't': sscanf(buffer, "t %i", &missionsCount); break;
+ default: break;
+ }
+ }
+
+ if (missionsCount > 0) missions = (Mission *)malloc(missionsCount*sizeof(Mission));
+ else return NULL;
+
+ rewind(misFile); // Return to the beginning of the file, to read again
+
+ int missionNum = 0;
+
+ while (!feof(misFile))
+ {
+ fgets(buffer, 512, misFile);
+
+ if (missionNum < missionsCount)
+ {
+ switch (buffer[0])
+ {
+ case 'b':
+ {
+ // New mission brief starts!
+ missions[missionNum].id = missionNum;
+ sscanf(buffer, "b %[^\n]s", missions[missionNum].brief);
+ } break;
+ case 'k': sscanf(buffer, "k %[^\n]s", missions[missionNum].key); break;
+ case 'm':
+ {
+ // NOTE: Message is loaded as is, needs to be processed!
+ sscanf(buffer, "m %[^\n]s", missions[missionNum].msg);
+ } break;
+ case 's':
+ {
+ sscanf(buffer, "s %i %i %i %i %i %i %i %i",
+ &missions[missionNum].sols[0],
+ &missions[missionNum].sols[1],
+ &missions[missionNum].sols[2],
+ &missions[missionNum].sols[3],
+ &missions[missionNum].sols[4],
+ &missions[missionNum].sols[5],
+ &missions[missionNum].sols[6],
+ &missions[missionNum].sols[7]);
+
+ missions[missionNum].wordsCount = 0;
+
+ for (int i = 0; i < 8; i++)
+ {
+ if (missions[missionNum].sols[i] > -1)
+ {
+ missions[missionNum].wordsCount++;
+ }
+ }
+
+ TraceLog(LOG_WARNING, "Mission %i - Words count %i", missionNum, missions[missionNum].wordsCount);
+
+ missionNum++;
+ } break;
+ default: break;
+ }
+ }
+ }
+
+ if (missionsCount != missionNum) TraceLog(LOG_WARNING, "Missions count and loaded missions don't match!");
+ }
+
+ fclose(misFile);
+
+ if (missions != NULL)
+ {
+ TraceLog(LOG_INFO, "Missions loaded: %i", missionsCount);
+ TraceLog(LOG_INFO, "Missions loaded successfully!");
+ }
+
+ return missions;
+}
+
+bool IsButtonPressed()
+{
+ if (CheckCollisionPointRec(GetMousePosition(), recButton))
+ {
+ fadeButton = 1.0f;
+
+ if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON) || IsGestureDetected(GESTURE_TAP))
+ {
+ PlaySound(fxButton);
+ return true;
+ }
+ }
+ else fadeButton = 0.80f;
+
+ return false;
+}
+
+void DrawButton(const char *text)
+{
+ //DrawRectangleRec(recButton, Fade(colorButton, fadeButton));
+ DrawTexturePro(texButton, (Rectangle){0,0,texButton.width, texButton.height}, recButton, (Vector2){0,0},0, Fade(WHITE, fadeButton));
+ Vector2 measure = MeasureTextEx(fontMission, text, fontSizeButton, 0);
+ Vector2 textPos = {textPositionButton.x - measure.x/2 + 10, textPositionButton.y - measure.y/2 - 10};
+ DrawTextEx(fontMission, text, textPos , fontSizeButton, 0, textColorButton);
+}
diff --git a/games/wave_collector/Makefile b/games/wave_collector/Makefile
index 7ea3653a9..035ce1010 100644
--- a/games/wave_collector/Makefile
+++ b/games/wave_collector/Makefile
@@ -2,7 +2,7 @@
#
# raylib makefile for Desktop platforms, Raspberry Pi, Android and HTML5
#
-# Copyright (c) 2013-2017 Ramon Santamaria (@raysan5)
+# Copyright (c) 2013-2018 Ramon Santamaria (@raysan5)
#
# This software is provided "as-is", without any express or implied warranty. In no event
# will the authors be held liable for any damages arising from the use of this software.
@@ -29,72 +29,87 @@ PLATFORM ?= PLATFORM_DESKTOP
RAYLIB_PATH ?= ..\..
PROJECT_NAME ?= wave_collector
-# Library type used for raylib and OpenAL Soft: STATIC (.a) or SHARED (.so/.dll)
-# NOTE: Libraries should be provided in the selected form
-RAYLIB_LIBTYPE ?= STATIC
-OPENAL_LIBTYPE ?= STATIC
-
-# On PLATFORM_WEB force OpenAL Soft shared library
-ifeq ($(PLATFORM),PLATFORM_WEB)
- OPENAL_LIBTYPE = SHARED
+# Default path for raylib on Raspberry Pi, if installed in different path, update it!
+ifeq ($(PLATFORM),PLATFORM_RPI)
+ RAYLIB_PATH ?= /home/pi/raylib
endif
+# Library type used for raylib: STATIC (.a) or SHARED (.so/.dll)
+RAYLIB_LIBTYPE ?= STATIC
+
+# Use external GLFW library instead of rglfw module
+USE_EXTERNAL_GLFW ?= FALSE
+
+# Use Wayland display server protocol on Linux desktop
+# by default it uses X11 windowing system
+USE_WAYLAND_DISPLAY ?= FALSE
+
+# NOTE: On PLATFORM_WEB OpenAL Soft backend is used by default (check raylib/src/Makefile)
+
+
# Determine PLATFORM_OS in case PLATFORM_DESKTOP selected
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
- # No uname.exe on MinGW!, but OS=Windows_NT on Windows! ifeq ($(UNAME),Msys) -> Windows
+ # No uname.exe on MinGW!, but OS=Windows_NT on Windows!
+ # ifeq ($(UNAME),Msys) -> Windows
ifeq ($(OS),Windows_NT)
PLATFORM_OS=WINDOWS
- LIBPATH=win32
else
UNAMEOS=$(shell uname)
ifeq ($(UNAMEOS),Linux)
PLATFORM_OS=LINUX
- LIBPATH=linux
- else
+ endif
+ ifeq ($(UNAMEOS),FreeBSD)
+ PLATFORM_OS=FREEBSD
+ endif
ifeq ($(UNAMEOS),Darwin)
PLATFORM_OS=OSX
- LIBPATH=osx
- endif
endif
endif
endif
-
ifeq ($(PLATFORM),PLATFORM_RPI)
- # RPI cross-compiler
- RPI_CROSS_COMPILE ?= NO
+ UNAMEOS=$(shell uname)
+ ifeq ($(UNAMEOS),Linux)
+ PLATFORM_OS=LINUX
+ endif
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
# Emscripten required variables
EMSDK_PATH = C:/emsdk
- EMSCRIPTEN_VERSION = 1.37.21
- CLANG_VERSION=e1.37.21_64bit
+ EMSCRIPTEN_VERSION = 1.37.28
+ CLANG_VERSION=e1.37.28_64bit
PYTHON_VERSION=2.7.5.3_64bit
NODE_VERSION=4.1.1_64bit
export PATH=$(EMSDK_PATH);$(EMSDK_PATH)\clang\$(CLANG_VERSION);$(EMSDK_PATH)\node\$(NODE_VERSION)\bin;$(EMSDK_PATH)\python\$(PYTHON_VERSION);$(EMSDK_PATH)\emscripten\$(EMSCRIPTEN_VERSION);C:\raylib\MinGW\bin:$$(PATH)
EMSCRIPTEN=$(EMSDK_PATH)\emscripten\$(EMSCRIPTEN_VERSION)
endif
+RAYLIB_RELEASE_PATH ?= $(RAYLIB_PATH)/release/libs
+
# Define raylib release directory for compiled library
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),WINDOWS)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/win32/mingw32
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/win32/mingw32
endif
ifeq ($(PLATFORM_OS),LINUX)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/linux
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/linux
endif
ifeq ($(PLATFORM_OS),OSX)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/osx
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/osx
+ endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/freebsd
endif
endif
-ifeq ($(PLATFORM),PLATFORM_WEB)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/html5
-endif
ifeq ($(PLATFORM),PLATFORM_RPI)
- RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/rpi
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/rpi
+endif
+ifeq ($(PLATFORM),PLATFORM_WEB)
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/html5
endif
# Define default C compiler: gcc
+# NOTE: define g++ compiler if using C++
CC = gcc
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
@@ -102,11 +117,16 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
# OSX default compiler
CC = clang
endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ # FreeBSD default compiler
+ CC = clang
+ endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
- ifeq ($(RPI_CROSS_COMPILE),YES)
- # RPI cross-compiler
- CC = armv6j-hardfloat-linux-gnueabi-gcc
+ ifeq ($(USE_RPI_CROSS_COMPILER),TRUE)
+ # Define RPI cross-compiler
+ #CC = armv6j-hardfloat-linux-gnueabi-gcc
+ CC = $(RPI_TOOLCHAIN)/bin/arm-linux-gnueabihf-gcc
endif
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
@@ -125,19 +145,23 @@ endif
# Define compiler flags:
# -O1 defines optimization level
-# -Og enable debugging
+# -g enable debugging
# -s strip unnecessary data from build
# -Wall turns on most, but not all, compiler warnings
# -std=c99 defines C language mode (standard C from 1999 revision)
# -std=gnu99 defines C language mode (GNU C from 1999 revision)
-# -fgnu89-inline declaring inline functions support (GCC optimized)
# -Wno-missing-braces ignore invalid warning (GCC bug 53119)
# -D_DEFAULT_SOURCE use with -std=c99 on Linux and PLATFORM_WEB, required for timespec
-CFLAGS += -O1 -s -Wall -std=c99 -D_DEFAULT_SOURCE -fgnu89-inline -Wno-missing-braces
+CFLAGS += -O1 -s -Wall -std=c99 -D_DEFAULT_SOURCE -Wno-missing-braces
# Additional flags for compiler (if desired)
#CFLAGS += -Wextra -Wmissing-prototypes -Wstrict-prototypes
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ ifeq ($(PLATFORM_OS),WINDOWS)
+ # resources file contains windows exe icon
+ # -Wl,--subsystem,windows hides the console window
+ CFLAGS += $(RAYLIB_PATH)/src/resources -Wl,--subsystem,windows
+ endif
ifeq ($(PLATFORM_OS),LINUX)
CFLAGS += -no-pie -D_DEFAULT_SOURCE
endif
@@ -151,7 +175,13 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
# -s ALLOW_MEMORY_GROWTH=1 # to allow memory resizing
# -s TOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB)
# -s USE_PTHREADS=1 # multithreading support
- CFLAGS += -s USE_GLFW=3 -s ASSERTIONS=1 --profiling -s TOTAL_MEMORY=16777216 --preload-file resources
+ # -s WASM=1 # support Web Assembly (https://github.com/kripken/emscripten/wiki/WebAssembly)
+ # --preload-file resources # specify a resources folder for data compilation
+ CFLAGS += -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 --profiling --preload-file resources
+
+ # Define a custom shell .html and output extension
+ CFLAGS += --shell-file $(RAYLIB_PATH)\templates\web_shell\shell.html
+ EXT = .html
endif
# Define include paths for required headers
@@ -167,7 +197,14 @@ ifeq ($(PLATFORM),PLATFORM_RPI)
endif
# Define library paths containing required libs
-LDFLAGS = -L. -L$(RAYLIB_RELEASE) -L$(RAYLIB_PATH)/src
+LDFLAGS = -L. -L$(RAYLIB_RELEASE_PATH) -L$(RAYLIB_PATH)/src
+
+ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ INCLUDE_PATHS += -I/usr/local/include
+ LDFLAGS += -L. -Lsrc -L/usr/local/lib
+ endif
+endif
ifeq ($(PLATFORM),PLATFORM_RPI)
LDFLAGS += -L/opt/vc/lib
@@ -177,54 +214,50 @@ endif
# if you want to link libraries (libname.so or libname.a), use the -lname
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),WINDOWS)
- # Libraries for Windows desktop compiling
- # NOTE: GLFW3 and OpenAL Soft libraries should be installed
- LDLIBS = -lraylib -lglfw3 -lopengl32 -lgdi32
-
- # Define required flags and libs for OpenAL Soft STATIC/SHARED usage
- # NOTE: ALLIBS flag only required for raylib Win32 SHARED library building
- ifeq ($(OPENAL_LIBTYPE),STATIC)
- LDLIBS += -lopenal32 -lwinmm
- CFLAGS += -DAL_LIBTYPE_STATIC -Wl,-allow-multiple-definition
- else
- LDLIBS += -lopenal32dll
- endif
+ # Libraries for Windows desktop compilation
+ LDLIBS = -lraylib -lopengl32 -lgdi32
endif
ifeq ($(PLATFORM_OS),LINUX)
# Libraries for Debian GNU/Linux desktop compiling
- # NOTE: Required packages: libglfw3-dev libopenal-dev libegl1-mesa-dev
- LDLIBS = -lraylib -lglfw3 -lGL -lopenal -lm -lpthread -ldl
+ # NOTE: Required packages: libegl1-mesa-dev
+ LDLIBS = -lraylib -lGL -lm -lpthread -ldl -lrt
- # On XWindow requires also below libraries
- LDLIBS += -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
+ # On X11 requires also below libraries
+ LDLIBS += -lX11
+ # NOTE: It seems additional libraries are not required any more, latest GLFW just dlopen them
+ #LDLIBS += -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
+
+ # On Wayland windowing system, additional libraries requires
+ ifeq ($(USE_WAYLAND_DISPLAY),TRUE)
+ LDLIBS += -lwayland-client -lwayland-cursor -lwayland-egl -lxkbcommon
+ endif
endif
ifeq ($(PLATFORM_OS),OSX)
# Libraries for OSX 10.9 desktop compiling
- # NOTE: Required packages: libglfw3-dev libopenal-dev libegl1-mesa-dev
- LDLIBS = -lraylib -lglfw -framework OpenGL -framework OpenAL -framework Cocoa
+ # NOTE: Required packages: libopenal-dev libegl1-mesa-dev
+ LDLIBS = -lraylib -framework OpenGL -framework OpenAL -framework Cocoa
+ endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ # Libraries for FreeBSD desktop compiling
+ # NOTE: Required packages: mesa-libs
+ LDLIBS = -lraylib -lGL -lpthread -lm
+
+ # On XWindow requires also below libraries
+ LDLIBS += -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
+ endif
+ ifeq ($(USE_EXTERNAL_GLFW),TRUE)
+ # NOTE: It could require additional packages installed: libglfw3-dev
+ LDLIBS += -lglfw
endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
# Libraries for Raspberry Pi compiling
- # NOTE: Required packages: libopenal1
- LDLIBS = -lraylib -lGLESv2 -lEGL -lpthread -lrt -lm -lbcm_host -lopenal
+ # NOTE: Required packages: libasound2-dev (ALSA)
+ LDLIBS = -lraylib -lbrcmGLESv2 -lbrcmEGL -lpthread -lrt -lm -lbcm_host -ldl
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
# Libraries for web (HTML5) compiling
- LDLIBS = $(RAYLIB_RELEASE)/libraylib.bc
-endif
-
-# Define additional parameters and flags for windows
-ifeq ($(PLATFORM_OS),WINDOWS)
- # resources file contains raylib icon for windows .exe
- # -Wl,--subsystem,windows hides the console window
- CFLAGS += $(RAYLIB_PATH)/src/resources -Wl,--subsystem,windows
-endif
-
-# Define output extension to generate a .html file using provided shell
-ifeq ($(PLATFORM),PLATFORM_WEB)
- EXT = .html
- WEB_SHELL = --shell-file $(RAYLIB_PATH)\templates\web_shell\shell.html
+ LDLIBS = $(RAYLIB_RELEASE_PATH)/libraylib.bc
endif
# Define all source files required
diff --git a/games/wave_collector/Makefile.Android b/games/wave_collector/Makefile.Android
index 1c8684544..f082ab230 100644
--- a/games/wave_collector/Makefile.Android
+++ b/games/wave_collector/Makefile.Android
@@ -53,26 +53,21 @@ APP_COMPANY_NAME ?= raylib
APP_PRODUCT_NAME ?= rgame
APP_VERSION_CODE ?= 1
APP_VERSION_NAME ?= 1.0
-APP_ICON_LDPI ?= $(RAYLIB_PATH)\logo\logo36x36.png
-APP_ICON_MDPI ?= $(RAYLIB_PATH)\logo\logo48x48.png
-APP_ICON_HDPI ?= $(RAYLIB_PATH)\logo\logo72x72.png
+APP_ICON_LDPI ?= $(RAYLIB_PATH)\logo\raylib_36x36.png
+APP_ICON_MDPI ?= $(RAYLIB_PATH)\logo\raylib_48x48.png
+APP_ICON_HDPI ?= $(RAYLIB_PATH)\logo\raylib_72x72.png
APP_SCREEN_ORIENTATION ?= landscape
APP_KEYSTORE_PASS ?= raylib
-# Library type used for raylib and OpenAL Soft: STATIC (.a) or SHARED (.so/.dll)
+# Library type used for raylib: STATIC (.a) or SHARED (.so/.dll)
RAYLIB_LIBTYPE ?= STATIC
-OPENAL_LIBTYPE ?= STATIC
RAYLIB_LIB_PATH = $(RAYLIB_PATH)\release\libs\android\armeabi-v7a
-OPENAL_LIB_PATH = $(RAYLIB_PATH)\release\libs\android\armeabi-v7a
# Shared libs must be added to APK if required
# NOTE: Generated NativeLoader.java automatically load those libraries
ifeq ($(RAYLIB_LIBTYPE),SHARED)
PROJECT_SHARED_LIBS = lib/armeabi-v7a/libraylib.so
endif
-ifeq ($(OPENAL_LIBTYPE),SHARED)
- PROJECT_SHARED_LIBS += lib/armeabi-v7a/libopenal.so
-endif
# Compiler and archiver
# NOTE: GCC is being deprectated in Android NDK r16
@@ -101,7 +96,7 @@ LDFLAGS += -L. -L$(PROJECT_BUILD_PATH)/obj -L$(PROJECT_BUILD_PATH)/lib/armeabi-v
# Define any libraries to link into executable
# if you want to link libraries (libname.so or libname.a), use the -lname
-LDLIBS = -lraylib -lnative_app_glue -lopenal -llog -landroid -lEGL -lGLESv2 -lOpenSLES -latomic -lc -lm -ldl
+LDLIBS = -lraylib -lnative_app_glue -llog -landroid -lEGL -lGLESv2 -lOpenSLES -latomic -lc -lm -ldl
# Generate target objects list from PROJECT_SOURCE_FILES
OBJS = $(patsubst %.c, $(PROJECT_BUILD_PATH)/obj/%.o, $(PROJECT_SOURCE_FILES))
@@ -154,15 +149,9 @@ copy_project_required_libs:
ifeq ($(RAYLIB_LIBTYPE),SHARED)
copy /Y $(RAYLIB_LIB_PATH)\libraylib.so $(PROJECT_BUILD_PATH)\lib\armeabi-v7a\libraylib.so
endif
-ifeq ($(OPENAL_LIBTYPE),SHARED)
- copy /Y $(OPENAL_LIB_PATH)\libopenal.so $(PROJECT_BUILD_PATH)\lib\armeabi-v7a\libopenal.so
-endif
ifeq ($(RAYLIB_LIBTYPE),STATIC)
copy /Y $(RAYLIB_LIB_PATH)\libraylib.a $(PROJECT_BUILD_PATH)\lib\armeabi-v7a\libraylib.a
endif
-ifeq ($(OPENAL_LIBTYPE),STATIC)
- copy /Y $(OPENAL_LIB_PATH)\libopenal.a $(PROJECT_BUILD_PATH)\lib\armeabi-v7a\libopenal.a
-endif
# Copy project required resources: strings.xml, icon.png, assets
# NOTE: Required strings.xml is generated and game resources are copied to assets folder
@@ -182,9 +171,6 @@ generate_loader_script:
@echo. >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
@echo public class NativeLoader extends android.app.NativeActivity { >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
@echo static { >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
-ifeq ($(OPENAL_LIBTYPE),SHARED)
- @echo System.loadLibrary("openal"); >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
-endif
ifeq ($(RAYLIB_LIBTYPE),SHARED)
@echo System.loadLibrary("raylib"); >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
endif
diff --git a/games/wave_collector/wave_collector.c b/games/wave_collector/wave_collector.c
index d4ce33d98..2099b74c1 100644
--- a/games/wave_collector/wave_collector.c
+++ b/games/wave_collector/wave_collector.c
@@ -22,10 +22,6 @@
#include // Required for: printf()
#include // Required for: strcpy()
-#if defined(PLATFORM_ANDROID)
- #include "android_native_app_glue.h"
-#endif
-
#if defined(PLATFORM_WEB)
#include
#endif
@@ -60,11 +56,7 @@ static void UpdateDrawFrame(void); // Update and Draw one frame
//----------------------------------------------------------------------------------
// Main entry point
//----------------------------------------------------------------------------------
-#if defined(PLATFORM_ANDROID)
-void android_main(struct android_app *app)
-#else
-int main(void)
-#endif
+int main(int argc, char *argv[])
{
// Initialization
//---------------------------------------------------------
@@ -89,12 +81,11 @@ int main(void)
}
#endif
-#if defined(PLATFORM_ANDROID)
- InitWindow(screenWidth, screenHeight, app);
-#else
+#ifndef PLATFORM_ANDROID
SetConfigFlags(FLAG_MSAA_4X_HINT);
- InitWindow(screenWidth, screenHeight, "GGJ17 - WAVE COLLECTOR");
#endif
+ // Note windowTitle is unused on Android
+ InitWindow(screenWidth, screenHeight, "GGJ17 - WAVE COLLECTOR");
// Global data loading (assets that must be available in all screens, i.e. fonts)
InitAudioDevice();
@@ -143,9 +134,8 @@ int main(void)
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
-#if !defined(PLATFORM_ANDROID)
+
return 0;
-#endif
}
//----------------------------------------------------------------------------------
@@ -315,4 +305,4 @@ static void UpdateDrawFrame(void)
EndDrawing();
//----------------------------------------------------------------------------------
-}
\ No newline at end of file
+}
diff --git a/logo/logo128x128.png b/logo/raylib_128x128.png
similarity index 100%
rename from logo/logo128x128.png
rename to logo/raylib_128x128.png
diff --git a/logo/logo16x16.png b/logo/raylib_16x16.png
similarity index 100%
rename from logo/logo16x16.png
rename to logo/raylib_16x16.png
diff --git a/logo/logo24x24.png b/logo/raylib_24x24.png
similarity index 100%
rename from logo/logo24x24.png
rename to logo/raylib_24x24.png
diff --git a/logo/logo256x256.png b/logo/raylib_256x256.png
similarity index 100%
rename from logo/logo256x256.png
rename to logo/raylib_256x256.png
diff --git a/logo/logo32x32.png b/logo/raylib_32x32.png
similarity index 100%
rename from logo/logo32x32.png
rename to logo/raylib_32x32.png
diff --git a/logo/logo36x36.png b/logo/raylib_36x36.png
similarity index 100%
rename from logo/logo36x36.png
rename to logo/raylib_36x36.png
diff --git a/logo/logo48x48.png b/logo/raylib_48x48.png
similarity index 100%
rename from logo/logo48x48.png
rename to logo/raylib_48x48.png
diff --git a/logo/raylib_512x512.png b/logo/raylib_512x512.png
new file mode 100644
index 000000000..0b8c48ec5
Binary files /dev/null and b/logo/raylib_512x512.png differ
diff --git a/logo/logo64x64.png b/logo/raylib_64x64.png
similarity index 100%
rename from logo/logo64x64.png
rename to logo/raylib_64x64.png
diff --git a/logo/logo72x72.png b/logo/raylib_72x72.png
similarity index 100%
rename from logo/logo72x72.png
rename to logo/raylib_72x72.png
diff --git a/logo/raylib_96x96.png b/logo/raylib_96x96.png
new file mode 100644
index 000000000..f2774d221
Binary files /dev/null and b/logo/raylib_96x96.png differ
diff --git a/meson.build b/meson.build
deleted file mode 100644
index c85905cce..000000000
--- a/meson.build
+++ /dev/null
@@ -1,15 +0,0 @@
-project('raylib', 'c', version: '1.8.0',
- license: 'zlib',
- meson_version: '>= 0.39.1',
- default_options : 'c_std=gnu99')
-
-cc = meson.get_compiler('c')
-
-glfw_dep = dependency('glfw3', version : '>=3.2')
-gl_dep = dependency('gl')
-openal_dep = dependency('openal')
-x11_dep = dependency('x11')
-m_dep = cc.find_library('m', required : false)
-
-subdir('src')
-
diff --git a/project/Builder/README.md b/project/Builder/README.md
new file mode 100644
index 000000000..556806ab2
--- /dev/null
+++ b/project/Builder/README.md
@@ -0,0 +1,26 @@
+# Builder project template
+
+This is a project template to be used with [GNOME Builder](https://raw.githubusercontent.com/jubalh/raymario/master/meson.build).
+We use the [meson](https://raw.githubusercontent.com/jubalh/raymario/master/meson.build) build system here.
+
+We can compile our project via the command line:
+```
+meson build
+cd build
+ninja
+ninja install
+```
+
+Or can simply click on the `meson.build` file to open it with Builder.
+Alternatively you can open Builder first and click on the `open` button and the left top.
+
+We added comments to the file to give you an idea which values you should edit.
+For a full overview of options please check the [meson manual](http://mesonbuild.com/Manual.html).
+
+In the provided file we assume that the build file is located at the root folder of your project, and that all your sources are in a `src` subfolder.
+
+Check out the `examples` directory for a simple example on how to use this template.
+You can also look at [raymario](https://github.com/jubalh/raymario) for a slightly more complex example which also installs resource files.
+
+# Notice
+The files provided link against glfw3 and openAL because the latest stable version of raylib is version 1.8, which still needs this. For later versions these two dependencies are not necessary anymore.
diff --git a/project/Builder/examples/README.md b/project/Builder/examples/README.md
new file mode 100644
index 000000000..cba3aef55
--- /dev/null
+++ b/project/Builder/examples/README.md
@@ -0,0 +1 @@
+Open `meson.build` with Builder or run `meson build; cd build; ninja; ./core_basic_window` on the commandline to launch the example.
diff --git a/project/Builder/examples/meson.build b/project/Builder/examples/meson.build
new file mode 100644
index 000000000..ab81ca6c3
--- /dev/null
+++ b/project/Builder/examples/meson.build
@@ -0,0 +1,27 @@
+# This file should be in the main folder of your project
+
+# Replace 'projectname' with the name of your project
+# Replace '1.0' with its version
+project('core_basic_window', 'c', version: '1.0',
+ meson_version: '>= 0.39.1')
+
+# We want a C Compiler to be present
+cc = meson.get_compiler('c')
+
+# Find dependencies
+glfw_dep = dependency('glfw3')
+gl_dep = dependency('gl')
+openal_dep = dependency('openal')
+m_dep = cc.find_library('m', required : false)
+raylib_dep = cc.find_library('raylib', required : false)
+
+# List your source files here
+source_c = [
+ '../../../examples/core/core_basic_window.c',
+]
+
+# Build executable
+core_basic_window = executable('core_basic_window',
+ source_c,
+ dependencies : [ raylib_dep, glfw_dep, gl_dep, openal_dep, m_dep ],
+ install : true)
diff --git a/project/Builder/meson.build b/project/Builder/meson.build
new file mode 100644
index 000000000..41b37fdc4
--- /dev/null
+++ b/project/Builder/meson.build
@@ -0,0 +1,28 @@
+# This file should be in the main folder of your project
+
+# Replace 'projectname' with the name of your project
+# Replace '1.0' with its version
+project('projectname', 'c', version: '1.0',
+ meson_version: '>= 0.39.1')
+
+# We want a C Compiler to be present
+cc = meson.get_compiler('c')
+
+# Find dependencies
+# glfw3 and openal are not needed for raylib > 1.8.0
+glfw_dep = dependency('glfw3')
+gl_dep = dependency('gl')
+openal_dep = dependency('openal')
+m_dep = cc.find_library('m', required : false)
+raylib_dep = cc.find_library('raylib', required : false)
+
+# List your source files here
+source_c = [
+ 'src/main.c',
+]
+
+# Build executable
+projectname = executable('projectname',
+ source_c,
+ dependencies : [ raylib_dep, glfw_dep, gl_dep, openal_dep, m_dep ],
+ install : true)
diff --git a/project/vs2015.UWP/raylib.App.UWP/App.cpp b/project/vs2015.UWP/raylib.App.UWP/App.cpp
new file mode 100644
index 000000000..6ce6915c1
--- /dev/null
+++ b/project/vs2015.UWP/raylib.App.UWP/App.cpp
@@ -0,0 +1,558 @@
+#include "pch.h"
+#include "app.h"
+
+#include "raylib.h"
+
+using namespace Windows::ApplicationModel::Core;
+using namespace Windows::ApplicationModel::Activation;
+using namespace Windows::UI::Core;
+using namespace Windows::UI::Input;
+using namespace Windows::Devices::Input;
+using namespace Windows::Foundation;
+using namespace Windows::Foundation::Collections;
+using namespace Windows::Gaming::Input;
+using namespace Windows::Graphics::Display;
+using namespace Microsoft::WRL;
+using namespace Platform;
+
+using namespace raylibUWP;
+
+/*
+TODO list:
+ - Cache reference to our CoreWindow?
+ - Implement gestures support
+*/
+
+// Declare uwpWindow as exter to be used by raylib internals
+// NOTE: It should be properly assigned before calling InitWindow()
+extern "C" { EGLNativeWindowType uwpWindow; };
+
+/* INPUT CODE */
+// Stand-ins for "core.c" variables
+#define MAX_GAMEPADS 4 // Max number of gamepads supported
+#define MAX_GAMEPAD_BUTTONS 32 // Max bumber of buttons supported (per gamepad)
+#define MAX_GAMEPAD_AXIS 8 // Max number of axis supported (per gamepad)
+
+static bool gamepadReady[MAX_GAMEPADS] = { false }; // Flag to know if gamepad is ready
+static float gamepadAxisState[MAX_GAMEPADS][MAX_GAMEPAD_AXIS]; // Gamepad axis state
+static char previousGamepadState[MAX_GAMEPADS][MAX_GAMEPAD_BUTTONS]; // Previous gamepad buttons state
+static char currentGamepadState[MAX_GAMEPADS][MAX_GAMEPAD_BUTTONS]; // Current gamepad buttons state
+
+static char previousKeyState[512] = { 0 }; // Contains previous frame keyboard state
+static char currentKeyState[512] = { 0 }; // Contains current frame keyboard state
+
+static char previousMouseState[3] = { 0 }; // Registers previous mouse button state
+static char currentMouseState[3] = { 0 }; // Registers current mouse button state
+static int previousMouseWheelY = 0; // Registers previous mouse wheel variation
+static int currentMouseWheelY = 0; // Registers current mouse wheel variation
+
+static bool cursorOnScreen = false; // Tracks if cursor is inside client area
+static bool cursorHidden = false; // Track if cursor is hidden
+
+static Vector2 mousePosition;
+static Vector2 mouseDelta; // NOTE: Added to keep track of mouse movement while the cursor is locked - no equivalent in "core.c"
+static bool toggleCursorLock;
+
+CoreCursor ^regularCursor = ref new CoreCursor(CoreCursorType::Arrow, 0); // The "visible arrow" cursor type
+
+// Helper to process key events
+void ProcessKeyEvent(Windows::System::VirtualKey key, int action)
+{
+ using Windows::System::VirtualKey;
+ switch (key)
+ {
+ case VirtualKey::Space: currentKeyState[KEY_SPACE] = action; break;
+ case VirtualKey::Escape: currentKeyState[KEY_ESCAPE] = action; break;
+ case VirtualKey::Enter: currentKeyState[KEY_ENTER] = action; break;
+ case VirtualKey::Delete: currentKeyState[KEY_BACKSPACE] = action; break;
+ case VirtualKey::Right: currentKeyState[KEY_RIGHT] = action; break;
+ case VirtualKey::Left: currentKeyState[KEY_LEFT] = action; break;
+ case VirtualKey::Down: currentKeyState[KEY_DOWN] = action; break;
+ case VirtualKey::Up: currentKeyState[KEY_UP] = action; break;
+ case VirtualKey::F1: currentKeyState[KEY_F1] = action; break;
+ case VirtualKey::F2: currentKeyState[KEY_F2] = action; break;
+ case VirtualKey::F3: currentKeyState[KEY_F4] = action; break;
+ case VirtualKey::F4: currentKeyState[KEY_F5] = action; break;
+ case VirtualKey::F5: currentKeyState[KEY_F6] = action; break;
+ case VirtualKey::F6: currentKeyState[KEY_F7] = action; break;
+ case VirtualKey::F7: currentKeyState[KEY_F8] = action; break;
+ case VirtualKey::F8: currentKeyState[KEY_F9] = action; break;
+ case VirtualKey::F9: currentKeyState[KEY_F10] = action; break;
+ case VirtualKey::F10: currentKeyState[KEY_F11] = action; break;
+ case VirtualKey::F11: currentKeyState[KEY_F12] = action; break;
+ case VirtualKey::LeftShift: currentKeyState[KEY_LEFT_SHIFT] = action; break;
+ case VirtualKey::LeftControl: currentKeyState[KEY_LEFT_CONTROL] = action; break;
+ case VirtualKey::LeftMenu: currentKeyState[KEY_LEFT_ALT] = action; break; // NOTE: Potential UWP bug with Alt key: https://social.msdn.microsoft.com/Forums/windowsapps/en-US/9bebfb0a-7637-400e-8bda-e55620091407/unexpected-behavior-in-windowscoreuicorephysicalkeystatusismenukeydown
+ case VirtualKey::RightShift: currentKeyState[KEY_RIGHT_SHIFT] = action; break;
+ case VirtualKey::RightControl: currentKeyState[KEY_RIGHT_CONTROL] = action; break;
+ case VirtualKey::RightMenu: currentKeyState[KEY_RIGHT_ALT] = action; break;
+ case VirtualKey::Number0: currentKeyState[KEY_ZERO] = action; break;
+ case VirtualKey::Number1: currentKeyState[KEY_ONE] = action; break;
+ case VirtualKey::Number2: currentKeyState[KEY_TWO] = action; break;
+ case VirtualKey::Number3: currentKeyState[KEY_THREE] = action; break;
+ case VirtualKey::Number4: currentKeyState[KEY_FOUR] = action; break;
+ case VirtualKey::Number5: currentKeyState[KEY_FIVE] = action; break;
+ case VirtualKey::Number6: currentKeyState[KEY_SIX] = action; break;
+ case VirtualKey::Number7: currentKeyState[KEY_SEVEN] = action; break;
+ case VirtualKey::Number8: currentKeyState[KEY_EIGHT] = action; break;
+ case VirtualKey::Number9: currentKeyState[KEY_NINE] = action; break;
+ case VirtualKey::A: currentKeyState[KEY_A] = action; break;
+ case VirtualKey::B: currentKeyState[KEY_B] = action; break;
+ case VirtualKey::C: currentKeyState[KEY_C] = action; break;
+ case VirtualKey::D: currentKeyState[KEY_D] = action; break;
+ case VirtualKey::E: currentKeyState[KEY_E] = action; break;
+ case VirtualKey::F: currentKeyState[KEY_F] = action; break;
+ case VirtualKey::G: currentKeyState[KEY_G] = action; break;
+ case VirtualKey::H: currentKeyState[KEY_H] = action; break;
+ case VirtualKey::I: currentKeyState[KEY_I] = action; break;
+ case VirtualKey::J: currentKeyState[KEY_J] = action; break;
+ case VirtualKey::K: currentKeyState[KEY_K] = action; break;
+ case VirtualKey::L: currentKeyState[KEY_L] = action; break;
+ case VirtualKey::M: currentKeyState[KEY_M] = action; break;
+ case VirtualKey::N: currentKeyState[KEY_N] = action; break;
+ case VirtualKey::O: currentKeyState[KEY_O] = action; break;
+ case VirtualKey::P: currentKeyState[KEY_P] = action; break;
+ case VirtualKey::Q: currentKeyState[KEY_Q] = action; break;
+ case VirtualKey::R: currentKeyState[KEY_R] = action; break;
+ case VirtualKey::S: currentKeyState[KEY_S] = action; break;
+ case VirtualKey::T: currentKeyState[KEY_T] = action; break;
+ case VirtualKey::U: currentKeyState[KEY_U] = action; break;
+ case VirtualKey::V: currentKeyState[KEY_V] = action; break;
+ case VirtualKey::W: currentKeyState[KEY_W] = action; break;
+ case VirtualKey::X: currentKeyState[KEY_X] = action; break;
+ case VirtualKey::Y: currentKeyState[KEY_Y] = action; break;
+ case VirtualKey::Z: currentKeyState[KEY_Z] = action; break;
+
+ }
+}
+
+// Callbacks
+void App::PointerPressed(CoreWindow^ window, PointerEventArgs^ args)
+{
+ if (args->CurrentPoint->Properties->IsLeftButtonPressed)
+ {
+ currentMouseState[MOUSE_LEFT_BUTTON] = 1;
+ }
+ if (args->CurrentPoint->Properties->IsRightButtonPressed)
+ {
+ currentMouseState[MOUSE_RIGHT_BUTTON] = 1;
+ }
+ if (args->CurrentPoint->Properties->IsMiddleButtonPressed)
+ {
+ currentMouseState[MOUSE_MIDDLE_BUTTON] = 1;
+ }
+}
+
+void App::PointerReleased(CoreWindow ^window, PointerEventArgs^ args)
+{
+ if (!(args->CurrentPoint->Properties->IsLeftButtonPressed))
+ {
+ currentMouseState[MOUSE_LEFT_BUTTON] = 0;
+ }
+ if (!(args->CurrentPoint->Properties->IsRightButtonPressed))
+ {
+ currentMouseState[MOUSE_RIGHT_BUTTON] = 0;
+ }
+ if (!(args->CurrentPoint->Properties->IsMiddleButtonPressed))
+ {
+ currentMouseState[MOUSE_MIDDLE_BUTTON] = 0;
+ }
+}
+
+void App::PointerWheelChanged(CoreWindow ^window, PointerEventArgs^ args)
+{
+ // TODO: Scale the MouseWheelDelta to match GLFW's mouse wheel sensitivity.
+ currentMouseWheelY += args->CurrentPoint->Properties->MouseWheelDelta;
+}
+
+void App::MouseMoved(Windows::Devices::Input::MouseDevice^ mouseDevice, Windows::Devices::Input::MouseEventArgs^ args)
+{
+ mouseDelta.x += args->MouseDelta.X;
+ mouseDelta.y += args->MouseDelta.Y;
+}
+
+void App::OnKeyDown(CoreWindow ^ sender, KeyEventArgs ^ args)
+{
+ ProcessKeyEvent(args->VirtualKey, 1);
+}
+
+void App::OnKeyUp(CoreWindow ^ sender, KeyEventArgs ^ args)
+{
+ ProcessKeyEvent(args->VirtualKey, 0);
+}
+
+/* REIMPLEMENTED FROM CORE.C */
+// Get one key state
+static bool GetKeyStatus(int key)
+{
+ return currentKeyState[key];
+}
+
+// Show mouse cursor
+void UWPShowCursor()
+{
+ CoreWindow::GetForCurrentThread()->PointerCursor = regularCursor;
+ cursorHidden = false;
+}
+
+// Hides mouse cursor
+void UWPHideCursor()
+{
+ CoreWindow::GetForCurrentThread()->PointerCursor = nullptr;
+ cursorHidden = true;
+}
+
+// Set mouse position XY
+void UWPSetMousePosition(Vector2 position)
+{
+ CoreWindow ^window = CoreWindow::GetForCurrentThread();
+ Point mousePosScreen = Point(position.x + window->Bounds.X, position.y + window->Bounds.Y);
+ window->PointerPosition = mousePosScreen;
+ mousePosition = position;
+}
+
+// Enables cursor (unlock cursor)
+void UWPEnableCursor()
+{
+ UWPShowCursor();
+ UWPSetMousePosition(mousePosition); // The mouse is hidden in the center of the screen - move it to where it should appear
+ toggleCursorLock = false;
+}
+
+// Disables cursor (lock cursor)
+void UWPDisableCursor()
+{
+ UWPHideCursor();
+ toggleCursorLock = true;
+}
+
+// Get one mouse button state
+static bool UWPGetMouseButtonStatus(int button)
+{
+ return currentMouseState[button];
+}
+
+// Poll (store) all input events
+void UWP_PollInput()
+{
+ // Register previous keyboard state
+ for (int k = 0; k < 512; k++) previousKeyState[k] = currentKeyState[k];
+
+ // Process Mouse
+ {
+ // Register previous mouse states
+ for (int i = 0; i < 3; i++) previousMouseState[i] = currentMouseState[i];
+ previousMouseWheelY = currentMouseWheelY;
+ currentMouseWheelY = 0;
+
+ CoreWindow ^window = CoreWindow::GetForCurrentThread();
+ if (toggleCursorLock)
+ {
+ // Track cursor movement delta, recenter it on the client
+ mousePosition.x += mouseDelta.x;
+ mousePosition.y += mouseDelta.y;
+
+ // Why we're not using UWPSetMousePosition here...
+ // UWPSetMousePosition changes the "mousePosition" variable to match where the cursor actually is.
+ // Our cursor is locked to the middle of screen, and we don't want that reflected in "mousePosition"
+ Vector2 centerClient = { (float)(GetScreenWidth() / 2), (float)(GetScreenHeight() / 2) };
+ window->PointerPosition = Point(centerClient.x + window->Bounds.X, centerClient.y + window->Bounds.Y);
+ }
+ else
+ {
+ // Record the cursor's position relative to the client
+ mousePosition.x = window->PointerPosition.X - window->Bounds.X;
+ mousePosition.y = window->PointerPosition.Y - window->Bounds.Y;
+ }
+
+ mouseDelta = { 0 ,0 };
+ }
+
+ // Process Gamepads
+ {
+ // Check if gamepads are ready
+ for (int i = 0; i < MAX_GAMEPADS; i++)
+ {
+ // HACK: UWP keeps a contiguous list of gamepads. For the interest of time I'm just doing a 1:1 mapping of
+ // connected gamepads with their spot in the list, but this has serious robustness problems
+ // e.g. player 1, 2, and 3 are playing a game - if player2 disconnects, p3's controller would now be mapped to p2's character since p3 is now second in the list.
+
+ gamepadReady[i] = (i < Gamepad::Gamepads->Size);
+ }
+
+ // Get current gamepad state
+ for (int i = 0; i < MAX_GAMEPADS; i++)
+ {
+ if (gamepadReady[i])
+ {
+ // Register previous gamepad states
+ for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) previousGamepadState[i][k] = currentGamepadState[i][k];
+
+ // Get current gamepad state
+ auto gamepad = Gamepad::Gamepads->GetAt(i);
+ GamepadReading reading = gamepad->GetCurrentReading();
+
+ // NOTE: Maybe it would be wiser to redefine the gamepad button mappings in "raylib.h" for the UWP platform instead of remapping them manually
+ currentGamepadState[i][GAMEPAD_XBOX_BUTTON_A] = ((reading.Buttons & GamepadButtons::A) == GamepadButtons::A);
+ currentGamepadState[i][GAMEPAD_XBOX_BUTTON_B] = ((reading.Buttons & GamepadButtons::B) == GamepadButtons::B);
+ currentGamepadState[i][GAMEPAD_XBOX_BUTTON_X] = ((reading.Buttons & GamepadButtons::X) == GamepadButtons::X);
+ currentGamepadState[i][GAMEPAD_XBOX_BUTTON_Y] = ((reading.Buttons & GamepadButtons::Y) == GamepadButtons::Y);
+ currentGamepadState[i][GAMEPAD_XBOX_BUTTON_LB] = ((reading.Buttons & GamepadButtons::LeftShoulder) == GamepadButtons::LeftShoulder);
+ currentGamepadState[i][GAMEPAD_XBOX_BUTTON_RB] = ((reading.Buttons & GamepadButtons::RightShoulder) == GamepadButtons::RightShoulder);
+ currentGamepadState[i][GAMEPAD_XBOX_BUTTON_SELECT] = ((reading.Buttons & GamepadButtons::View) == GamepadButtons::View); // Changed for XB1 Controller
+ currentGamepadState[i][GAMEPAD_XBOX_BUTTON_START] = ((reading.Buttons & GamepadButtons::Menu) == GamepadButtons::Menu); // Changed for XB1 Controller
+ currentGamepadState[i][GAMEPAD_XBOX_BUTTON_UP] = ((reading.Buttons & GamepadButtons::DPadUp) == GamepadButtons::DPadUp);
+ currentGamepadState[i][GAMEPAD_XBOX_BUTTON_RIGHT] = ((reading.Buttons & GamepadButtons::DPadRight) == GamepadButtons::DPadRight);
+ currentGamepadState[i][GAMEPAD_XBOX_BUTTON_DOWN] = ((reading.Buttons & GamepadButtons::DPadLeft) == GamepadButtons::DPadDown);
+ currentGamepadState[i][GAMEPAD_XBOX_BUTTON_LEFT] = ((reading.Buttons & GamepadButtons::DPadDown) == GamepadButtons::DPadLeft);
+ currentGamepadState[i][GAMEPAD_XBOX_BUTTON_HOME] = false; // Home button not supported by UWP
+
+ // Get current axis state
+ gamepadAxisState[i][GAMEPAD_XBOX_AXIS_LEFT_X] = reading.LeftThumbstickX;
+ gamepadAxisState[i][GAMEPAD_XBOX_AXIS_LEFT_Y] = reading.LeftThumbstickY;
+ gamepadAxisState[i][GAMEPAD_XBOX_AXIS_RIGHT_X] = reading.RightThumbstickX;
+ gamepadAxisState[i][GAMEPAD_XBOX_AXIS_RIGHT_Y] = reading.RightThumbstickY;
+ gamepadAxisState[i][GAMEPAD_XBOX_AXIS_LT] = reading.LeftTrigger;
+ gamepadAxisState[i][GAMEPAD_XBOX_AXIS_RT] = reading.RightTrigger;
+ }
+ }
+ }
+
+}
+
+// The following functions were ripped from core.c and have *no additional work done on them*
+// Detect if a key has been pressed once
+bool UWPIsKeyPressed(int key)
+{
+ bool pressed = false;
+
+ if ((currentKeyState[key] != previousKeyState[key]) && (currentKeyState[key] == 1)) pressed = true;
+ else pressed = false;
+
+ return pressed;
+}
+
+// Detect if a key is being pressed (key held down)
+bool UWPIsKeyDown(int key)
+{
+ if (GetKeyStatus(key) == 1) return true;
+ else return false;
+}
+
+// Detect if a key has been released once
+bool UWPIsKeyReleased(int key)
+{
+ bool released = false;
+
+ if ((currentKeyState[key] != previousKeyState[key]) && (currentKeyState[key] == 0)) released = true;
+ else released = false;
+
+ return released;
+}
+
+// Detect if a key is NOT being pressed (key not held down)
+bool UWPIsKeyUp(int key)
+{
+ if (GetKeyStatus(key) == 0) return true;
+ else return false;
+}
+
+/* OTHER CODE */
+
+// Helper to convert a length in device-independent pixels (DIPs) to a length in physical pixels.
+inline float ConvertDipsToPixels(float dips, float dpi)
+{
+ static const float dipsPerInch = 96.0f;
+ return floor(dips * dpi / dipsPerInch + 0.5f); // Round to nearest integer.
+}
+
+// Implementation of the IFrameworkViewSource interface, necessary to run our app.
+ref class SimpleApplicationSource sealed : Windows::ApplicationModel::Core::IFrameworkViewSource
+{
+public:
+ virtual Windows::ApplicationModel::Core::IFrameworkView^ CreateView()
+ {
+ return ref new App();
+ }
+};
+
+// The main function creates an IFrameworkViewSource for our app, and runs the app.
+[Platform::MTAThread]
+int main(Platform::Array^)
+{
+ auto simpleApplicationSource = ref new SimpleApplicationSource();
+ CoreApplication::Run(simpleApplicationSource);
+
+ return 0;
+}
+
+App::App() :
+ mWindowClosed(false),
+ mWindowVisible(true)
+{
+}
+
+// The first method called when the IFrameworkView is being created.
+void App::Initialize(CoreApplicationView^ applicationView)
+{
+ // Register event handlers for app lifecycle. This example includes Activated, so that we
+ // can make the CoreWindow active and start rendering on the window.
+ applicationView->Activated += ref new TypedEventHandler(this, &App::OnActivated);
+
+ // Logic for other event handlers could go here.
+ // Information about the Suspending and Resuming event handlers can be found here:
+ // http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh994930.aspx
+
+ CoreApplication::Resuming += ref new EventHandler(this, &App::OnResuming);
+}
+
+// Called when the CoreWindow object is created (or re-created).
+void App::SetWindow(CoreWindow^ window)
+{
+ window->SizeChanged += ref new TypedEventHandler(this, &App::OnWindowSizeChanged);
+ window->VisibilityChanged += ref new TypedEventHandler(this, &App::OnVisibilityChanged);
+ window->Closed += ref new TypedEventHandler(this, &App::OnWindowClosed);
+
+ window->PointerPressed += ref new TypedEventHandler(this, &App::PointerPressed);
+ window->PointerReleased += ref new TypedEventHandler(this, &App::PointerReleased);
+ window->PointerWheelChanged += ref new TypedEventHandler(this, &App::PointerWheelChanged);
+ window->KeyDown += ref new TypedEventHandler(this, &App::OnKeyDown);
+ window->KeyUp += ref new TypedEventHandler(this, &App::OnKeyUp);
+
+ Windows::Devices::Input::MouseDevice::GetForCurrentView()->MouseMoved += ref new TypedEventHandler(this, &App::MouseMoved);
+
+ DisplayInformation^ currentDisplayInformation = DisplayInformation::GetForCurrentView();
+ currentDisplayInformation->DpiChanged += ref new TypedEventHandler(this, &App::OnDpiChanged);
+ currentDisplayInformation->OrientationChanged += ref new TypedEventHandler(this, &App::OnOrientationChanged);
+
+ // The CoreWindow has been created, so EGL can be initialized.
+
+ uwpWindow = (EGLNativeWindowType)window;
+
+ InitWindow(800, 450, NULL);
+}
+
+// Initializes scene resources
+void App::Load(Platform::String^ entryPoint)
+{
+ // InitWindow() --> rlglInit()
+}
+
+static int posX = 100;
+static int posY = 100;
+static int time = 0;
+// This method is called after the window becomes active.
+void App::Run()
+{
+ while (!mWindowClosed)
+ {
+ if (mWindowVisible)
+ {
+ // Draw
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ posX += gamepadAxisState[GAMEPAD_PLAYER1][GAMEPAD_XBOX_AXIS_LEFT_X] * 5;
+ posY += gamepadAxisState[GAMEPAD_PLAYER1][GAMEPAD_XBOX_AXIS_LEFT_Y] * -5;
+ DrawRectangle(posX, posY, 400, 100, RED);
+
+ DrawLine(0, 0, GetScreenWidth(), GetScreenHeight(), BLUE);
+
+ DrawCircle(mousePosition.x, mousePosition.y, 40, BLUE);
+
+ if (UWPIsKeyDown(KEY_S)) DrawCircle(100, 100, 100, BLUE);
+
+ if (UWPIsKeyPressed(KEY_A))
+ {
+ posX -= 50;
+ UWPEnableCursor();
+ }
+
+ if (UWPIsKeyPressed(KEY_D))
+ {
+ posX += 50;
+ UWPDisableCursor();
+ }
+
+ if (currentKeyState[KEY_LEFT_ALT]) DrawRectangle(250, 250, 20, 20, BLACK);
+ if (currentKeyState[KEY_BACKSPACE]) DrawRectangle(280, 250, 20, 20, BLACK);
+ if (currentMouseState[MOUSE_LEFT_BUTTON]) DrawRectangle(280, 250, 20, 20, BLACK);
+
+ static int pos = 0;
+ pos -= currentMouseWheelY;
+
+ DrawRectangle(280, pos + 50, 20, 20, BLACK);
+ DrawRectangle(250, 280 + (time++ % 60), 10, 10, PURPLE);
+
+ EndDrawing();
+
+ UWP_PollInput();
+
+ CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
+ }
+ else
+ {
+ CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
+ }
+ }
+
+ CloseWindow();
+}
+
+// Terminate events do not cause Uninitialize to be called. It will be called if your IFrameworkView
+// class is torn down while the app is in the foreground.
+void App::Uninitialize()
+{
+ // CloseWindow();
+}
+
+// Application lifecycle event handler.
+void App::OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args)
+{
+ // Run() won't start until the CoreWindow is activated.
+ CoreWindow::GetForCurrentThread()->Activate();
+}
+
+void App::OnResuming(Object^ sender, Object^ args)
+{
+ // Restore any data or state that was unloaded on suspend. By default, data
+ // and state are persisted when resuming from suspend. Note that this event
+ // does not occur if the app was previously terminated.
+}
+
+void App::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args)
+{
+ // TODO: Update window and render area size
+ //m_deviceResources->SetLogicalSize(Size(sender->Bounds.Width, sender->Bounds.Height));
+ //m_main->UpdateForWindowSizeChange();
+}
+
+// Window event handlers.
+void App::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args)
+{
+ mWindowVisible = args->Visible;
+
+ // raylib core has the variable windowMinimized to register state,
+ // it should be modifyed by this event...
+}
+
+void App::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args)
+{
+ mWindowClosed = true;
+
+ // raylib core has the variable windowShouldClose to register state,
+ // it should be modifyed by this event...
+}
+
+void App::OnDpiChanged(DisplayInformation^ sender, Object^ args)
+{
+ //m_deviceResources->SetDpi(sender->LogicalDpi);
+ //m_main->UpdateForWindowSizeChange();
+}
+
+void App::OnOrientationChanged(DisplayInformation^ sender, Object^ args)
+{
+ //m_deviceResources->SetCurrentOrientation(sender->CurrentOrientation);
+ //m_main->UpdateForWindowSizeChange();
+}
diff --git a/project/vs2015.UWP/raylib.App.UWP/App.h b/project/vs2015.UWP/raylib.App.UWP/App.h
new file mode 100644
index 000000000..5b58528ba
--- /dev/null
+++ b/project/vs2015.UWP/raylib.App.UWP/App.h
@@ -0,0 +1,49 @@
+#pragma once
+
+#include
+
+#include "pch.h"
+
+namespace raylibUWP
+{
+ ref class App sealed : public Windows::ApplicationModel::Core::IFrameworkView
+ {
+ public:
+ App();
+
+ // IFrameworkView Methods.
+ virtual void Initialize(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView);
+ virtual void SetWindow(Windows::UI::Core::CoreWindow^ window);
+ virtual void Load(Platform::String^ entryPoint);
+ virtual void Run();
+ virtual void Uninitialize();
+
+ protected:
+
+ // Application lifecycle event handlers.
+ void OnActivated(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView, Windows::ApplicationModel::Activation::IActivatedEventArgs^ args);
+ void OnResuming(Platform::Object^ sender, Platform::Object^ args);
+
+ // Window event handlers.
+ void OnWindowSizeChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ args);
+ void OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args);
+ void OnWindowClosed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CoreWindowEventArgs^ args);
+
+ // DisplayInformation event handlers.
+ void OnDpiChanged(Windows::Graphics::Display::DisplayInformation^ sender, Platform::Object^ args);
+ void OnOrientationChanged(Windows::Graphics::Display::DisplayInformation^ sender, Platform::Object^ args);
+
+ // Input event handlers
+ void PointerPressed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
+ void PointerReleased(Windows::UI::Core::CoreWindow ^sender, Windows::UI::Core::PointerEventArgs^ args);
+ void PointerWheelChanged(Windows::UI::Core::CoreWindow ^sender, Windows::UI::Core::PointerEventArgs^ args);
+ void MouseMoved(Windows::Devices::Input::MouseDevice^ mouseDevice, Windows::Devices::Input::MouseEventArgs^ args);
+ void OnKeyDown(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::KeyEventArgs ^ args);
+ void OnKeyUp(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::KeyEventArgs ^ args);
+
+ private:
+
+ bool mWindowClosed;
+ bool mWindowVisible;
+ };
+}
diff --git a/project/vs2015.UWP/raylib.App.UWP/Assets/Logo.scale-100.png b/project/vs2015.UWP/raylib.App.UWP/Assets/Logo.scale-100.png
new file mode 100644
index 000000000..e26771cb3
Binary files /dev/null and b/project/vs2015.UWP/raylib.App.UWP/Assets/Logo.scale-100.png differ
diff --git a/project/vs2015.UWP/raylib.App.UWP/Assets/SmallLogo.scale-100.png b/project/vs2015.UWP/raylib.App.UWP/Assets/SmallLogo.scale-100.png
new file mode 100644
index 000000000..1eb0d9d52
Binary files /dev/null and b/project/vs2015.UWP/raylib.App.UWP/Assets/SmallLogo.scale-100.png differ
diff --git a/project/vs2015.UWP/raylib.App.UWP/Assets/SplashScreen.scale-100.png b/project/vs2015.UWP/raylib.App.UWP/Assets/SplashScreen.scale-100.png
new file mode 100644
index 000000000..c951e031b
Binary files /dev/null and b/project/vs2015.UWP/raylib.App.UWP/Assets/SplashScreen.scale-100.png differ
diff --git a/project/vs2015.UWP/raylib.App.UWP/Assets/StoreLogo.scale-100.png b/project/vs2015.UWP/raylib.App.UWP/Assets/StoreLogo.scale-100.png
new file mode 100644
index 000000000..dcb672712
Binary files /dev/null and b/project/vs2015.UWP/raylib.App.UWP/Assets/StoreLogo.scale-100.png differ
diff --git a/project/vs2015.UWP/raylib.App.UWP/Assets/WideLogo.scale-100.png b/project/vs2015.UWP/raylib.App.UWP/Assets/WideLogo.scale-100.png
new file mode 100644
index 000000000..9dd94b628
Binary files /dev/null and b/project/vs2015.UWP/raylib.App.UWP/Assets/WideLogo.scale-100.png differ
diff --git a/project/vs2015.UWP/raylib.App.UWP/Package.appxmanifest b/project/vs2015.UWP/raylib.App.UWP/Package.appxmanifest
new file mode 100644
index 000000000..56020a505
--- /dev/null
+++ b/project/vs2015.UWP/raylib.App.UWP/Package.appxmanifest
@@ -0,0 +1,26 @@
+
+
+
+
+
+ raylibUWP
+ raysan5
+ Assets\StoreLogo.png
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/project/vs2015.UWP/raylib.App.UWP/packages.config b/project/vs2015.UWP/raylib.App.UWP/packages.config
new file mode 100644
index 000000000..70c3dea0e
--- /dev/null
+++ b/project/vs2015.UWP/raylib.App.UWP/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/project/vs2015.UWP/raylib.App.UWP/pch.cpp b/project/vs2015.UWP/raylib.App.UWP/pch.cpp
new file mode 100644
index 000000000..bcb5590be
--- /dev/null
+++ b/project/vs2015.UWP/raylib.App.UWP/pch.cpp
@@ -0,0 +1 @@
+#include "pch.h"
diff --git a/project/vs2015.UWP/raylib.App.UWP/pch.h b/project/vs2015.UWP/raylib.App.UWP/pch.h
new file mode 100644
index 000000000..dcbd23785
--- /dev/null
+++ b/project/vs2015.UWP/raylib.App.UWP/pch.h
@@ -0,0 +1,16 @@
+#pragma once
+
+#include
+#include
+
+// OpenGL ES includes
+#include
+#include
+
+// EGL includes
+#include
+#include
+#include
+
+// ANGLE include for Windows Store
+#include
\ No newline at end of file
diff --git a/project/vs2015.UWP/raylib.App.UWP/raylib.App.UWP.TemporaryKey.pfx b/project/vs2015.UWP/raylib.App.UWP/raylib.App.UWP.TemporaryKey.pfx
new file mode 100644
index 000000000..0ada3be01
Binary files /dev/null and b/project/vs2015.UWP/raylib.App.UWP/raylib.App.UWP.TemporaryKey.pfx differ
diff --git a/project/vs2015.UWP/raylib.App.UWP/raylib.App.UWP.filters b/project/vs2015.UWP/raylib.App.UWP/raylib.App.UWP.filters
new file mode 100644
index 000000000..4e83c9790
--- /dev/null
+++ b/project/vs2015.UWP/raylib.App.UWP/raylib.App.UWP.filters
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ Assets
+
+
+ Assets
+
+
+ Assets
+
+
+ Assets
+
+
+ Assets
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {d16954bb-de54-472b-ac10-ecab10d3fdc8}
+
+
+
\ No newline at end of file
diff --git a/project/vs2015.UWP/raylib.App.UWP/raylib.App.UWP.user b/project/vs2015.UWP/raylib.App.UWP/raylib.App.UWP.user
new file mode 100644
index 000000000..abe8dd896
--- /dev/null
+++ b/project/vs2015.UWP/raylib.App.UWP/raylib.App.UWP.user
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/project/vs2015.UWP/raylib.App.UWP/raylib.App.UWP.vcxproj b/project/vs2015.UWP/raylib.App.UWP/raylib.App.UWP.vcxproj
new file mode 100644
index 000000000..6af9db604
--- /dev/null
+++ b/project/vs2015.UWP/raylib.App.UWP/raylib.App.UWP.vcxproj
@@ -0,0 +1,145 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+ Debug
+ ARM
+
+
+ Release
+ ARM
+
+
+
+ {b842558c-c034-4e4b-9457-a286f26e83cc}
+ raylibUWP
+ en-US
+ 14.0
+ true
+ Windows Store
+ 10.0.14393.0
+ 10.0.14393.0
+ 10.0
+ raylib.App.UWP
+
+
+
+ Application
+ true
+ v140
+
+
+ Application
+ false
+ true
+ v140
+
+
+
+
+
+
+
+ raylib.App.UWP.TemporaryKey.pfx
+
+
+ C:\Users\Sam\Documents\GitHub\raylib\release\include;$(IncludePath)
+ C:\Users\Sam\Documents\GitHub\raylib\project\vs2015.UWP\raylib\Debug;$(LibraryPath)
+
+
+
+ mincore.lib;raylib.lib;%(AdditionalDependencies)
+ %(AdditionalLibraryDirectories);$(VCInstallDir)\lib\store\arm;$(VCInstallDir)\lib\arm
+
+
+
+
+ mincore.lib;raylib.lib;%(AdditionalDependencies)
+ $(SolutionDir)raylib\Debug;%(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store; $(VCInstallDir)\lib
+
+
+
+
+ mincore.lib;raylib.lib;%(AdditionalDependencies)
+ C:\Users\Sam\Documents\GitHub\raylib\project\vs2015.UWP\x64\Debug;C:\Users\Alumno\Downloads\angle\UWP_OpenGLES2\raylib;%(AdditionalLibraryDirectories);$(VCInstallDir)\lib\store\amd64;$(VCInstallDir)\lib\amd64
+
+
+
+
+ pch.h
+ $(IntDir)pch.pch
+ $(SolutionDir)..\..\src;$(ProjectDir);$(IntermediateOutputPath);%(AdditionalIncludeDirectories)
+ /bigobj %(AdditionalOptions)
+ 4453;28204
+ _DEBUG;%(PreprocessorDefinitions)
+
+
+ true
+
+
+
+
+ pch.h
+ $(IntDir)pch.pch
+ $(SolutionDir)..\..\src;$(ProjectDir);$(IntermediateOutputPath);%(AdditionalIncludeDirectories)
+ /bigobj %(AdditionalOptions)
+ 4453;28204
+ NDEBUG;%(PreprocessorDefinitions)
+ Default
+ false
+
+
+ /NODEFAULTLIB %(AdditionalOptions)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Create
+
+
+
+
+ Designer
+
+
+
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
\ No newline at end of file
diff --git a/project/vs2015.UWP/raylib.UWP.sln b/project/vs2015.UWP/raylib.UWP.sln
new file mode 100644
index 000000000..b2f95ca2a
--- /dev/null
+++ b/project/vs2015.UWP/raylib.UWP.sln
@@ -0,0 +1,50 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "raylib.App.UWP", "raylib.App.UWP\raylib.App.UWP.vcxproj", "{B842558C-C034-4E4B-9457-A286F26E83CC}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "raylib", "raylib\raylib.vcxproj", "{E89D61AC-55DE-4482-AFD4-DF7242EBC859}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|ARM = Debug|ARM
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|ARM = Release|ARM
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {B842558C-C034-4E4B-9457-A286F26E83CC}.Debug|ARM.ActiveCfg = Debug|ARM
+ {B842558C-C034-4E4B-9457-A286F26E83CC}.Debug|ARM.Build.0 = Debug|ARM
+ {B842558C-C034-4E4B-9457-A286F26E83CC}.Debug|ARM.Deploy.0 = Debug|ARM
+ {B842558C-C034-4E4B-9457-A286F26E83CC}.Debug|x64.ActiveCfg = Debug|x64
+ {B842558C-C034-4E4B-9457-A286F26E83CC}.Debug|x64.Build.0 = Debug|x64
+ {B842558C-C034-4E4B-9457-A286F26E83CC}.Debug|x64.Deploy.0 = Debug|x64
+ {B842558C-C034-4E4B-9457-A286F26E83CC}.Debug|x86.ActiveCfg = Debug|Win32
+ {B842558C-C034-4E4B-9457-A286F26E83CC}.Debug|x86.Build.0 = Debug|Win32
+ {B842558C-C034-4E4B-9457-A286F26E83CC}.Debug|x86.Deploy.0 = Debug|Win32
+ {B842558C-C034-4E4B-9457-A286F26E83CC}.Release|ARM.ActiveCfg = Release|ARM
+ {B842558C-C034-4E4B-9457-A286F26E83CC}.Release|ARM.Build.0 = Release|ARM
+ {B842558C-C034-4E4B-9457-A286F26E83CC}.Release|ARM.Deploy.0 = Release|ARM
+ {B842558C-C034-4E4B-9457-A286F26E83CC}.Release|x64.ActiveCfg = Release|x64
+ {B842558C-C034-4E4B-9457-A286F26E83CC}.Release|x64.Build.0 = Release|x64
+ {B842558C-C034-4E4B-9457-A286F26E83CC}.Release|x64.Deploy.0 = Release|x64
+ {B842558C-C034-4E4B-9457-A286F26E83CC}.Release|x86.ActiveCfg = Release|Win32
+ {B842558C-C034-4E4B-9457-A286F26E83CC}.Release|x86.Build.0 = Release|Win32
+ {B842558C-C034-4E4B-9457-A286F26E83CC}.Release|x86.Deploy.0 = Release|Win32
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug|ARM.ActiveCfg = Debug|Win32
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug|x64.ActiveCfg = Debug|x64
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug|x86.ActiveCfg = Debug|Win32
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug|x86.Build.0 = Debug|Win32
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release|ARM.ActiveCfg = Release|Win32
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release|x64.ActiveCfg = Release|Win32
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release|x86.ActiveCfg = Release|Win32
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/project/vs2015.UWP/raylib/raylib.vcxproj b/project/vs2015.UWP/raylib/raylib.vcxproj
new file mode 100644
index 000000000..c1fbca500
--- /dev/null
+++ b/project/vs2015.UWP/raylib/raylib.vcxproj
@@ -0,0 +1,186 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}
+ Win32Proj
+ raylib
+ 10.0.16299.0
+
+
+
+ StaticLibrary
+ true
+ v140
+ Unicode
+
+
+ StaticLibrary
+ true
+ v140
+ Unicode
+
+
+ StaticLibrary
+ false
+ v140
+ true
+ Unicode
+
+
+ StaticLibrary
+ false
+ v140
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(SolutionDir)$(ProjectName)\$(Configuration)\
+
+
+
+ $(SolutionDir)$(ProjectName)\$(Configuration)\
+ $(SolutionDir)$(ProjectName)\$(Configuration)\temp
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_ES2;PLATFORM_UWP
+ CompileAsC
+ $(SolutionDir)..\..\release\include;$(SolutionDir)..\..\src\external\ANGLE
+
+
+ Windows
+
+
+ %(AdditionalLibraryDirectories)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_ES2;PLATFORM_UWP
+ CompileAsC
+ $(SolutionDir)..\..\release\include;$(SolutionDir)..\..\src\external\include\ANGLE
+
+
+ Windows
+
+
+ %(AdditionalLibraryDirectories)
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_ES2;PLATFORM_UWP
+ $(SolutionDir)..\..\src\external\ANGLE;$(SolutionDir)..\..\release\include
+ CompileAsC
+
+
+ Windows
+ true
+ true
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_ES2;PLATFORM_UWP
+ $(SolutionDir)..\..\src\external\include\ANGLE;$(SolutionDir)..\..\release\include
+ CompileAsC
+
+
+ Windows
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/project/vs2015/examples/core_basic_window.vcxproj b/project/vs2015/examples/core_basic_window.vcxproj
index 2e8ed67ff..a5b484954 100644
--- a/project/vs2015/examples/core_basic_window.vcxproj
+++ b/project/vs2015/examples/core_basic_window.vcxproj
@@ -1,10 +1,18 @@

+
+ Debug_DLL
+ Win32
+
Debug
Win32
+
+ Release_DLL
+ Win32
+
Release
Win32
@@ -24,6 +32,12 @@
v140
Unicode
+
+ Application
+ true
+ v140
+ Unicode
+
Application
false
@@ -31,6 +45,13 @@
true
Unicode
+
+ Application
+ false
+ v140
+ true
+ Unicode
+
@@ -39,20 +60,36 @@
+
+
+
+
+
+
true
$(ProjectDir)$(ProjectName)\$(Configuration)\
$(ProjectDir)$(ProjectName)\$(Configuration)\temp
+
+ true
+ $(ProjectDir)$(ProjectName)\$(Configuration)\
+ $(ProjectDir)$(ProjectName)\$(Configuration)\temp
+
false
$(ProjectDir)$(ProjectName)\$(Configuration)\
$(ProjectDir)$(ProjectName)\$(Configuration)\temp
+
+ false
+ $(ProjectDir)$(ProjectName)\$(Configuration)\
+ $(ProjectDir)$(ProjectName)\$(Configuration)\temp
+
@@ -61,13 +98,30 @@
Disabled
WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
CompileAsC
- $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ $(SolutionDir)..\..\release\include;%(AdditionalIncludeDirectories)
Console
true
- $(SolutionDir)external\glfw3\lib\win32;$(SolutionDir)external\openal_soft\lib\win32;%(AdditionalLibraryDirectories)
- kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;glfw3.lib;%(AdditionalDependencies)
+ $(SolutionDir)..\..\release\libs\win32\msvc;%(AdditionalLibraryDirectories)
+ kernel32.lib;user32.lib;gdi32.lib;opengl32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\release\include;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)..\..\release\libs\win32\msvc;%(AdditionalLibraryDirectories)
+ kernel32.lib;user32.lib;gdi32.lib;opengl32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
@@ -79,7 +133,7 @@
true
true
WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
- $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ $(SolutionDir)..\..\release\include;%(AdditionalIncludeDirectories)
CompileAsC
true
@@ -88,8 +142,30 @@
true
true
true
- kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;glfw3.lib;%(AdditionalDependencies)
- $(SolutionDir)external\glfw3\lib\win32;$(SolutionDir)external\openal_soft\lib\win32;%(AdditionalLibraryDirectories)
+ kernel32.lib;user32.lib;gdi32.lib;opengl32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)..\..\release\libs\win32\msvc;%(AdditionalLibraryDirectories)
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\release\include;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ kernel32.lib;user32.lib;gdi32.lib;opengl32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)..\..\release\libs\win32\msvc;%(AdditionalLibraryDirectories)
diff --git a/project/vs2015/examples/core_basic_window_cpp.vcxproj b/project/vs2015/examples/core_basic_window_cpp.vcxproj
index 49c212281..90379fe5f 100644
--- a/project/vs2015/examples/core_basic_window_cpp.vcxproj
+++ b/project/vs2015/examples/core_basic_window_cpp.vcxproj
@@ -1,10 +1,18 @@

+
+ Debug_DLL
+ Win32
+
Debug
Win32
+
+ Release_DLL
+ Win32
+
Release
Win32
@@ -24,6 +32,12 @@
v140
Unicode
+
+ Application
+ true
+ v140
+ Unicode
+
Application
false
@@ -31,6 +45,13 @@
true
Unicode
+
+ Application
+ false
+ v140
+ true
+ Unicode
+
@@ -39,20 +60,36 @@
+
+
+
+
+
+
true
$(ProjectDir)$(ProjectName)\$(Configuration)
$(ProjectDir)$(ProjectName)\$(Configuration)\temp
+
+ true
+ $(ProjectDir)$(ProjectName)\$(Configuration)
+ $(ProjectDir)$(ProjectName)\$(Configuration)\temp
+
false
$(ProjectDir)$(ProjectName)\$(Configuration)
$(ProjectDir)$(ProjectName)\$(Configuration)\temp
+
+ false
+ $(ProjectDir)$(ProjectName)\$(Configuration)
+ $(ProjectDir)$(ProjectName)\$(Configuration)\temp
+
@@ -60,14 +97,31 @@
Level3
Disabled
WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
- $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ $(SolutionDir)..\..\release\include;%(AdditionalIncludeDirectories)
CompileAsCpp
Console
true
- kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;glfw3.lib;%(AdditionalDependencies)
- $(SolutionDir)external\glfw3\lib\win32;%(AdditionalLibraryDirectories)
+ kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)..\..\release\libs\win32\msvc;%(AdditionalLibraryDirectories)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ $(SolutionDir)..\..\release\include;%(AdditionalIncludeDirectories)
+ CompileAsCpp
+
+
+ Console
+ true
+ kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)..\..\release\libs\win32\msvc;%(AdditionalLibraryDirectories)
@@ -80,15 +134,36 @@
true
WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
CompileAsCpp
- $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ $(SolutionDir)..\..\release\include;%(AdditionalIncludeDirectories)
Console
true
true
true
- $(SolutionDir)external\glfw3\lib\win32;%(AdditionalLibraryDirectories)
- kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;glfw3.lib;%(AdditionalDependencies)
+ $(SolutionDir)..\..\release\libs\win32\msvc;%(AdditionalLibraryDirectories)
+ kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ CompileAsCpp
+ $(SolutionDir)..\..\release\include;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ true
+ true
+ $(SolutionDir)..\..\release\libs\win32\msvc;%(AdditionalLibraryDirectories)
+ kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
diff --git a/project/vs2015/external/glfw3/COPYING.txt b/project/vs2015/external/glfw3/COPYING.txt
deleted file mode 100644
index ad16462a9..000000000
--- a/project/vs2015/external/glfw3/COPYING.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-Copyright (c) 2002-2006 Marcus Geelnard
-Copyright (c) 2006-2016 Camilla Berglund
-
-This software is provided 'as-is', without any express or implied
-warranty. In no event will the authors be held liable for any damages
-arising from the use of this software.
-
-Permission is granted to anyone to use this software for any purpose,
-including commercial applications, and to alter it and redistribute it
-freely, subject to the following restrictions:
-
-1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would
- be appreciated but is not required.
-
-2. Altered source versions must be plainly marked as such, and must not
- be misrepresented as being the original software.
-
-3. This notice may not be removed or altered from any source
- distribution.
-
diff --git a/project/vs2015/external/glfw3/include/GLFW/glfw3.h b/project/vs2015/external/glfw3/include/GLFW/glfw3.h
deleted file mode 100644
index 5a0c45089..000000000
--- a/project/vs2015/external/glfw3/include/GLFW/glfw3.h
+++ /dev/null
@@ -1,4235 +0,0 @@
-/*************************************************************************
- * GLFW 3.2 - www.glfw.org
- * A library for OpenGL, window and input
- *------------------------------------------------------------------------
- * Copyright (c) 2002-2006 Marcus Geelnard
- * Copyright (c) 2006-2016 Camilla Berglund
- *
- * This software is provided 'as-is', without any express or implied
- * warranty. In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- * claim that you wrote the original software. If you use this software
- * in a product, an acknowledgment in the product documentation would
- * be appreciated but is not required.
- *
- * 2. Altered source versions must be plainly marked as such, and must not
- * be misrepresented as being the original software.
- *
- * 3. This notice may not be removed or altered from any source
- * distribution.
- *
- *************************************************************************/
-
-#ifndef _glfw3_h_
-#define _glfw3_h_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*************************************************************************
- * Doxygen documentation
- *************************************************************************/
-
-/*! @file glfw3.h
- * @brief The header of the GLFW 3 API.
- *
- * This is the header file of the GLFW 3 API. It defines all its types and
- * declares all its functions.
- *
- * For more information about how to use this file, see @ref build_include.
- */
-/*! @defgroup context Context reference
- *
- * This is the reference documentation for OpenGL and OpenGL ES context related
- * functions. For more task-oriented information, see the @ref context_guide.
- */
-/*! @defgroup vulkan Vulkan reference
- *
- * This is the reference documentation for Vulkan related functions and types.
- * For more task-oriented information, see the @ref vulkan_guide.
- */
-/*! @defgroup init Initialization, version and error reference
- *
- * This is the reference documentation for initialization and termination of
- * the library, version management and error handling. For more task-oriented
- * information, see the @ref intro_guide.
- */
-/*! @defgroup input Input reference
- *
- * This is the reference documentation for input related functions and types.
- * For more task-oriented information, see the @ref input_guide.
- */
-/*! @defgroup monitor Monitor reference
- *
- * This is the reference documentation for monitor related functions and types.
- * For more task-oriented information, see the @ref monitor_guide.
- */
-/*! @defgroup window Window reference
- *
- * This is the reference documentation for window related functions and types,
- * including creation, deletion and event polling. For more task-oriented
- * information, see the @ref window_guide.
- */
-
-
-/*************************************************************************
- * Compiler- and platform-specific preprocessor work
- *************************************************************************/
-
-/* If we are we on Windows, we want a single define for it.
- */
-#if !defined(_WIN32) && (defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__))
- #define _WIN32
-#endif /* _WIN32 */
-
-/* It is customary to use APIENTRY for OpenGL function pointer declarations on
- * all platforms. Additionally, the Windows OpenGL header needs APIENTRY.
- */
-#ifndef APIENTRY
- #ifdef _WIN32
- #define APIENTRY __stdcall
- #else
- #define APIENTRY
- #endif
-#endif /* APIENTRY */
-
-/* Some Windows OpenGL headers need this.
- */
-#if !defined(WINGDIAPI) && defined(_WIN32)
- #define WINGDIAPI __declspec(dllimport)
- #define GLFW_WINGDIAPI_DEFINED
-#endif /* WINGDIAPI */
-
-/* Some Windows GLU headers need this.
- */
-#if !defined(CALLBACK) && defined(_WIN32)
- #define CALLBACK __stdcall
- #define GLFW_CALLBACK_DEFINED
-#endif /* CALLBACK */
-
-/* Most Windows GLU headers need wchar_t.
- * The OS X OpenGL header blocks the definition of ptrdiff_t by glext.h.
- * Include it unconditionally to avoid surprising side-effects.
- */
-#include
-#include
-
-/* Include the chosen client API headers.
- */
-#if defined(__APPLE__)
- #if defined(GLFW_INCLUDE_GLCOREARB)
- #include
- #if defined(GLFW_INCLUDE_GLEXT)
- #include
- #endif
- #elif !defined(GLFW_INCLUDE_NONE)
- #if !defined(GLFW_INCLUDE_GLEXT)
- #define GL_GLEXT_LEGACY
- #endif
- #include
- #endif
- #if defined(GLFW_INCLUDE_GLU)
- #include
- #endif
-#else
- #if defined(GLFW_INCLUDE_GLCOREARB)
- #include
- #elif defined(GLFW_INCLUDE_ES1)
- #include
- #if defined(GLFW_INCLUDE_GLEXT)
- #include
- #endif
- #elif defined(GLFW_INCLUDE_ES2)
- #include
- #if defined(GLFW_INCLUDE_GLEXT)
- #include
- #endif
- #elif defined(GLFW_INCLUDE_ES3)
- #include
- #if defined(GLFW_INCLUDE_GLEXT)
- #include
- #endif
- #elif defined(GLFW_INCLUDE_ES31)
- #include
- #if defined(GLFW_INCLUDE_GLEXT)
- #include
- #endif
- #elif defined(GLFW_INCLUDE_VULKAN)
- #include
- #elif !defined(GLFW_INCLUDE_NONE)
- #include
- #if defined(GLFW_INCLUDE_GLEXT)
- #include
- #endif
- #endif
- #if defined(GLFW_INCLUDE_GLU)
- #include
- #endif
-#endif
-
-#if defined(GLFW_DLL) && defined(_GLFW_BUILD_DLL)
- /* GLFW_DLL must be defined by applications that are linking against the DLL
- * version of the GLFW library. _GLFW_BUILD_DLL is defined by the GLFW
- * configuration header when compiling the DLL version of the library.
- */
- #error "You must not have both GLFW_DLL and _GLFW_BUILD_DLL defined"
-#endif
-
-/* GLFWAPI is used to declare public API functions for export
- * from the DLL / shared library / dynamic library.
- */
-#if defined(_WIN32) && defined(_GLFW_BUILD_DLL)
- /* We are building GLFW as a Win32 DLL */
- #define GLFWAPI __declspec(dllexport)
-#elif defined(_WIN32) && defined(GLFW_DLL)
- /* We are calling GLFW as a Win32 DLL */
- #define GLFWAPI __declspec(dllimport)
-#elif defined(__GNUC__) && defined(_GLFW_BUILD_DLL)
- /* We are building GLFW as a shared / dynamic library */
- #define GLFWAPI __attribute__((visibility("default")))
-#else
- /* We are building or calling GLFW as a static library */
- #define GLFWAPI
-#endif
-
-
-/*************************************************************************
- * GLFW API tokens
- *************************************************************************/
-
-/*! @name GLFW version macros
- * @{ */
-/*! @brief The major version number of the GLFW library.
- *
- * This is incremented when the API is changed in non-compatible ways.
- * @ingroup init
- */
-#define GLFW_VERSION_MAJOR 3
-/*! @brief The minor version number of the GLFW library.
- *
- * This is incremented when features are added to the API but it remains
- * backward-compatible.
- * @ingroup init
- */
-#define GLFW_VERSION_MINOR 2
-/*! @brief The revision number of the GLFW library.
- *
- * This is incremented when a bug fix release is made that does not contain any
- * API changes.
- * @ingroup init
- */
-#define GLFW_VERSION_REVISION 0
-/*! @} */
-
-/*! @name Boolean values
- * @{ */
-/*! @brief One.
- *
- * One. Seriously. You don't _need_ to use this symbol in your code. It's
- * just semantic sugar for the number 1. You can use `1` or `true` or `_True`
- * or `GL_TRUE` or whatever you want.
- */
-#define GLFW_TRUE 1
-/*! @brief Zero.
- *
- * Zero. Seriously. You don't _need_ to use this symbol in your code. It's
- * just just semantic sugar for the number 0. You can use `0` or `false` or
- * `_False` or `GL_FALSE` or whatever you want.
- */
-#define GLFW_FALSE 0
-/*! @} */
-
-/*! @name Key and button actions
- * @{ */
-/*! @brief The key or mouse button was released.
- *
- * The key or mouse button was released.
- *
- * @ingroup input
- */
-#define GLFW_RELEASE 0
-/*! @brief The key or mouse button was pressed.
- *
- * The key or mouse button was pressed.
- *
- * @ingroup input
- */
-#define GLFW_PRESS 1
-/*! @brief The key was held down until it repeated.
- *
- * The key was held down until it repeated.
- *
- * @ingroup input
- */
-#define GLFW_REPEAT 2
-/*! @} */
-
-/*! @defgroup keys Keyboard keys
- *
- * See [key input](@ref input_key) for how these are used.
- *
- * These key codes are inspired by the _USB HID Usage Tables v1.12_ (p. 53-60),
- * but re-arranged to map to 7-bit ASCII for printable keys (function keys are
- * put in the 256+ range).
- *
- * The naming of the key codes follow these rules:
- * - The US keyboard layout is used
- * - Names of printable alpha-numeric characters are used (e.g. "A", "R",
- * "3", etc.)
- * - For non-alphanumeric characters, Unicode:ish names are used (e.g.
- * "COMMA", "LEFT_SQUARE_BRACKET", etc.). Note that some names do not
- * correspond to the Unicode standard (usually for brevity)
- * - Keys that lack a clear US mapping are named "WORLD_x"
- * - For non-printable keys, custom names are used (e.g. "F4",
- * "BACKSPACE", etc.)
- *
- * @ingroup input
- * @{
- */
-
-/* The unknown key */
-#define GLFW_KEY_UNKNOWN -1
-
-/* Printable keys */
-#define GLFW_KEY_SPACE 32
-#define GLFW_KEY_APOSTROPHE 39 /* ' */
-#define GLFW_KEY_COMMA 44 /* , */
-#define GLFW_KEY_MINUS 45 /* - */
-#define GLFW_KEY_PERIOD 46 /* . */
-#define GLFW_KEY_SLASH 47 /* / */
-#define GLFW_KEY_0 48
-#define GLFW_KEY_1 49
-#define GLFW_KEY_2 50
-#define GLFW_KEY_3 51
-#define GLFW_KEY_4 52
-#define GLFW_KEY_5 53
-#define GLFW_KEY_6 54
-#define GLFW_KEY_7 55
-#define GLFW_KEY_8 56
-#define GLFW_KEY_9 57
-#define GLFW_KEY_SEMICOLON 59 /* ; */
-#define GLFW_KEY_EQUAL 61 /* = */
-#define GLFW_KEY_A 65
-#define GLFW_KEY_B 66
-#define GLFW_KEY_C 67
-#define GLFW_KEY_D 68
-#define GLFW_KEY_E 69
-#define GLFW_KEY_F 70
-#define GLFW_KEY_G 71
-#define GLFW_KEY_H 72
-#define GLFW_KEY_I 73
-#define GLFW_KEY_J 74
-#define GLFW_KEY_K 75
-#define GLFW_KEY_L 76
-#define GLFW_KEY_M 77
-#define GLFW_KEY_N 78
-#define GLFW_KEY_O 79
-#define GLFW_KEY_P 80
-#define GLFW_KEY_Q 81
-#define GLFW_KEY_R 82
-#define GLFW_KEY_S 83
-#define GLFW_KEY_T 84
-#define GLFW_KEY_U 85
-#define GLFW_KEY_V 86
-#define GLFW_KEY_W 87
-#define GLFW_KEY_X 88
-#define GLFW_KEY_Y 89
-#define GLFW_KEY_Z 90
-#define GLFW_KEY_LEFT_BRACKET 91 /* [ */
-#define GLFW_KEY_BACKSLASH 92 /* \ */
-#define GLFW_KEY_RIGHT_BRACKET 93 /* ] */
-#define GLFW_KEY_GRAVE_ACCENT 96 /* ` */
-#define GLFW_KEY_WORLD_1 161 /* non-US #1 */
-#define GLFW_KEY_WORLD_2 162 /* non-US #2 */
-
-/* Function keys */
-#define GLFW_KEY_ESCAPE 256
-#define GLFW_KEY_ENTER 257
-#define GLFW_KEY_TAB 258
-#define GLFW_KEY_BACKSPACE 259
-#define GLFW_KEY_INSERT 260
-#define GLFW_KEY_DELETE 261
-#define GLFW_KEY_RIGHT 262
-#define GLFW_KEY_LEFT 263
-#define GLFW_KEY_DOWN 264
-#define GLFW_KEY_UP 265
-#define GLFW_KEY_PAGE_UP 266
-#define GLFW_KEY_PAGE_DOWN 267
-#define GLFW_KEY_HOME 268
-#define GLFW_KEY_END 269
-#define GLFW_KEY_CAPS_LOCK 280
-#define GLFW_KEY_SCROLL_LOCK 281
-#define GLFW_KEY_NUM_LOCK 282
-#define GLFW_KEY_PRINT_SCREEN 283
-#define GLFW_KEY_PAUSE 284
-#define GLFW_KEY_F1 290
-#define GLFW_KEY_F2 291
-#define GLFW_KEY_F3 292
-#define GLFW_KEY_F4 293
-#define GLFW_KEY_F5 294
-#define GLFW_KEY_F6 295
-#define GLFW_KEY_F7 296
-#define GLFW_KEY_F8 297
-#define GLFW_KEY_F9 298
-#define GLFW_KEY_F10 299
-#define GLFW_KEY_F11 300
-#define GLFW_KEY_F12 301
-#define GLFW_KEY_F13 302
-#define GLFW_KEY_F14 303
-#define GLFW_KEY_F15 304
-#define GLFW_KEY_F16 305
-#define GLFW_KEY_F17 306
-#define GLFW_KEY_F18 307
-#define GLFW_KEY_F19 308
-#define GLFW_KEY_F20 309
-#define GLFW_KEY_F21 310
-#define GLFW_KEY_F22 311
-#define GLFW_KEY_F23 312
-#define GLFW_KEY_F24 313
-#define GLFW_KEY_F25 314
-#define GLFW_KEY_KP_0 320
-#define GLFW_KEY_KP_1 321
-#define GLFW_KEY_KP_2 322
-#define GLFW_KEY_KP_3 323
-#define GLFW_KEY_KP_4 324
-#define GLFW_KEY_KP_5 325
-#define GLFW_KEY_KP_6 326
-#define GLFW_KEY_KP_7 327
-#define GLFW_KEY_KP_8 328
-#define GLFW_KEY_KP_9 329
-#define GLFW_KEY_KP_DECIMAL 330
-#define GLFW_KEY_KP_DIVIDE 331
-#define GLFW_KEY_KP_MULTIPLY 332
-#define GLFW_KEY_KP_SUBTRACT 333
-#define GLFW_KEY_KP_ADD 334
-#define GLFW_KEY_KP_ENTER 335
-#define GLFW_KEY_KP_EQUAL 336
-#define GLFW_KEY_LEFT_SHIFT 340
-#define GLFW_KEY_LEFT_CONTROL 341
-#define GLFW_KEY_LEFT_ALT 342
-#define GLFW_KEY_LEFT_SUPER 343
-#define GLFW_KEY_RIGHT_SHIFT 344
-#define GLFW_KEY_RIGHT_CONTROL 345
-#define GLFW_KEY_RIGHT_ALT 346
-#define GLFW_KEY_RIGHT_SUPER 347
-#define GLFW_KEY_MENU 348
-
-#define GLFW_KEY_LAST GLFW_KEY_MENU
-
-/*! @} */
-
-/*! @defgroup mods Modifier key flags
- *
- * See [key input](@ref input_key) for how these are used.
- *
- * @ingroup input
- * @{ */
-
-/*! @brief If this bit is set one or more Shift keys were held down.
- */
-#define GLFW_MOD_SHIFT 0x0001
-/*! @brief If this bit is set one or more Control keys were held down.
- */
-#define GLFW_MOD_CONTROL 0x0002
-/*! @brief If this bit is set one or more Alt keys were held down.
- */
-#define GLFW_MOD_ALT 0x0004
-/*! @brief If this bit is set one or more Super keys were held down.
- */
-#define GLFW_MOD_SUPER 0x0008
-
-/*! @} */
-
-/*! @defgroup buttons Mouse buttons
- *
- * See [mouse button input](@ref input_mouse_button) for how these are used.
- *
- * @ingroup input
- * @{ */
-#define GLFW_MOUSE_BUTTON_1 0
-#define GLFW_MOUSE_BUTTON_2 1
-#define GLFW_MOUSE_BUTTON_3 2
-#define GLFW_MOUSE_BUTTON_4 3
-#define GLFW_MOUSE_BUTTON_5 4
-#define GLFW_MOUSE_BUTTON_6 5
-#define GLFW_MOUSE_BUTTON_7 6
-#define GLFW_MOUSE_BUTTON_8 7
-#define GLFW_MOUSE_BUTTON_LAST GLFW_MOUSE_BUTTON_8
-#define GLFW_MOUSE_BUTTON_LEFT GLFW_MOUSE_BUTTON_1
-#define GLFW_MOUSE_BUTTON_RIGHT GLFW_MOUSE_BUTTON_2
-#define GLFW_MOUSE_BUTTON_MIDDLE GLFW_MOUSE_BUTTON_3
-/*! @} */
-
-/*! @defgroup joysticks Joysticks
- *
- * See [joystick input](@ref joystick) for how these are used.
- *
- * @ingroup input
- * @{ */
-#define GLFW_JOYSTICK_1 0
-#define GLFW_JOYSTICK_2 1
-#define GLFW_JOYSTICK_3 2
-#define GLFW_JOYSTICK_4 3
-#define GLFW_JOYSTICK_5 4
-#define GLFW_JOYSTICK_6 5
-#define GLFW_JOYSTICK_7 6
-#define GLFW_JOYSTICK_8 7
-#define GLFW_JOYSTICK_9 8
-#define GLFW_JOYSTICK_10 9
-#define GLFW_JOYSTICK_11 10
-#define GLFW_JOYSTICK_12 11
-#define GLFW_JOYSTICK_13 12
-#define GLFW_JOYSTICK_14 13
-#define GLFW_JOYSTICK_15 14
-#define GLFW_JOYSTICK_16 15
-#define GLFW_JOYSTICK_LAST GLFW_JOYSTICK_16
-/*! @} */
-
-/*! @defgroup errors Error codes
- *
- * See [error handling](@ref error_handling) for how these are used.
- *
- * @ingroup init
- * @{ */
-/*! @brief GLFW has not been initialized.
- *
- * This occurs if a GLFW function was called that must not be called unless the
- * library is [initialized](@ref intro_init).
- *
- * @analysis Application programmer error. Initialize GLFW before calling any
- * function that requires initialization.
- */
-#define GLFW_NOT_INITIALIZED 0x00010001
-/*! @brief No context is current for this thread.
- *
- * This occurs if a GLFW function was called that needs and operates on the
- * current OpenGL or OpenGL ES context but no context is current on the calling
- * thread. One such function is @ref glfwSwapInterval.
- *
- * @analysis Application programmer error. Ensure a context is current before
- * calling functions that require a current context.
- */
-#define GLFW_NO_CURRENT_CONTEXT 0x00010002
-/*! @brief One of the arguments to the function was an invalid enum value.
- *
- * One of the arguments to the function was an invalid enum value, for example
- * requesting [GLFW_RED_BITS](@ref window_hints_fb) with @ref
- * glfwGetWindowAttrib.
- *
- * @analysis Application programmer error. Fix the offending call.
- */
-#define GLFW_INVALID_ENUM 0x00010003
-/*! @brief One of the arguments to the function was an invalid value.
- *
- * One of the arguments to the function was an invalid value, for example
- * requesting a non-existent OpenGL or OpenGL ES version like 2.7.
- *
- * Requesting a valid but unavailable OpenGL or OpenGL ES version will instead
- * result in a @ref GLFW_VERSION_UNAVAILABLE error.
- *
- * @analysis Application programmer error. Fix the offending call.
- */
-#define GLFW_INVALID_VALUE 0x00010004
-/*! @brief A memory allocation failed.
- *
- * A memory allocation failed.
- *
- * @analysis A bug in GLFW or the underlying operating system. Report the bug
- * to our [issue tracker](https://github.com/glfw/glfw/issues).
- */
-#define GLFW_OUT_OF_MEMORY 0x00010005
-/*! @brief GLFW could not find support for the requested API on the system.
- *
- * GLFW could not find support for the requested API on the system.
- *
- * @analysis The installed graphics driver does not support the requested
- * API, or does not support it via the chosen context creation backend.
- * Below are a few examples.
- *
- * @par
- * Some pre-installed Windows graphics drivers do not support OpenGL. AMD only
- * supports OpenGL ES via EGL, while Nvidia and Intel only support it via
- * a WGL or GLX extension. OS X does not provide OpenGL ES at all. The Mesa
- * EGL, OpenGL and OpenGL ES libraries do not interface with the Nvidia binary
- * driver. Older graphics drivers do not support Vulkan.
- */
-#define GLFW_API_UNAVAILABLE 0x00010006
-/*! @brief The requested OpenGL or OpenGL ES version is not available.
- *
- * The requested OpenGL or OpenGL ES version (including any requested context
- * or framebuffer hints) is not available on this machine.
- *
- * @analysis The machine does not support your requirements. If your
- * application is sufficiently flexible, downgrade your requirements and try
- * again. Otherwise, inform the user that their machine does not match your
- * requirements.
- *
- * @par
- * Future invalid OpenGL and OpenGL ES versions, for example OpenGL 4.8 if 5.0
- * comes out before the 4.x series gets that far, also fail with this error and
- * not @ref GLFW_INVALID_VALUE, because GLFW cannot know what future versions
- * will exist.
- */
-#define GLFW_VERSION_UNAVAILABLE 0x00010007
-/*! @brief A platform-specific error occurred that does not match any of the
- * more specific categories.
- *
- * A platform-specific error occurred that does not match any of the more
- * specific categories.
- *
- * @analysis A bug or configuration error in GLFW, the underlying operating
- * system or its drivers, or a lack of required resources. Report the issue to
- * our [issue tracker](https://github.com/glfw/glfw/issues).
- */
-#define GLFW_PLATFORM_ERROR 0x00010008
-/*! @brief The requested format is not supported or available.
- *
- * If emitted during window creation, the requested pixel format is not
- * supported.
- *
- * If emitted when querying the clipboard, the contents of the clipboard could
- * not be converted to the requested format.
- *
- * @analysis If emitted during window creation, one or more
- * [hard constraints](@ref window_hints_hard) did not match any of the
- * available pixel formats. If your application is sufficiently flexible,
- * downgrade your requirements and try again. Otherwise, inform the user that
- * their machine does not match your requirements.
- *
- * @par
- * If emitted when querying the clipboard, ignore the error or report it to
- * the user, as appropriate.
- */
-#define GLFW_FORMAT_UNAVAILABLE 0x00010009
-/*! @brief The specified window does not have an OpenGL or OpenGL ES context.
- *
- * A window that does not have an OpenGL or OpenGL ES context was passed to
- * a function that requires it to have one.
- *
- * @analysis Application programmer error. Fix the offending call.
- */
-#define GLFW_NO_WINDOW_CONTEXT 0x0001000A
-/*! @} */
-
-#define GLFW_FOCUSED 0x00020001
-#define GLFW_ICONIFIED 0x00020002
-#define GLFW_RESIZABLE 0x00020003
-#define GLFW_VISIBLE 0x00020004
-#define GLFW_DECORATED 0x00020005
-#define GLFW_AUTO_ICONIFY 0x00020006
-#define GLFW_FLOATING 0x00020007
-#define GLFW_MAXIMIZED 0x00020008
-
-#define GLFW_RED_BITS 0x00021001
-#define GLFW_GREEN_BITS 0x00021002
-#define GLFW_BLUE_BITS 0x00021003
-#define GLFW_ALPHA_BITS 0x00021004
-#define GLFW_DEPTH_BITS 0x00021005
-#define GLFW_STENCIL_BITS 0x00021006
-#define GLFW_ACCUM_RED_BITS 0x00021007
-#define GLFW_ACCUM_GREEN_BITS 0x00021008
-#define GLFW_ACCUM_BLUE_BITS 0x00021009
-#define GLFW_ACCUM_ALPHA_BITS 0x0002100A
-#define GLFW_AUX_BUFFERS 0x0002100B
-#define GLFW_STEREO 0x0002100C
-#define GLFW_SAMPLES 0x0002100D
-#define GLFW_SRGB_CAPABLE 0x0002100E
-#define GLFW_REFRESH_RATE 0x0002100F
-#define GLFW_DOUBLEBUFFER 0x00021010
-
-#define GLFW_CLIENT_API 0x00022001
-#define GLFW_CONTEXT_VERSION_MAJOR 0x00022002
-#define GLFW_CONTEXT_VERSION_MINOR 0x00022003
-#define GLFW_CONTEXT_REVISION 0x00022004
-#define GLFW_CONTEXT_ROBUSTNESS 0x00022005
-#define GLFW_OPENGL_FORWARD_COMPAT 0x00022006
-#define GLFW_OPENGL_DEBUG_CONTEXT 0x00022007
-#define GLFW_OPENGL_PROFILE 0x00022008
-#define GLFW_CONTEXT_RELEASE_BEHAVIOR 0x00022009
-#define GLFW_CONTEXT_NO_ERROR 0x0002200A
-#define GLFW_CONTEXT_CREATION_API 0x0002200B
-
-#define GLFW_NO_API 0
-#define GLFW_OPENGL_API 0x00030001
-#define GLFW_OPENGL_ES_API 0x00030002
-
-#define GLFW_NO_ROBUSTNESS 0
-#define GLFW_NO_RESET_NOTIFICATION 0x00031001
-#define GLFW_LOSE_CONTEXT_ON_RESET 0x00031002
-
-#define GLFW_OPENGL_ANY_PROFILE 0
-#define GLFW_OPENGL_CORE_PROFILE 0x00032001
-#define GLFW_OPENGL_COMPAT_PROFILE 0x00032002
-
-#define GLFW_CURSOR 0x00033001
-#define GLFW_STICKY_KEYS 0x00033002
-#define GLFW_STICKY_MOUSE_BUTTONS 0x00033003
-
-#define GLFW_CURSOR_NORMAL 0x00034001
-#define GLFW_CURSOR_HIDDEN 0x00034002
-#define GLFW_CURSOR_DISABLED 0x00034003
-
-#define GLFW_ANY_RELEASE_BEHAVIOR 0
-#define GLFW_RELEASE_BEHAVIOR_FLUSH 0x00035001
-#define GLFW_RELEASE_BEHAVIOR_NONE 0x00035002
-
-#define GLFW_NATIVE_CONTEXT_API 0x00036001
-#define GLFW_EGL_CONTEXT_API 0x00036002
-
-/*! @defgroup shapes Standard cursor shapes
- *
- * See [standard cursor creation](@ref cursor_standard) for how these are used.
- *
- * @ingroup input
- * @{ */
-
-/*! @brief The regular arrow cursor shape.
- *
- * The regular arrow cursor.
- */
-#define GLFW_ARROW_CURSOR 0x00036001
-/*! @brief The text input I-beam cursor shape.
- *
- * The text input I-beam cursor shape.
- */
-#define GLFW_IBEAM_CURSOR 0x00036002
-/*! @brief The crosshair shape.
- *
- * The crosshair shape.
- */
-#define GLFW_CROSSHAIR_CURSOR 0x00036003
-/*! @brief The hand shape.
- *
- * The hand shape.
- */
-#define GLFW_HAND_CURSOR 0x00036004
-/*! @brief The horizontal resize arrow shape.
- *
- * The horizontal resize arrow shape.
- */
-#define GLFW_HRESIZE_CURSOR 0x00036005
-/*! @brief The vertical resize arrow shape.
- *
- * The vertical resize arrow shape.
- */
-#define GLFW_VRESIZE_CURSOR 0x00036006
-/*! @} */
-
-#define GLFW_CONNECTED 0x00040001
-#define GLFW_DISCONNECTED 0x00040002
-
-#define GLFW_DONT_CARE -1
-
-
-/*************************************************************************
- * GLFW API types
- *************************************************************************/
-
-/*! @brief Client API function pointer type.
- *
- * Generic function pointer used for returning client API function pointers
- * without forcing a cast from a regular pointer.
- *
- * @sa @ref context_glext
- * @sa glfwGetProcAddress
- *
- * @since Added in version 3.0.
-
- * @ingroup context
- */
-typedef void (*GLFWglproc)(void);
-
-/*! @brief Vulkan API function pointer type.
- *
- * Generic function pointer used for returning Vulkan API function pointers
- * without forcing a cast from a regular pointer.
- *
- * @sa @ref vulkan_proc
- * @sa glfwGetInstanceProcAddress
- *
- * @since Added in version 3.2.
- *
- * @ingroup vulkan
- */
-typedef void (*GLFWvkproc)(void);
-
-/*! @brief Opaque monitor object.
- *
- * Opaque monitor object.
- *
- * @see @ref monitor_object
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-typedef struct GLFWmonitor GLFWmonitor;
-
-/*! @brief Opaque window object.
- *
- * Opaque window object.
- *
- * @see @ref window_object
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-typedef struct GLFWwindow GLFWwindow;
-
-/*! @brief Opaque cursor object.
- *
- * Opaque cursor object.
- *
- * @see @ref cursor_object
- *
- * @since Added in version 3.1.
- *
- * @ingroup cursor
- */
-typedef struct GLFWcursor GLFWcursor;
-
-/*! @brief The function signature for error callbacks.
- *
- * This is the function signature for error callback functions.
- *
- * @param[in] error An [error code](@ref errors).
- * @param[in] description A UTF-8 encoded string describing the error.
- *
- * @sa @ref error_handling
- * @sa glfwSetErrorCallback
- *
- * @since Added in version 3.0.
- *
- * @ingroup init
- */
-typedef void (* GLFWerrorfun)(int,const char*);
-
-/*! @brief The function signature for window position callbacks.
- *
- * This is the function signature for window position callback functions.
- *
- * @param[in] window The window that was moved.
- * @param[in] xpos The new x-coordinate, in screen coordinates, of the
- * upper-left corner of the client area of the window.
- * @param[in] ypos The new y-coordinate, in screen coordinates, of the
- * upper-left corner of the client area of the window.
- *
- * @sa @ref window_pos
- * @sa glfwSetWindowPosCallback
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-typedef void (* GLFWwindowposfun)(GLFWwindow*,int,int);
-
-/*! @brief The function signature for window resize callbacks.
- *
- * This is the function signature for window size callback functions.
- *
- * @param[in] window The window that was resized.
- * @param[in] width The new width, in screen coordinates, of the window.
- * @param[in] height The new height, in screen coordinates, of the window.
- *
- * @sa @ref window_size
- * @sa glfwSetWindowSizeCallback
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup window
- */
-typedef void (* GLFWwindowsizefun)(GLFWwindow*,int,int);
-
-/*! @brief The function signature for window close callbacks.
- *
- * This is the function signature for window close callback functions.
- *
- * @param[in] window The window that the user attempted to close.
- *
- * @sa @ref window_close
- * @sa glfwSetWindowCloseCallback
- *
- * @since Added in version 2.5.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup window
- */
-typedef void (* GLFWwindowclosefun)(GLFWwindow*);
-
-/*! @brief The function signature for window content refresh callbacks.
- *
- * This is the function signature for window refresh callback functions.
- *
- * @param[in] window The window whose content needs to be refreshed.
- *
- * @sa @ref window_refresh
- * @sa glfwSetWindowRefreshCallback
- *
- * @since Added in version 2.5.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup window
- */
-typedef void (* GLFWwindowrefreshfun)(GLFWwindow*);
-
-/*! @brief The function signature for window focus/defocus callbacks.
- *
- * This is the function signature for window focus callback functions.
- *
- * @param[in] window The window that gained or lost input focus.
- * @param[in] focused `GLFW_TRUE` if the window was given input focus, or
- * `GLFW_FALSE` if it lost it.
- *
- * @sa @ref window_focus
- * @sa glfwSetWindowFocusCallback
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-typedef void (* GLFWwindowfocusfun)(GLFWwindow*,int);
-
-/*! @brief The function signature for window iconify/restore callbacks.
- *
- * This is the function signature for window iconify/restore callback
- * functions.
- *
- * @param[in] window The window that was iconified or restored.
- * @param[in] iconified `GLFW_TRUE` if the window was iconified, or
- * `GLFW_FALSE` if it was restored.
- *
- * @sa @ref window_iconify
- * @sa glfwSetWindowIconifyCallback
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-typedef void (* GLFWwindowiconifyfun)(GLFWwindow*,int);
-
-/*! @brief The function signature for framebuffer resize callbacks.
- *
- * This is the function signature for framebuffer resize callback
- * functions.
- *
- * @param[in] window The window whose framebuffer was resized.
- * @param[in] width The new width, in pixels, of the framebuffer.
- * @param[in] height The new height, in pixels, of the framebuffer.
- *
- * @sa @ref window_fbsize
- * @sa glfwSetFramebufferSizeCallback
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-typedef void (* GLFWframebuffersizefun)(GLFWwindow*,int,int);
-
-/*! @brief The function signature for mouse button callbacks.
- *
- * This is the function signature for mouse button callback functions.
- *
- * @param[in] window The window that received the event.
- * @param[in] button The [mouse button](@ref buttons) that was pressed or
- * released.
- * @param[in] action One of `GLFW_PRESS` or `GLFW_RELEASE`.
- * @param[in] mods Bit field describing which [modifier keys](@ref mods) were
- * held down.
- *
- * @sa @ref input_mouse_button
- * @sa glfwSetMouseButtonCallback
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle and modifier mask parameters.
- *
- * @ingroup input
- */
-typedef void (* GLFWmousebuttonfun)(GLFWwindow*,int,int,int);
-
-/*! @brief The function signature for cursor position callbacks.
- *
- * This is the function signature for cursor position callback functions.
- *
- * @param[in] window The window that received the event.
- * @param[in] xpos The new cursor x-coordinate, relative to the left edge of
- * the client area.
- * @param[in] ypos The new cursor y-coordinate, relative to the top edge of the
- * client area.
- *
- * @sa @ref cursor_pos
- * @sa glfwSetCursorPosCallback
- *
- * @since Added in version 3.0. Replaces `GLFWmouseposfun`.
- *
- * @ingroup input
- */
-typedef void (* GLFWcursorposfun)(GLFWwindow*,double,double);
-
-/*! @brief The function signature for cursor enter/leave callbacks.
- *
- * This is the function signature for cursor enter/leave callback functions.
- *
- * @param[in] window The window that received the event.
- * @param[in] entered `GLFW_TRUE` if the cursor entered the window's client
- * area, or `GLFW_FALSE` if it left it.
- *
- * @sa @ref cursor_enter
- * @sa glfwSetCursorEnterCallback
- *
- * @since Added in version 3.0.
- *
- * @ingroup input
- */
-typedef void (* GLFWcursorenterfun)(GLFWwindow*,int);
-
-/*! @brief The function signature for scroll callbacks.
- *
- * This is the function signature for scroll callback functions.
- *
- * @param[in] window The window that received the event.
- * @param[in] xoffset The scroll offset along the x-axis.
- * @param[in] yoffset The scroll offset along the y-axis.
- *
- * @sa @ref scrolling
- * @sa glfwSetScrollCallback
- *
- * @since Added in version 3.0. Replaces `GLFWmousewheelfun`.
- *
- * @ingroup input
- */
-typedef void (* GLFWscrollfun)(GLFWwindow*,double,double);
-
-/*! @brief The function signature for keyboard key callbacks.
- *
- * This is the function signature for keyboard key callback functions.
- *
- * @param[in] window The window that received the event.
- * @param[in] key The [keyboard key](@ref keys) that was pressed or released.
- * @param[in] scancode The system-specific scancode of the key.
- * @param[in] action `GLFW_PRESS`, `GLFW_RELEASE` or `GLFW_REPEAT`.
- * @param[in] mods Bit field describing which [modifier keys](@ref mods) were
- * held down.
- *
- * @sa @ref input_key
- * @sa glfwSetKeyCallback
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle, scancode and modifier mask parameters.
- *
- * @ingroup input
- */
-typedef void (* GLFWkeyfun)(GLFWwindow*,int,int,int,int);
-
-/*! @brief The function signature for Unicode character callbacks.
- *
- * This is the function signature for Unicode character callback functions.
- *
- * @param[in] window The window that received the event.
- * @param[in] codepoint The Unicode code point of the character.
- *
- * @sa @ref input_char
- * @sa glfwSetCharCallback
- *
- * @since Added in version 2.4.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup input
- */
-typedef void (* GLFWcharfun)(GLFWwindow*,unsigned int);
-
-/*! @brief The function signature for Unicode character with modifiers
- * callbacks.
- *
- * This is the function signature for Unicode character with modifiers callback
- * functions. It is called for each input character, regardless of what
- * modifier keys are held down.
- *
- * @param[in] window The window that received the event.
- * @param[in] codepoint The Unicode code point of the character.
- * @param[in] mods Bit field describing which [modifier keys](@ref mods) were
- * held down.
- *
- * @sa @ref input_char
- * @sa glfwSetCharModsCallback
- *
- * @since Added in version 3.1.
- *
- * @ingroup input
- */
-typedef void (* GLFWcharmodsfun)(GLFWwindow*,unsigned int,int);
-
-/*! @brief The function signature for file drop callbacks.
- *
- * This is the function signature for file drop callbacks.
- *
- * @param[in] window The window that received the event.
- * @param[in] count The number of dropped files.
- * @param[in] paths The UTF-8 encoded file and/or directory path names.
- *
- * @sa @ref path_drop
- * @sa glfwSetDropCallback
- *
- * @since Added in version 3.1.
- *
- * @ingroup input
- */
-typedef void (* GLFWdropfun)(GLFWwindow*,int,const char**);
-
-/*! @brief The function signature for monitor configuration callbacks.
- *
- * This is the function signature for monitor configuration callback functions.
- *
- * @param[in] monitor The monitor that was connected or disconnected.
- * @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`.
- *
- * @sa @ref monitor_event
- * @sa glfwSetMonitorCallback
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-typedef void (* GLFWmonitorfun)(GLFWmonitor*,int);
-
-/*! @brief The function signature for joystick configuration callbacks.
- *
- * This is the function signature for joystick configuration callback
- * functions.
- *
- * @param[in] joy The joystick that was connected or disconnected.
- * @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`.
- *
- * @sa @ref joystick_event
- * @sa glfwSetJoystickCallback
- *
- * @since Added in version 3.2.
- *
- * @ingroup input
- */
-typedef void (* GLFWjoystickfun)(int,int);
-
-/*! @brief Video mode type.
- *
- * This describes a single video mode.
- *
- * @sa @ref monitor_modes
- * @sa glfwGetVideoMode glfwGetVideoModes
- *
- * @since Added in version 1.0.
- * @glfw3 Added refresh rate member.
- *
- * @ingroup monitor
- */
-typedef struct GLFWvidmode
-{
- /*! The width, in screen coordinates, of the video mode.
- */
- int width;
- /*! The height, in screen coordinates, of the video mode.
- */
- int height;
- /*! The bit depth of the red channel of the video mode.
- */
- int redBits;
- /*! The bit depth of the green channel of the video mode.
- */
- int greenBits;
- /*! The bit depth of the blue channel of the video mode.
- */
- int blueBits;
- /*! The refresh rate, in Hz, of the video mode.
- */
- int refreshRate;
-} GLFWvidmode;
-
-/*! @brief Gamma ramp.
- *
- * This describes the gamma ramp for a monitor.
- *
- * @sa @ref monitor_gamma
- * @sa glfwGetGammaRamp glfwSetGammaRamp
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-typedef struct GLFWgammaramp
-{
- /*! An array of value describing the response of the red channel.
- */
- unsigned short* red;
- /*! An array of value describing the response of the green channel.
- */
- unsigned short* green;
- /*! An array of value describing the response of the blue channel.
- */
- unsigned short* blue;
- /*! The number of elements in each array.
- */
- unsigned int size;
-} GLFWgammaramp;
-
-/*! @brief Image data.
- *
- * @sa @ref cursor_custom
- *
- * @since Added in version 2.1.
- * @glfw3 Removed format and bytes-per-pixel members.
- */
-typedef struct GLFWimage
-{
- /*! The width, in pixels, of this image.
- */
- int width;
- /*! The height, in pixels, of this image.
- */
- int height;
- /*! The pixel data of this image, arranged left-to-right, top-to-bottom.
- */
- unsigned char* pixels;
-} GLFWimage;
-
-
-/*************************************************************************
- * GLFW API functions
- *************************************************************************/
-
-/*! @brief Initializes the GLFW library.
- *
- * This function initializes the GLFW library. Before most GLFW functions can
- * be used, GLFW must be initialized, and before an application terminates GLFW
- * should be terminated in order to free any resources allocated during or
- * after initialization.
- *
- * If this function fails, it calls @ref glfwTerminate before returning. If it
- * succeeds, you should call @ref glfwTerminate before the application exits.
- *
- * Additional calls to this function after successful initialization but before
- * termination will return `GLFW_TRUE` immediately.
- *
- * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_PLATFORM_ERROR.
- *
- * @remark @osx This function will change the current directory of the
- * application to the `Contents/Resources` subdirectory of the application's
- * bundle, if present. This can be disabled with a
- * [compile-time option](@ref compile_options_osx).
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref intro_init
- * @sa glfwTerminate
- *
- * @since Added in version 1.0.
- *
- * @ingroup init
- */
-GLFWAPI int glfwInit(void);
-
-/*! @brief Terminates the GLFW library.
- *
- * This function destroys all remaining windows and cursors, restores any
- * modified gamma ramps and frees any other allocated resources. Once this
- * function is called, you must again call @ref glfwInit successfully before
- * you will be able to use most GLFW functions.
- *
- * If GLFW has been successfully initialized, this function should be called
- * before the application exits. If initialization fails, there is no need to
- * call this function, as it is called by @ref glfwInit before it returns
- * failure.
- *
- * @errors Possible errors include @ref GLFW_PLATFORM_ERROR.
- *
- * @remark This function may be called before @ref glfwInit.
- *
- * @warning The contexts of any remaining windows must not be current on any
- * other thread when this function is called.
- *
- * @reentrancy This function must not be called from a callback.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref intro_init
- * @sa glfwInit
- *
- * @since Added in version 1.0.
- *
- * @ingroup init
- */
-GLFWAPI void glfwTerminate(void);
-
-/*! @brief Retrieves the version of the GLFW library.
- *
- * This function retrieves the major, minor and revision numbers of the GLFW
- * library. It is intended for when you are using GLFW as a shared library and
- * want to ensure that you are using the minimum required version.
- *
- * Any or all of the version arguments may be `NULL`.
- *
- * @param[out] major Where to store the major version number, or `NULL`.
- * @param[out] minor Where to store the minor version number, or `NULL`.
- * @param[out] rev Where to store the revision number, or `NULL`.
- *
- * @errors None.
- *
- * @remark This function may be called before @ref glfwInit.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref intro_version
- * @sa glfwGetVersionString
- *
- * @since Added in version 1.0.
- *
- * @ingroup init
- */
-GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev);
-
-/*! @brief Returns a string describing the compile-time configuration.
- *
- * This function returns the compile-time generated
- * [version string](@ref intro_version_string) of the GLFW library binary. It
- * describes the version, platform, compiler and any platform-specific
- * compile-time options. It should not be confused with the OpenGL or OpenGL
- * ES version string, queried with `glGetString`.
- *
- * __Do not use the version string__ to parse the GLFW library version. The
- * @ref glfwGetVersion function provides the version of the running library
- * binary in numerical format.
- *
- * @return The ASCII encoded GLFW version string.
- *
- * @errors None.
- *
- * @remark This function may be called before @ref glfwInit.
- *
- * @pointer_lifetime The returned string is static and compile-time generated.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref intro_version
- * @sa glfwGetVersion
- *
- * @since Added in version 3.0.
- *
- * @ingroup init
- */
-GLFWAPI const char* glfwGetVersionString(void);
-
-/*! @brief Sets the error callback.
- *
- * This function sets the error callback, which is called with an error code
- * and a human-readable description each time a GLFW error occurs.
- *
- * The error callback is called on the thread where the error occurred. If you
- * are using GLFW from multiple threads, your error callback needs to be
- * written accordingly.
- *
- * Because the description string may have been generated specifically for that
- * error, it is not guaranteed to be valid after the callback has returned. If
- * you wish to use it after the callback returns, you need to make a copy.
- *
- * Once set, the error callback remains set even after the library has been
- * terminated.
- *
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set.
- *
- * @errors None.
- *
- * @remark This function may be called before @ref glfwInit.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref error_handling
- *
- * @since Added in version 3.0.
- *
- * @ingroup init
- */
-GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun);
-
-/*! @brief Returns the currently connected monitors.
- *
- * This function returns an array of handles for all currently connected
- * monitors. The primary monitor is always first in the returned array. If no
- * monitors were found, this function returns `NULL`.
- *
- * @param[out] count Where to store the number of monitors in the returned
- * array. This is set to zero if an error occurred.
- * @return An array of monitor handles, or `NULL` if no monitors were found or
- * if an [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @pointer_lifetime The returned array is allocated and freed by GLFW. You
- * should not free it yourself. It is guaranteed to be valid only until the
- * monitor configuration changes or the library is terminated.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref monitor_monitors
- * @sa @ref monitor_event
- * @sa glfwGetPrimaryMonitor
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-GLFWAPI GLFWmonitor** glfwGetMonitors(int* count);
-
-/*! @brief Returns the primary monitor.
- *
- * This function returns the primary monitor. This is usually the monitor
- * where elements like the task bar or global menu bar are located.
- *
- * @return The primary monitor, or `NULL` if no monitors were found or if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @remark The primary monitor is always first in the array returned by @ref
- * glfwGetMonitors.
- *
- * @sa @ref monitor_monitors
- * @sa glfwGetMonitors
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void);
-
-/*! @brief Returns the position of the monitor's viewport on the virtual screen.
- *
- * This function returns the position, in screen coordinates, of the upper-left
- * corner of the specified monitor.
- *
- * Any or all of the position arguments may be `NULL`. If an error occurs, all
- * non-`NULL` position arguments will be set to zero.
- *
- * @param[in] monitor The monitor to query.
- * @param[out] xpos Where to store the monitor x-coordinate, or `NULL`.
- * @param[out] ypos Where to store the monitor y-coordinate, or `NULL`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref monitor_properties
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-GLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos);
-
-/*! @brief Returns the physical size of the monitor.
- *
- * This function returns the size, in millimetres, of the display area of the
- * specified monitor.
- *
- * Some systems do not provide accurate monitor size information, either
- * because the monitor
- * [EDID](https://en.wikipedia.org/wiki/Extended_display_identification_data)
- * data is incorrect or because the driver does not report it accurately.
- *
- * Any or all of the size arguments may be `NULL`. If an error occurs, all
- * non-`NULL` size arguments will be set to zero.
- *
- * @param[in] monitor The monitor to query.
- * @param[out] widthMM Where to store the width, in millimetres, of the
- * monitor's display area, or `NULL`.
- * @param[out] heightMM Where to store the height, in millimetres, of the
- * monitor's display area, or `NULL`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @remark @win32 calculates the returned physical size from the
- * current resolution and system DPI instead of querying the monitor EDID data.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref monitor_properties
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* monitor, int* widthMM, int* heightMM);
-
-/*! @brief Returns the name of the specified monitor.
- *
- * This function returns a human-readable name, encoded as UTF-8, of the
- * specified monitor. The name typically reflects the make and model of the
- * monitor and is not guaranteed to be unique among the connected monitors.
- *
- * @param[in] monitor The monitor to query.
- * @return The UTF-8 encoded name of the monitor, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @pointer_lifetime The returned string is allocated and freed by GLFW. You
- * should not free it yourself. It is valid until the specified monitor is
- * disconnected or the library is terminated.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref monitor_properties
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* monitor);
-
-/*! @brief Sets the monitor configuration callback.
- *
- * This function sets the monitor configuration callback, or removes the
- * currently set callback. This is called when a monitor is connected to or
- * disconnected from the system.
- *
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref monitor_event
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun);
-
-/*! @brief Returns the available video modes for the specified monitor.
- *
- * This function returns an array of all video modes supported by the specified
- * monitor. The returned array is sorted in ascending order, first by color
- * bit depth (the sum of all channel depths) and then by resolution area (the
- * product of width and height).
- *
- * @param[in] monitor The monitor to query.
- * @param[out] count Where to store the number of video modes in the returned
- * array. This is set to zero if an error occurred.
- * @return An array of video modes, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @pointer_lifetime The returned array is allocated and freed by GLFW. You
- * should not free it yourself. It is valid until the specified monitor is
- * disconnected, this function is called again for that monitor or the library
- * is terminated.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref monitor_modes
- * @sa glfwGetVideoMode
- *
- * @since Added in version 1.0.
- * @glfw3 Changed to return an array of modes for a specific monitor.
- *
- * @ingroup monitor
- */
-GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* monitor, int* count);
-
-/*! @brief Returns the current mode of the specified monitor.
- *
- * This function returns the current video mode of the specified monitor. If
- * you have created a full screen window for that monitor, the return value
- * will depend on whether that window is iconified.
- *
- * @param[in] monitor The monitor to query.
- * @return The current mode of the monitor, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @pointer_lifetime The returned array is allocated and freed by GLFW. You
- * should not free it yourself. It is valid until the specified monitor is
- * disconnected or the library is terminated.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref monitor_modes
- * @sa glfwGetVideoModes
- *
- * @since Added in version 3.0. Replaces `glfwGetDesktopMode`.
- *
- * @ingroup monitor
- */
-GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor);
-
-/*! @brief Generates a gamma ramp and sets it for the specified monitor.
- *
- * This function generates a 256-element gamma ramp from the specified exponent
- * and then calls @ref glfwSetGammaRamp with it. The value must be a finite
- * number greater than zero.
- *
- * @param[in] monitor The monitor whose gamma ramp to set.
- * @param[in] gamma The desired exponent.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref monitor_gamma
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma);
-
-/*! @brief Returns the current gamma ramp for the specified monitor.
- *
- * This function returns the current gamma ramp of the specified monitor.
- *
- * @param[in] monitor The monitor to query.
- * @return The current gamma ramp, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @pointer_lifetime The returned structure and its arrays are allocated and
- * freed by GLFW. You should not free them yourself. They are valid until the
- * specified monitor is disconnected, this function is called again for that
- * monitor or the library is terminated.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref monitor_gamma
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor);
-
-/*! @brief Sets the current gamma ramp for the specified monitor.
- *
- * This function sets the current gamma ramp for the specified monitor. The
- * original gamma ramp for that monitor is saved by GLFW the first time this
- * function is called and is restored by @ref glfwTerminate.
- *
- * @param[in] monitor The monitor whose gamma ramp to set.
- * @param[in] ramp The gamma ramp to use.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @remark Gamma ramp sizes other than 256 are not supported by all platforms
- * or graphics hardware.
- *
- * @remark @win32 The gamma ramp size must be 256.
- *
- * @pointer_lifetime The specified gamma ramp is copied before this function
- * returns.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref monitor_gamma
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-GLFWAPI void glfwSetGammaRamp(GLFWmonitor* monitor, const GLFWgammaramp* ramp);
-
-/*! @brief Resets all window hints to their default values.
- *
- * This function resets all window hints to their
- * [default values](@ref window_hints_values).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_hints
- * @sa glfwWindowHint
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI void glfwDefaultWindowHints(void);
-
-/*! @brief Sets the specified window hint to the desired value.
- *
- * This function sets hints for the next call to @ref glfwCreateWindow. The
- * hints, once set, retain their values until changed by a call to @ref
- * glfwWindowHint or @ref glfwDefaultWindowHints, or until the library is
- * terminated.
- *
- * This function does not check whether the specified hint values are valid.
- * If you set hints to invalid values this will instead be reported by the next
- * call to @ref glfwCreateWindow.
- *
- * @param[in] hint The [window hint](@ref window_hints) to set.
- * @param[in] value The new value of the window hint.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_INVALID_ENUM.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_hints
- * @sa glfwDefaultWindowHints
- *
- * @since Added in version 3.0. Replaces `glfwOpenWindowHint`.
- *
- * @ingroup window
- */
-GLFWAPI void glfwWindowHint(int hint, int value);
-
-/*! @brief Creates a window and its associated context.
- *
- * This function creates a window and its associated OpenGL or OpenGL ES
- * context. Most of the options controlling how the window and its context
- * should be created are specified with [window hints](@ref window_hints).
- *
- * Successful creation does not change which context is current. Before you
- * can use the newly created context, you need to
- * [make it current](@ref context_current). For information about the `share`
- * parameter, see @ref context_sharing.
- *
- * The created window, framebuffer and context may differ from what you
- * requested, as not all parameters and hints are
- * [hard constraints](@ref window_hints_hard). This includes the size of the
- * window, especially for full screen windows. To query the actual attributes
- * of the created window, framebuffer and context, see @ref
- * glfwGetWindowAttrib, @ref glfwGetWindowSize and @ref glfwGetFramebufferSize.
- *
- * To create a full screen window, you need to specify the monitor the window
- * will cover. If no monitor is specified, the window will be windowed mode.
- * Unless you have a way for the user to choose a specific monitor, it is
- * recommended that you pick the primary monitor. For more information on how
- * to query connected monitors, see @ref monitor_monitors.
- *
- * For full screen windows, the specified size becomes the resolution of the
- * window's _desired video mode_. As long as a full screen window is not
- * iconified, the supported video mode most closely matching the desired video
- * mode is set for the specified monitor. For more information about full
- * screen windows, including the creation of so called _windowed full screen_
- * or _borderless full screen_ windows, see @ref window_windowed_full_screen.
- *
- * By default, newly created windows use the placement recommended by the
- * window system. To create the window at a specific position, make it
- * initially invisible using the [GLFW_VISIBLE](@ref window_hints_wnd) window
- * hint, set its [position](@ref window_pos) and then [show](@ref window_hide)
- * it.
- *
- * As long as at least one full screen window is not iconified, the screensaver
- * is prohibited from starting.
- *
- * Window systems put limits on window sizes. Very large or very small window
- * dimensions may be overridden by the window system on creation. Check the
- * actual [size](@ref window_size) after creation.
- *
- * The [swap interval](@ref buffer_swap) is not set during window creation and
- * the initial value may vary depending on driver settings and defaults.
- *
- * @param[in] width The desired width, in screen coordinates, of the window.
- * This must be greater than zero.
- * @param[in] height The desired height, in screen coordinates, of the window.
- * This must be greater than zero.
- * @param[in] title The initial, UTF-8 encoded window title.
- * @param[in] monitor The monitor to use for full screen mode, or `NULL` for
- * windowed mode.
- * @param[in] share The window whose context to share resources with, or `NULL`
- * to not share resources.
- * @return The handle of the created window, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE, @ref GLFW_API_UNAVAILABLE, @ref
- * GLFW_VERSION_UNAVAILABLE, @ref GLFW_FORMAT_UNAVAILABLE and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @remark @win32 Window creation will fail if the Microsoft GDI software
- * OpenGL implementation is the only one available.
- *
- * @remark @win32 If the executable has an icon resource named `GLFW_ICON,` it
- * will be set as the initial icon for the window. If no such icon is present,
- * the `IDI_WINLOGO` icon will be used instead. To set a different icon, see
- * @ref glfwSetWindowIcon.
- *
- * @remark @win32 The context to share resources with must not be current on
- * any other thread.
- *
- * @remark @osx The GLFW window has no icon, as it is not a document
- * window, but the dock icon will be the same as the application bundle's icon.
- * For more information on bundles, see the
- * [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/)
- * in the Mac Developer Library.
- *
- * @remark @osx The first time a window is created the menu bar is populated
- * with common commands like Hide, Quit and About. The About entry opens
- * a minimal about dialog with information from the application's bundle. The
- * menu bar can be disabled with a
- * [compile-time option](@ref compile_options_osx).
- *
- * @remark @osx On OS X 10.10 and later the window frame will not be rendered
- * at full resolution on Retina displays unless the `NSHighResolutionCapable`
- * key is enabled in the application bundle's `Info.plist`. For more
- * information, see
- * [High Resolution Guidelines for OS X](https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html)
- * in the Mac Developer Library. The GLFW test and example programs use
- * a custom `Info.plist` template for this, which can be found as
- * `CMake/MacOSXBundleInfo.plist.in` in the source tree.
- *
- * @remark @x11 Some window managers will not respect the placement of
- * initially hidden windows.
- *
- * @remark @x11 Due to the asynchronous nature of X11, it may take a moment for
- * a window to reach its requested state. This means you may not be able to
- * query the final size, position or other attributes directly after window
- * creation.
- *
- * @reentrancy This function must not be called from a callback.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_creation
- * @sa glfwDestroyWindow
- *
- * @since Added in version 3.0. Replaces `glfwOpenWindow`.
- *
- * @ingroup window
- */
-GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, GLFWmonitor* monitor, GLFWwindow* share);
-
-/*! @brief Destroys the specified window and its context.
- *
- * This function destroys the specified window and its context. On calling
- * this function, no further callbacks will be called for that window.
- *
- * If the context of the specified window is current on the main thread, it is
- * detached before being destroyed.
- *
- * @param[in] window The window to destroy.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @note The context of the specified window must not be current on any other
- * thread when this function is called.
- *
- * @reentrancy This function must not be called from a callback.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_creation
- * @sa glfwCreateWindow
- *
- * @since Added in version 3.0. Replaces `glfwCloseWindow`.
- *
- * @ingroup window
- */
-GLFWAPI void glfwDestroyWindow(GLFWwindow* window);
-
-/*! @brief Checks the close flag of the specified window.
- *
- * This function returns the value of the close flag of the specified window.
- *
- * @param[in] window The window to query.
- * @return The value of the close flag.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @sa @ref window_close
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI int glfwWindowShouldClose(GLFWwindow* window);
-
-/*! @brief Sets the close flag of the specified window.
- *
- * This function sets the value of the close flag of the specified window.
- * This can be used to override the user's attempt to close the window, or
- * to signal that it should be closed.
- *
- * @param[in] window The window whose flag to change.
- * @param[in] value The new value.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @sa @ref window_close
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* window, int value);
-
-/*! @brief Sets the title of the specified window.
- *
- * This function sets the window title, encoded as UTF-8, of the specified
- * window.
- *
- * @param[in] window The window whose title to change.
- * @param[in] title The UTF-8 encoded window title.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @remark @osx The window title will not be updated until the next time you
- * process events.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_title
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup window
- */
-GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title);
-
-/*! @brief Sets the icon for the specified window.
- *
- * This function sets the icon of the specified window. If passed an array of
- * candidate images, those of or closest to the sizes desired by the system are
- * selected. If no images are specified, the window reverts to its default
- * icon.
- *
- * The desired image sizes varies depending on platform and system settings.
- * The selected images will be rescaled as needed. Good sizes include 16x16,
- * 32x32 and 48x48.
- *
- * @param[in] window The window whose icon to set.
- * @param[in] count The number of images in the specified array, or zero to
- * revert to the default window icon.
- * @param[in] images The images to create the icon from. This is ignored if
- * count is zero.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @pointer_lifetime The specified image data is copied before this function
- * returns.
- *
- * @remark @osx The GLFW window has no icon, as it is not a document
- * window, so this function does nothing. The dock icon will be the same as
- * the application bundle's icon. For more information on bundles, see the
- * [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/)
- * in the Mac Developer Library.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_icon
- *
- * @since Added in version 3.2.
- *
- * @ingroup window
- */
-GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* images);
-
-/*! @brief Retrieves the position of the client area of the specified window.
- *
- * This function retrieves the position, in screen coordinates, of the
- * upper-left corner of the client area of the specified window.
- *
- * Any or all of the position arguments may be `NULL`. If an error occurs, all
- * non-`NULL` position arguments will be set to zero.
- *
- * @param[in] window The window to query.
- * @param[out] xpos Where to store the x-coordinate of the upper-left corner of
- * the client area, or `NULL`.
- * @param[out] ypos Where to store the y-coordinate of the upper-left corner of
- * the client area, or `NULL`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_pos
- * @sa glfwSetWindowPos
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos);
-
-/*! @brief Sets the position of the client area of the specified window.
- *
- * This function sets the position, in screen coordinates, of the upper-left
- * corner of the client area of the specified windowed mode window. If the
- * window is a full screen window, this function does nothing.
- *
- * __Do not use this function__ to move an already visible window unless you
- * have very good reasons for doing so, as it will confuse and annoy the user.
- *
- * The window manager may put limits on what positions are allowed. GLFW
- * cannot and should not override these limits.
- *
- * @param[in] window The window to query.
- * @param[in] xpos The x-coordinate of the upper-left corner of the client area.
- * @param[in] ypos The y-coordinate of the upper-left corner of the client area.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_pos
- * @sa glfwGetWindowPos
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup window
- */
-GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos);
-
-/*! @brief Retrieves the size of the client area of the specified window.
- *
- * This function retrieves the size, in screen coordinates, of the client area
- * of the specified window. If you wish to retrieve the size of the
- * framebuffer of the window in pixels, see @ref glfwGetFramebufferSize.
- *
- * Any or all of the size arguments may be `NULL`. If an error occurs, all
- * non-`NULL` size arguments will be set to zero.
- *
- * @param[in] window The window whose size to retrieve.
- * @param[out] width Where to store the width, in screen coordinates, of the
- * client area, or `NULL`.
- * @param[out] height Where to store the height, in screen coordinates, of the
- * client area, or `NULL`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_size
- * @sa glfwSetWindowSize
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup window
- */
-GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height);
-
-/*! @brief Sets the size limits of the specified window.
- *
- * This function sets the size limits of the client area of the specified
- * window. If the window is full screen, the size limits only take effect
- * once it is made windowed. If the window is not resizable, this function
- * does nothing.
- *
- * The size limits are applied immediately to a windowed mode window and may
- * cause it to be resized.
- *
- * The maximum dimensions must be greater than or equal to the minimum
- * dimensions and all must be greater than or equal to zero.
- *
- * @param[in] window The window to set limits for.
- * @param[in] minwidth The minimum width, in screen coordinates, of the client
- * area, or `GLFW_DONT_CARE`.
- * @param[in] minheight The minimum height, in screen coordinates, of the
- * client area, or `GLFW_DONT_CARE`.
- * @param[in] maxwidth The maximum width, in screen coordinates, of the client
- * area, or `GLFW_DONT_CARE`.
- * @param[in] maxheight The maximum height, in screen coordinates, of the
- * client area, or `GLFW_DONT_CARE`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.
- *
- * @remark If you set size limits and an aspect ratio that conflict, the
- * results are undefined.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_sizelimits
- * @sa glfwSetWindowAspectRatio
- *
- * @since Added in version 3.2.
- *
- * @ingroup window
- */
-GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight);
-
-/*! @brief Sets the aspect ratio of the specified window.
- *
- * This function sets the required aspect ratio of the client area of the
- * specified window. If the window is full screen, the aspect ratio only takes
- * effect once it is made windowed. If the window is not resizable, this
- * function does nothing.
- *
- * The aspect ratio is specified as a numerator and a denominator and both
- * values must be greater than zero. For example, the common 16:9 aspect ratio
- * is specified as 16 and 9, respectively.
- *
- * If the numerator and denominator is set to `GLFW_DONT_CARE` then the aspect
- * ratio limit is disabled.
- *
- * The aspect ratio is applied immediately to a windowed mode window and may
- * cause it to be resized.
- *
- * @param[in] window The window to set limits for.
- * @param[in] numer The numerator of the desired aspect ratio, or
- * `GLFW_DONT_CARE`.
- * @param[in] denom The denominator of the desired aspect ratio, or
- * `GLFW_DONT_CARE`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.
- *
- * @remark If you set size limits and an aspect ratio that conflict, the
- * results are undefined.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_sizelimits
- * @sa glfwSetWindowSizeLimits
- *
- * @since Added in version 3.2.
- *
- * @ingroup window
- */
-GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom);
-
-/*! @brief Sets the size of the client area of the specified window.
- *
- * This function sets the size, in screen coordinates, of the client area of
- * the specified window.
- *
- * For full screen windows, this function updates the resolution of its desired
- * video mode and switches to the video mode closest to it, without affecting
- * the window's context. As the context is unaffected, the bit depths of the
- * framebuffer remain unchanged.
- *
- * If you wish to update the refresh rate of the desired video mode in addition
- * to its resolution, see @ref glfwSetWindowMonitor.
- *
- * The window manager may put limits on what sizes are allowed. GLFW cannot
- * and should not override these limits.
- *
- * @param[in] window The window to resize.
- * @param[in] width The desired width, in screen coordinates, of the window
- * client area.
- * @param[in] height The desired height, in screen coordinates, of the window
- * client area.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_size
- * @sa glfwGetWindowSize
- * @sa glfwSetWindowMonitor
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup window
- */
-GLFWAPI void glfwSetWindowSize(GLFWwindow* window, int width, int height);
-
-/*! @brief Retrieves the size of the framebuffer of the specified window.
- *
- * This function retrieves the size, in pixels, of the framebuffer of the
- * specified window. If you wish to retrieve the size of the window in screen
- * coordinates, see @ref glfwGetWindowSize.
- *
- * Any or all of the size arguments may be `NULL`. If an error occurs, all
- * non-`NULL` size arguments will be set to zero.
- *
- * @param[in] window The window whose framebuffer to query.
- * @param[out] width Where to store the width, in pixels, of the framebuffer,
- * or `NULL`.
- * @param[out] height Where to store the height, in pixels, of the framebuffer,
- * or `NULL`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_fbsize
- * @sa glfwSetFramebufferSizeCallback
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI void glfwGetFramebufferSize(GLFWwindow* window, int* width, int* height);
-
-/*! @brief Retrieves the size of the frame of the window.
- *
- * This function retrieves the size, in screen coordinates, of each edge of the
- * frame of the specified window. This size includes the title bar, if the
- * window has one. The size of the frame may vary depending on the
- * [window-related hints](@ref window_hints_wnd) used to create it.
- *
- * Because this function retrieves the size of each window frame edge and not
- * the offset along a particular coordinate axis, the retrieved values will
- * always be zero or positive.
- *
- * Any or all of the size arguments may be `NULL`. If an error occurs, all
- * non-`NULL` size arguments will be set to zero.
- *
- * @param[in] window The window whose frame size to query.
- * @param[out] left Where to store the size, in screen coordinates, of the left
- * edge of the window frame, or `NULL`.
- * @param[out] top Where to store the size, in screen coordinates, of the top
- * edge of the window frame, or `NULL`.
- * @param[out] right Where to store the size, in screen coordinates, of the
- * right edge of the window frame, or `NULL`.
- * @param[out] bottom Where to store the size, in screen coordinates, of the
- * bottom edge of the window frame, or `NULL`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_size
- *
- * @since Added in version 3.1.
- *
- * @ingroup window
- */
-GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* window, int* left, int* top, int* right, int* bottom);
-
-/*! @brief Iconifies the specified window.
- *
- * This function iconifies (minimizes) the specified window if it was
- * previously restored. If the window is already iconified, this function does
- * nothing.
- *
- * If the specified window is a full screen window, the original monitor
- * resolution is restored until the window is restored.
- *
- * @param[in] window The window to iconify.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_iconify
- * @sa glfwRestoreWindow
- * @sa glfwMaximizeWindow
- *
- * @since Added in version 2.1.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup window
- */
-GLFWAPI void glfwIconifyWindow(GLFWwindow* window);
-
-/*! @brief Restores the specified window.
- *
- * This function restores the specified window if it was previously iconified
- * (minimized) or maximized. If the window is already restored, this function
- * does nothing.
- *
- * If the specified window is a full screen window, the resolution chosen for
- * the window is restored on the selected monitor.
- *
- * @param[in] window The window to restore.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_iconify
- * @sa glfwIconifyWindow
- * @sa glfwMaximizeWindow
- *
- * @since Added in version 2.1.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup window
- */
-GLFWAPI void glfwRestoreWindow(GLFWwindow* window);
-
-/*! @brief Maximizes the specified window.
- *
- * This function maximizes the specified window if it was previously not
- * maximized. If the window is already maximized, this function does nothing.
- *
- * If the specified window is a full screen window, this function does nothing.
- *
- * @param[in] window The window to maximize.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @par Thread Safety
- * This function may only be called from the main thread.
- *
- * @sa @ref window_iconify
- * @sa glfwIconifyWindow
- * @sa glfwRestoreWindow
- *
- * @since Added in GLFW 3.2.
- *
- * @ingroup window
- */
-GLFWAPI void glfwMaximizeWindow(GLFWwindow* window);
-
-/*! @brief Makes the specified window visible.
- *
- * This function makes the specified window visible if it was previously
- * hidden. If the window is already visible or is in full screen mode, this
- * function does nothing.
- *
- * @param[in] window The window to make visible.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_hide
- * @sa glfwHideWindow
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI void glfwShowWindow(GLFWwindow* window);
-
-/*! @brief Hides the specified window.
- *
- * This function hides the specified window if it was previously visible. If
- * the window is already hidden or is in full screen mode, this function does
- * nothing.
- *
- * @param[in] window The window to hide.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_hide
- * @sa glfwShowWindow
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI void glfwHideWindow(GLFWwindow* window);
-
-/*! @brief Brings the specified window to front and sets input focus.
- *
- * This function brings the specified window to front and sets input focus.
- * The window should already be visible and not iconified.
- *
- * By default, both windowed and full screen mode windows are focused when
- * initially created. Set the [GLFW_FOCUSED](@ref window_hints_wnd) to disable
- * this behavior.
- *
- * __Do not use this function__ to steal focus from other applications unless
- * you are certain that is what the user wants. Focus stealing can be
- * extremely disruptive.
- *
- * @param[in] window The window to give input focus.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_focus
- *
- * @since Added in version 3.2.
- *
- * @ingroup window
- */
-GLFWAPI void glfwFocusWindow(GLFWwindow* window);
-
-/*! @brief Returns the monitor that the window uses for full screen mode.
- *
- * This function returns the handle of the monitor that the specified window is
- * in full screen on.
- *
- * @param[in] window The window to query.
- * @return The monitor, or `NULL` if the window is in windowed mode or an error
- * occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_monitor
- * @sa glfwSetWindowMonitor
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window);
-
-/*! @brief Sets the mode, monitor, video mode and placement of a window.
- *
- * This function sets the monitor that the window uses for full screen mode or,
- * if the monitor is `NULL`, makes it windowed mode.
- *
- * When setting a monitor, this function updates the width, height and refresh
- * rate of the desired video mode and switches to the video mode closest to it.
- * The window position is ignored when setting a monitor.
- *
- * When the monitor is `NULL`, the position, width and height are used to
- * place the window client area. The refresh rate is ignored when no monitor
- * is specified.
- *
- * If you only wish to update the resolution of a full screen window or the
- * size of a windowed mode window, see @ref glfwSetWindowSize.
- *
- * When a window transitions from full screen to windowed mode, this function
- * restores any previous window settings such as whether it is decorated,
- * floating, resizable, has size or aspect ratio limits, etc..
- *
- * @param[in] window The window whose monitor, size or video mode to set.
- * @param[in] monitor The desired monitor, or `NULL` to set windowed mode.
- * @param[in] xpos The desired x-coordinate of the upper-left corner of the
- * client area.
- * @param[in] ypos The desired y-coordinate of the upper-left corner of the
- * client area.
- * @param[in] width The desired with, in screen coordinates, of the client area
- * or video mode.
- * @param[in] height The desired height, in screen coordinates, of the client
- * area or video mode.
- * @param[in] refreshRate The desired refresh rate, in Hz, of the video mode,
- * or `GLFW_DONT_CARE`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_monitor
- * @sa @ref window_full_screen
- * @sa glfwGetWindowMonitor
- * @sa glfwSetWindowSize
- *
- * @since Added in version 3.2.
- *
- * @ingroup window
- */
-GLFWAPI void glfwSetWindowMonitor(GLFWwindow* window, GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);
-
-/*! @brief Returns an attribute of the specified window.
- *
- * This function returns the value of an attribute of the specified window or
- * its OpenGL or OpenGL ES context.
- *
- * @param[in] window The window to query.
- * @param[in] attrib The [window attribute](@ref window_attribs) whose value to
- * return.
- * @return The value of the attribute, or zero if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
- *
- * @remark Framebuffer related hints are not window attributes. See @ref
- * window_attribs_fb for more information.
- *
- * @remark Zero is a valid value for many window and context related
- * attributes so you cannot use a return value of zero as an indication of
- * errors. However, this function should not fail as long as it is passed
- * valid arguments and the library has been [initialized](@ref intro_init).
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_attribs
- *
- * @since Added in version 3.0. Replaces `glfwGetWindowParam` and
- * `glfwGetGLVersion`.
- *
- * @ingroup window
- */
-GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib);
-
-/*! @brief Sets the user pointer of the specified window.
- *
- * This function sets the user-defined pointer of the specified window. The
- * current value is retained until the window is destroyed. The initial value
- * is `NULL`.
- *
- * @param[in] window The window whose pointer to set.
- * @param[in] pointer The new value.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @sa @ref window_userptr
- * @sa glfwGetWindowUserPointer
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* window, void* pointer);
-
-/*! @brief Returns the user pointer of the specified window.
- *
- * This function returns the current value of the user-defined pointer of the
- * specified window. The initial value is `NULL`.
- *
- * @param[in] window The window whose pointer to return.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @sa @ref window_userptr
- * @sa glfwSetWindowUserPointer
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window);
-
-/*! @brief Sets the position callback for the specified window.
- *
- * This function sets the position callback of the specified window, which is
- * called when the window is moved. The callback is provided with the screen
- * position of the upper-left corner of the client area of the window.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_pos
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* window, GLFWwindowposfun cbfun);
-
-/*! @brief Sets the size callback for the specified window.
- *
- * This function sets the size callback of the specified window, which is
- * called when the window is resized. The callback is provided with the size,
- * in screen coordinates, of the client area of the window.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_size
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle parameter and return value.
- *
- * @ingroup window
- */
-GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwindowsizefun cbfun);
-
-/*! @brief Sets the close callback for the specified window.
- *
- * This function sets the close callback of the specified window, which is
- * called when the user attempts to close the window, for example by clicking
- * the close widget in the title bar.
- *
- * The close flag is set before this callback is called, but you can modify it
- * at any time with @ref glfwSetWindowShouldClose.
- *
- * The close callback is not triggered by @ref glfwDestroyWindow.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @remark @osx Selecting Quit from the application menu will trigger the close
- * callback for all windows.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_close
- *
- * @since Added in version 2.5.
- * @glfw3 Added window handle parameter and return value.
- *
- * @ingroup window
- */
-GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwindowclosefun cbfun);
-
-/*! @brief Sets the refresh callback for the specified window.
- *
- * This function sets the refresh callback of the specified window, which is
- * called when the client area of the window needs to be redrawn, for example
- * if the window has been exposed after having been covered by another window.
- *
- * On compositing window systems such as Aero, Compiz or Aqua, where the window
- * contents are saved off-screen, this callback may be called only very
- * infrequently or never at all.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_refresh
- *
- * @since Added in version 2.5.
- * @glfw3 Added window handle parameter and return value.
- *
- * @ingroup window
- */
-GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* window, GLFWwindowrefreshfun cbfun);
-
-/*! @brief Sets the focus callback for the specified window.
- *
- * This function sets the focus callback of the specified window, which is
- * called when the window gains or loses input focus.
- *
- * After the focus callback is called for a window that lost input focus,
- * synthetic key and mouse button release events will be generated for all such
- * that had been pressed. For more information, see @ref glfwSetKeyCallback
- * and @ref glfwSetMouseButtonCallback.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_focus
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwindowfocusfun cbfun);
-
-/*! @brief Sets the iconify callback for the specified window.
- *
- * This function sets the iconification callback of the specified window, which
- * is called when the window is iconified or restored.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_iconify
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* window, GLFWwindowiconifyfun cbfun);
-
-/*! @brief Sets the framebuffer resize callback for the specified window.
- *
- * This function sets the framebuffer resize callback of the specified window,
- * which is called when the framebuffer of the specified window is resized.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_fbsize
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* window, GLFWframebuffersizefun cbfun);
-
-/*! @brief Processes all pending events.
- *
- * This function processes only those events that are already in the event
- * queue and then returns immediately. Processing events will cause the window
- * and input callbacks associated with those events to be called.
- *
- * On some platforms, a window move, resize or menu operation will cause event
- * processing to block. This is due to how event processing is designed on
- * those platforms. You can use the
- * [window refresh callback](@ref window_refresh) to redraw the contents of
- * your window when necessary during such operations.
- *
- * On some platforms, certain events are sent directly to the application
- * without going through the event queue, causing callbacks to be called
- * outside of a call to one of the event processing functions.
- *
- * Event processing is not required for joystick input to work.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @reentrancy This function must not be called from a callback.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref events
- * @sa glfwWaitEvents
- * @sa glfwWaitEventsTimeout
- *
- * @since Added in version 1.0.
- *
- * @ingroup window
- */
-GLFWAPI void glfwPollEvents(void);
-
-/*! @brief Waits until events are queued and processes them.
- *
- * This function puts the calling thread to sleep until at least one event is
- * available in the event queue. Once one or more events are available,
- * it behaves exactly like @ref glfwPollEvents, i.e. the events in the queue
- * are processed and the function then returns immediately. Processing events
- * will cause the window and input callbacks associated with those events to be
- * called.
- *
- * Since not all events are associated with callbacks, this function may return
- * without a callback having been called even if you are monitoring all
- * callbacks.
- *
- * On some platforms, a window move, resize or menu operation will cause event
- * processing to block. This is due to how event processing is designed on
- * those platforms. You can use the
- * [window refresh callback](@ref window_refresh) to redraw the contents of
- * your window when necessary during such operations.
- *
- * On some platforms, certain callbacks may be called outside of a call to one
- * of the event processing functions.
- *
- * If no windows exist, this function returns immediately. For synchronization
- * of threads in applications that do not create windows, use your threading
- * library of choice.
- *
- * Event processing is not required for joystick input to work.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @reentrancy This function must not be called from a callback.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref events
- * @sa glfwPollEvents
- * @sa glfwWaitEventsTimeout
- *
- * @since Added in version 2.5.
- *
- * @ingroup window
- */
-GLFWAPI void glfwWaitEvents(void);
-
-/*! @brief Waits with timeout until events are queued and processes them.
- *
- * This function puts the calling thread to sleep until at least one event is
- * available in the event queue, or until the specified timeout is reached. If
- * one or more events are available, it behaves exactly like @ref
- * glfwPollEvents, i.e. the events in the queue are processed and the function
- * then returns immediately. Processing events will cause the window and input
- * callbacks associated with those events to be called.
- *
- * The timeout value must be a positive finite number.
- *
- * Since not all events are associated with callbacks, this function may return
- * without a callback having been called even if you are monitoring all
- * callbacks.
- *
- * On some platforms, a window move, resize or menu operation will cause event
- * processing to block. This is due to how event processing is designed on
- * those platforms. You can use the
- * [window refresh callback](@ref window_refresh) to redraw the contents of
- * your window when necessary during such operations.
- *
- * On some platforms, certain callbacks may be called outside of a call to one
- * of the event processing functions.
- *
- * If no windows exist, this function returns immediately. For synchronization
- * of threads in applications that do not create windows, use your threading
- * library of choice.
- *
- * Event processing is not required for joystick input to work.
- *
- * @param[in] timeout The maximum amount of time, in seconds, to wait.
- *
- * @reentrancy This function must not be called from a callback.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref events
- * @sa glfwPollEvents
- * @sa glfwWaitEvents
- *
- * @since Added in version 3.2.
- *
- * @ingroup window
- */
-GLFWAPI void glfwWaitEventsTimeout(double timeout);
-
-/*! @brief Posts an empty event to the event queue.
- *
- * This function posts an empty event from the current thread to the event
- * queue, causing @ref glfwWaitEvents to return.
- *
- * If no windows exist, this function returns immediately. For synchronization
- * of threads in applications that do not create windows, use your threading
- * library of choice.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref events
- * @sa glfwWaitEvents
- *
- * @since Added in version 3.1.
- *
- * @ingroup window
- */
-GLFWAPI void glfwPostEmptyEvent(void);
-
-/*! @brief Returns the value of an input option for the specified window.
- *
- * This function returns the value of an input option for the specified window.
- * The mode must be one of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or
- * `GLFW_STICKY_MOUSE_BUTTONS`.
- *
- * @param[in] window The window to query.
- * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or
- * `GLFW_STICKY_MOUSE_BUTTONS`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_INVALID_ENUM.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa glfwSetInputMode
- *
- * @since Added in version 3.0.
- *
- * @ingroup input
- */
-GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);
-
-/*! @brief Sets an input option for the specified window.
- *
- * This function sets an input mode option for the specified window. The mode
- * must be one of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or
- * `GLFW_STICKY_MOUSE_BUTTONS`.
- *
- * If the mode is `GLFW_CURSOR`, the value must be one of the following cursor
- * modes:
- * - `GLFW_CURSOR_NORMAL` makes the cursor visible and behaving normally.
- * - `GLFW_CURSOR_HIDDEN` makes the cursor invisible when it is over the client
- * area of the window but does not restrict the cursor from leaving.
- * - `GLFW_CURSOR_DISABLED` hides and grabs the cursor, providing virtual
- * and unlimited cursor movement. This is useful for implementing for
- * example 3D camera controls.
- *
- * If the mode is `GLFW_STICKY_KEYS`, the value must be either `GLFW_TRUE` to
- * enable sticky keys, or `GLFW_FALSE` to disable it. If sticky keys are
- * enabled, a key press will ensure that @ref glfwGetKey returns `GLFW_PRESS`
- * the next time it is called even if the key had been released before the
- * call. This is useful when you are only interested in whether keys have been
- * pressed but not when or in which order.
- *
- * If the mode is `GLFW_STICKY_MOUSE_BUTTONS`, the value must be either
- * `GLFW_TRUE` to enable sticky mouse buttons, or `GLFW_FALSE` to disable it.
- * If sticky mouse buttons are enabled, a mouse button press will ensure that
- * @ref glfwGetMouseButton returns `GLFW_PRESS` the next time it is called even
- * if the mouse button had been released before the call. This is useful when
- * you are only interested in whether mouse buttons have been pressed but not
- * when or in which order.
- *
- * @param[in] window The window whose input mode to set.
- * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or
- * `GLFW_STICKY_MOUSE_BUTTONS`.
- * @param[in] value The new value of the specified input mode.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa glfwGetInputMode
- *
- * @since Added in version 3.0. Replaces `glfwEnable` and `glfwDisable`.
- *
- * @ingroup input
- */
-GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value);
-
-/*! @brief Returns the localized name of the specified printable key.
- *
- * This function returns the localized name of the specified printable key.
- * This is intended for displaying key bindings to the user.
- *
- * If the key is `GLFW_KEY_UNKNOWN`, the scancode is used instead, otherwise
- * the scancode is ignored. If a non-printable key or (if the key is
- * `GLFW_KEY_UNKNOWN`) a scancode that maps to a non-printable key is
- * specified, this function returns `NULL`.
- *
- * This behavior allows you to pass in the arguments passed to the
- * [key callback](@ref input_key) without modification.
- *
- * The printable keys are:
- * - `GLFW_KEY_APOSTROPHE`
- * - `GLFW_KEY_COMMA`
- * - `GLFW_KEY_MINUS`
- * - `GLFW_KEY_PERIOD`
- * - `GLFW_KEY_SLASH`
- * - `GLFW_KEY_SEMICOLON`
- * - `GLFW_KEY_EQUAL`
- * - `GLFW_KEY_LEFT_BRACKET`
- * - `GLFW_KEY_RIGHT_BRACKET`
- * - `GLFW_KEY_BACKSLASH`
- * - `GLFW_KEY_WORLD_1`
- * - `GLFW_KEY_WORLD_2`
- * - `GLFW_KEY_0` to `GLFW_KEY_9`
- * - `GLFW_KEY_A` to `GLFW_KEY_Z`
- * - `GLFW_KEY_KP_0` to `GLFW_KEY_KP_9`
- * - `GLFW_KEY_KP_DECIMAL`
- * - `GLFW_KEY_KP_DIVIDE`
- * - `GLFW_KEY_KP_MULTIPLY`
- * - `GLFW_KEY_KP_SUBTRACT`
- * - `GLFW_KEY_KP_ADD`
- * - `GLFW_KEY_KP_EQUAL`
- *
- * @param[in] key The key to query, or `GLFW_KEY_UNKNOWN`.
- * @param[in] scancode The scancode of the key to query.
- * @return The localized name of the key, or `NULL`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @pointer_lifetime The returned string is allocated and freed by GLFW. You
- * should not free it yourself. It is valid until the next call to @ref
- * glfwGetKeyName, or until the library is terminated.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref input_key_name
- *
- * @since Added in version 3.2.
- *
- * @ingroup input
- */
-GLFWAPI const char* glfwGetKeyName(int key, int scancode);
-
-/*! @brief Returns the last reported state of a keyboard key for the specified
- * window.
- *
- * This function returns the last state reported for the specified key to the
- * specified window. The returned state is one of `GLFW_PRESS` or
- * `GLFW_RELEASE`. The higher-level action `GLFW_REPEAT` is only reported to
- * the key callback.
- *
- * If the `GLFW_STICKY_KEYS` input mode is enabled, this function returns
- * `GLFW_PRESS` the first time you call it for a key that was pressed, even if
- * that key has already been released.
- *
- * The key functions deal with physical keys, with [key tokens](@ref keys)
- * named after their use on the standard US keyboard layout. If you want to
- * input text, use the Unicode character callback instead.
- *
- * The [modifier key bit masks](@ref mods) are not key tokens and cannot be
- * used with this function.
- *
- * __Do not use this function__ to implement [text input](@ref input_char).
- *
- * @param[in] window The desired window.
- * @param[in] key The desired [keyboard key](@ref keys). `GLFW_KEY_UNKNOWN` is
- * not a valid key for this function.
- * @return One of `GLFW_PRESS` or `GLFW_RELEASE`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_INVALID_ENUM.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref input_key
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup input
- */
-GLFWAPI int glfwGetKey(GLFWwindow* window, int key);
-
-/*! @brief Returns the last reported state of a mouse button for the specified
- * window.
- *
- * This function returns the last state reported for the specified mouse button
- * to the specified window. The returned state is one of `GLFW_PRESS` or
- * `GLFW_RELEASE`.
- *
- * If the `GLFW_STICKY_MOUSE_BUTTONS` input mode is enabled, this function
- * `GLFW_PRESS` the first time you call it for a mouse button that was pressed,
- * even if that mouse button has already been released.
- *
- * @param[in] window The desired window.
- * @param[in] button The desired [mouse button](@ref buttons).
- * @return One of `GLFW_PRESS` or `GLFW_RELEASE`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_INVALID_ENUM.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref input_mouse_button
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup input
- */
-GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button);
-
-/*! @brief Retrieves the position of the cursor relative to the client area of
- * the window.
- *
- * This function returns the position of the cursor, in screen coordinates,
- * relative to the upper-left corner of the client area of the specified
- * window.
- *
- * If the cursor is disabled (with `GLFW_CURSOR_DISABLED`) then the cursor
- * position is unbounded and limited only by the minimum and maximum values of
- * a `double`.
- *
- * The coordinate can be converted to their integer equivalents with the
- * `floor` function. Casting directly to an integer type works for positive
- * coordinates, but fails for negative ones.
- *
- * Any or all of the position arguments may be `NULL`. If an error occurs, all
- * non-`NULL` position arguments will be set to zero.
- *
- * @param[in] window The desired window.
- * @param[out] xpos Where to store the cursor x-coordinate, relative to the
- * left edge of the client area, or `NULL`.
- * @param[out] ypos Where to store the cursor y-coordinate, relative to the to
- * top edge of the client area, or `NULL`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref cursor_pos
- * @sa glfwSetCursorPos
- *
- * @since Added in version 3.0. Replaces `glfwGetMousePos`.
- *
- * @ingroup input
- */
-GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos);
-
-/*! @brief Sets the position of the cursor, relative to the client area of the
- * window.
- *
- * This function sets the position, in screen coordinates, of the cursor
- * relative to the upper-left corner of the client area of the specified
- * window. The window must have input focus. If the window does not have
- * input focus when this function is called, it fails silently.
- *
- * __Do not use this function__ to implement things like camera controls. GLFW
- * already provides the `GLFW_CURSOR_DISABLED` cursor mode that hides the
- * cursor, transparently re-centers it and provides unconstrained cursor
- * motion. See @ref glfwSetInputMode for more information.
- *
- * If the cursor mode is `GLFW_CURSOR_DISABLED` then the cursor position is
- * unconstrained and limited only by the minimum and maximum values of
- * a `double`.
- *
- * @param[in] window The desired window.
- * @param[in] xpos The desired x-coordinate, relative to the left edge of the
- * client area.
- * @param[in] ypos The desired y-coordinate, relative to the top edge of the
- * client area.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref cursor_pos
- * @sa glfwGetCursorPos
- *
- * @since Added in version 3.0. Replaces `glfwSetMousePos`.
- *
- * @ingroup input
- */
-GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos);
-
-/*! @brief Creates a custom cursor.
- *
- * Creates a new custom cursor image that can be set for a window with @ref
- * glfwSetCursor. The cursor can be destroyed with @ref glfwDestroyCursor.
- * Any remaining cursors are destroyed by @ref glfwTerminate.
- *
- * The pixels are 32-bit, little-endian, non-premultiplied RGBA, i.e. eight
- * bits per channel. They are arranged canonically as packed sequential rows,
- * starting from the top-left corner.
- *
- * The cursor hotspot is specified in pixels, relative to the upper-left corner
- * of the cursor image. Like all other coordinate systems in GLFW, the X-axis
- * points to the right and the Y-axis points down.
- *
- * @param[in] image The desired cursor image.
- * @param[in] xhot The desired x-coordinate, in pixels, of the cursor hotspot.
- * @param[in] yhot The desired y-coordinate, in pixels, of the cursor hotspot.
- * @return The handle of the created cursor, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @pointer_lifetime The specified image data is copied before this function
- * returns.
- *
- * @reentrancy This function must not be called from a callback.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref cursor_object
- * @sa glfwDestroyCursor
- * @sa glfwCreateStandardCursor
- *
- * @since Added in version 3.1.
- *
- * @ingroup input
- */
-GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot);
-
-/*! @brief Creates a cursor with a standard shape.
- *
- * Returns a cursor with a [standard shape](@ref shapes), that can be set for
- * a window with @ref glfwSetCursor.
- *
- * @param[in] shape One of the [standard shapes](@ref shapes).
- * @return A new cursor ready to use or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
- *
- * @reentrancy This function must not be called from a callback.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref cursor_object
- * @sa glfwCreateCursor
- *
- * @since Added in version 3.1.
- *
- * @ingroup input
- */
-GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape);
-
-/*! @brief Destroys a cursor.
- *
- * This function destroys a cursor previously created with @ref
- * glfwCreateCursor. Any remaining cursors will be destroyed by @ref
- * glfwTerminate.
- *
- * @param[in] cursor The cursor object to destroy.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @reentrancy This function must not be called from a callback.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref cursor_object
- * @sa glfwCreateCursor
- *
- * @since Added in version 3.1.
- *
- * @ingroup input
- */
-GLFWAPI void glfwDestroyCursor(GLFWcursor* cursor);
-
-/*! @brief Sets the cursor for the window.
- *
- * This function sets the cursor image to be used when the cursor is over the
- * client area of the specified window. The set cursor will only be visible
- * when the [cursor mode](@ref cursor_mode) of the window is
- * `GLFW_CURSOR_NORMAL`.
- *
- * On some platforms, the set cursor may not be visible unless the window also
- * has input focus.
- *
- * @param[in] window The window to set the cursor for.
- * @param[in] cursor The cursor to set, or `NULL` to switch back to the default
- * arrow cursor.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref cursor_object
- *
- * @since Added in version 3.1.
- *
- * @ingroup input
- */
-GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor);
-
-/*! @brief Sets the key callback.
- *
- * This function sets the key callback of the specified window, which is called
- * when a key is pressed, repeated or released.
- *
- * The key functions deal with physical keys, with layout independent
- * [key tokens](@ref keys) named after their values in the standard US keyboard
- * layout. If you want to input text, use the
- * [character callback](@ref glfwSetCharCallback) instead.
- *
- * When a window loses input focus, it will generate synthetic key release
- * events for all pressed keys. You can tell these events from user-generated
- * events by the fact that the synthetic ones are generated after the focus
- * loss event has been processed, i.e. after the
- * [window focus callback](@ref glfwSetWindowFocusCallback) has been called.
- *
- * The scancode of a key is specific to that platform or sometimes even to that
- * machine. Scancodes are intended to allow users to bind keys that don't have
- * a GLFW key token. Such keys have `key` set to `GLFW_KEY_UNKNOWN`, their
- * state is not saved and so it cannot be queried with @ref glfwGetKey.
- *
- * Sometimes GLFW needs to generate synthetic key events, in which case the
- * scancode may be zero.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new key callback, or `NULL` to remove the currently
- * set callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref input_key
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle parameter and return value.
- *
- * @ingroup input
- */
-GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun cbfun);
-
-/*! @brief Sets the Unicode character callback.
- *
- * This function sets the character callback of the specified window, which is
- * called when a Unicode character is input.
- *
- * The character callback is intended for Unicode text input. As it deals with
- * characters, it is keyboard layout dependent, whereas the
- * [key callback](@ref glfwSetKeyCallback) is not. Characters do not map 1:1
- * to physical keys, as a key may produce zero, one or more characters. If you
- * want to know whether a specific physical key was pressed or released, see
- * the key callback instead.
- *
- * The character callback behaves as system text input normally does and will
- * not be called if modifier keys are held down that would prevent normal text
- * input on that platform, for example a Super (Command) key on OS X or Alt key
- * on Windows. There is a
- * [character with modifiers callback](@ref glfwSetCharModsCallback) that
- * receives these events.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref input_char
- *
- * @since Added in version 2.4.
- * @glfw3 Added window handle parameter and return value.
- *
- * @ingroup input
- */
-GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* window, GLFWcharfun cbfun);
-
-/*! @brief Sets the Unicode character with modifiers callback.
- *
- * This function sets the character with modifiers callback of the specified
- * window, which is called when a Unicode character is input regardless of what
- * modifier keys are used.
- *
- * The character with modifiers callback is intended for implementing custom
- * Unicode character input. For regular Unicode text input, see the
- * [character callback](@ref glfwSetCharCallback). Like the character
- * callback, the character with modifiers callback deals with characters and is
- * keyboard layout dependent. Characters do not map 1:1 to physical keys, as
- * a key may produce zero, one or more characters. If you want to know whether
- * a specific physical key was pressed or released, see the
- * [key callback](@ref glfwSetKeyCallback) instead.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or an
- * error occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref input_char
- *
- * @since Added in version 3.1.
- *
- * @ingroup input
- */
-GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmodsfun cbfun);
-
-/*! @brief Sets the mouse button callback.
- *
- * This function sets the mouse button callback of the specified window, which
- * is called when a mouse button is pressed or released.
- *
- * When a window loses input focus, it will generate synthetic mouse button
- * release events for all pressed mouse buttons. You can tell these events
- * from user-generated events by the fact that the synthetic ones are generated
- * after the focus loss event has been processed, i.e. after the
- * [window focus callback](@ref glfwSetWindowFocusCallback) has been called.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref input_mouse_button
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle parameter and return value.
- *
- * @ingroup input
- */
-GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* window, GLFWmousebuttonfun cbfun);
-
-/*! @brief Sets the cursor position callback.
- *
- * This function sets the cursor position callback of the specified window,
- * which is called when the cursor is moved. The callback is provided with the
- * position, in screen coordinates, relative to the upper-left corner of the
- * client area of the window.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref cursor_pos
- *
- * @since Added in version 3.0. Replaces `glfwSetMousePosCallback`.
- *
- * @ingroup input
- */
-GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* window, GLFWcursorposfun cbfun);
-
-/*! @brief Sets the cursor enter/exit callback.
- *
- * This function sets the cursor boundary crossing callback of the specified
- * window, which is called when the cursor enters or leaves the client area of
- * the window.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref cursor_enter
- *
- * @since Added in version 3.0.
- *
- * @ingroup input
- */
-GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* window, GLFWcursorenterfun cbfun);
-
-/*! @brief Sets the scroll callback.
- *
- * This function sets the scroll callback of the specified window, which is
- * called when a scrolling device is used, such as a mouse wheel or scrolling
- * area of a touchpad.
- *
- * The scroll callback receives all scrolling input, like that from a mouse
- * wheel or a touchpad scrolling area.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new scroll callback, or `NULL` to remove the currently
- * set callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref scrolling
- *
- * @since Added in version 3.0. Replaces `glfwSetMouseWheelCallback`.
- *
- * @ingroup input
- */
-GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun cbfun);
-
-/*! @brief Sets the file drop callback.
- *
- * This function sets the file drop callback of the specified window, which is
- * called when one or more dragged files are dropped on the window.
- *
- * Because the path array and its strings may have been generated specifically
- * for that event, they are not guaranteed to be valid after the callback has
- * returned. If you wish to use them after the callback returns, you need to
- * make a deep copy.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new file drop callback, or `NULL` to remove the
- * currently set callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref path_drop
- *
- * @since Added in version 3.1.
- *
- * @ingroup input
- */
-GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* window, GLFWdropfun cbfun);
-
-/*! @brief Returns whether the specified joystick is present.
- *
- * This function returns whether the specified joystick is present.
- *
- * @param[in] joy The [joystick](@ref joysticks) to query.
- * @return `GLFW_TRUE` if the joystick is present, or `GLFW_FALSE` otherwise.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref joystick
- *
- * @since Added in version 3.0. Replaces `glfwGetJoystickParam`.
- *
- * @ingroup input
- */
-GLFWAPI int glfwJoystickPresent(int joy);
-
-/*! @brief Returns the values of all axes of the specified joystick.
- *
- * This function returns the values of all axes of the specified joystick.
- * Each element in the array is a value between -1.0 and 1.0.
- *
- * Querying a joystick slot with no device present is not an error, but will
- * cause this function to return `NULL`. Call @ref glfwJoystickPresent to
- * check device presence.
- *
- * @param[in] joy The [joystick](@ref joysticks) to query.
- * @param[out] count Where to store the number of axis values in the returned
- * array. This is set to zero if an error occurred.
- * @return An array of axis values, or `NULL` if the joystick is not present.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
- *
- * @pointer_lifetime The returned array is allocated and freed by GLFW. You
- * should not free it yourself. It is valid until the specified joystick is
- * disconnected, this function is called again for that joystick or the library
- * is terminated.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref joystick_axis
- *
- * @since Added in version 3.0. Replaces `glfwGetJoystickPos`.
- *
- * @ingroup input
- */
-GLFWAPI const float* glfwGetJoystickAxes(int joy, int* count);
-
-/*! @brief Returns the state of all buttons of the specified joystick.
- *
- * This function returns the state of all buttons of the specified joystick.
- * Each element in the array is either `GLFW_PRESS` or `GLFW_RELEASE`.
- *
- * Querying a joystick slot with no device present is not an error, but will
- * cause this function to return `NULL`. Call @ref glfwJoystickPresent to
- * check device presence.
- *
- * @param[in] joy The [joystick](@ref joysticks) to query.
- * @param[out] count Where to store the number of button states in the returned
- * array. This is set to zero if an error occurred.
- * @return An array of button states, or `NULL` if the joystick is not present.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
- *
- * @pointer_lifetime The returned array is allocated and freed by GLFW. You
- * should not free it yourself. It is valid until the specified joystick is
- * disconnected, this function is called again for that joystick or the library
- * is terminated.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref joystick_button
- *
- * @since Added in version 2.2.
- * @glfw3 Changed to return a dynamic array.
- *
- * @ingroup input
- */
-GLFWAPI const unsigned char* glfwGetJoystickButtons(int joy, int* count);
-
-/*! @brief Returns the name of the specified joystick.
- *
- * This function returns the name, encoded as UTF-8, of the specified joystick.
- * The returned string is allocated and freed by GLFW. You should not free it
- * yourself.
- *
- * Querying a joystick slot with no device present is not an error, but will
- * cause this function to return `NULL`. Call @ref glfwJoystickPresent to
- * check device presence.
- *
- * @param[in] joy The [joystick](@ref joysticks) to query.
- * @return The UTF-8 encoded name of the joystick, or `NULL` if the joystick
- * is not present.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
- *
- * @pointer_lifetime The returned string is allocated and freed by GLFW. You
- * should not free it yourself. It is valid until the specified joystick is
- * disconnected, this function is called again for that joystick or the library
- * is terminated.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref joystick_name
- *
- * @since Added in version 3.0.
- *
- * @ingroup input
- */
-GLFWAPI const char* glfwGetJoystickName(int joy);
-
-/*! @brief Sets the joystick configuration callback.
- *
- * This function sets the joystick configuration callback, or removes the
- * currently set callback. This is called when a joystick is connected to or
- * disconnected from the system.
- *
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref joystick_event
- *
- * @since Added in version 3.2.
- *
- * @ingroup input
- */
-GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun);
-
-/*! @brief Sets the clipboard to the specified string.
- *
- * This function sets the system clipboard to the specified, UTF-8 encoded
- * string.
- *
- * @param[in] window The window that will own the clipboard contents.
- * @param[in] string A UTF-8 encoded string.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @pointer_lifetime The specified string is copied before this function
- * returns.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref clipboard
- * @sa glfwGetClipboardString
- *
- * @since Added in version 3.0.
- *
- * @ingroup input
- */
-GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string);
-
-/*! @brief Returns the contents of the clipboard as a string.
- *
- * This function returns the contents of the system clipboard, if it contains
- * or is convertible to a UTF-8 encoded string. If the clipboard is empty or
- * if its contents cannot be converted, `NULL` is returned and a @ref
- * GLFW_FORMAT_UNAVAILABLE error is generated.
- *
- * @param[in] window The window that will request the clipboard contents.
- * @return The contents of the clipboard as a UTF-8 encoded string, or `NULL`
- * if an [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @pointer_lifetime The returned string is allocated and freed by GLFW. You
- * should not free it yourself. It is valid until the next call to @ref
- * glfwGetClipboardString or @ref glfwSetClipboardString, or until the library
- * is terminated.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref clipboard
- * @sa glfwSetClipboardString
- *
- * @since Added in version 3.0.
- *
- * @ingroup input
- */
-GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window);
-
-/*! @brief Returns the value of the GLFW timer.
- *
- * This function returns the value of the GLFW timer. Unless the timer has
- * been set using @ref glfwSetTime, the timer measures time elapsed since GLFW
- * was initialized.
- *
- * The resolution of the timer is system dependent, but is usually on the order
- * of a few micro- or nanoseconds. It uses the highest-resolution monotonic
- * time source on each supported platform.
- *
- * @return The current value, in seconds, or zero if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function may be called from any thread. Reading and
- * writing of the internal timer offset is not atomic, so it needs to be
- * externally synchronized with calls to @ref glfwSetTime.
- *
- * @sa @ref time
- *
- * @since Added in version 1.0.
- *
- * @ingroup input
- */
-GLFWAPI double glfwGetTime(void);
-
-/*! @brief Sets the GLFW timer.
- *
- * This function sets the value of the GLFW timer. It then continues to count
- * up from that value. The value must be a positive finite number less than
- * or equal to 18446744073.0, which is approximately 584.5 years.
- *
- * @param[in] time The new value, in seconds.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_INVALID_VALUE.
- *
- * @remark The upper limit of the timer is calculated as
- * floor((264 - 1) / 109) and is due to implementations
- * storing nanoseconds in 64 bits. The limit may be increased in the future.
- *
- * @thread_safety This function may be called from any thread. Reading and
- * writing of the internal timer offset is not atomic, so it needs to be
- * externally synchronized with calls to @ref glfwGetTime.
- *
- * @sa @ref time
- *
- * @since Added in version 2.2.
- *
- * @ingroup input
- */
-GLFWAPI void glfwSetTime(double time);
-
-/*! @brief Returns the current value of the raw timer.
- *
- * This function returns the current value of the raw timer, measured in
- * 1 / frequency seconds. To get the frequency, call @ref
- * glfwGetTimerFrequency.
- *
- * @return The value of the timer, or zero if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref time
- * @sa glfwGetTimerFrequency
- *
- * @since Added in version 3.2.
- *
- * @ingroup input
- */
-GLFWAPI uint64_t glfwGetTimerValue(void);
-
-/*! @brief Returns the frequency, in Hz, of the raw timer.
- *
- * This function returns the frequency, in Hz, of the raw timer.
- *
- * @return The frequency of the timer, in Hz, or zero if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref time
- * @sa glfwGetTimerValue
- *
- * @since Added in version 3.2.
- *
- * @ingroup input
- */
-GLFWAPI uint64_t glfwGetTimerFrequency(void);
-
-/*! @brief Makes the context of the specified window current for the calling
- * thread.
- *
- * This function makes the OpenGL or OpenGL ES context of the specified window
- * current on the calling thread. A context can only be made current on
- * a single thread at a time and each thread can have only a single current
- * context at a time.
- *
- * By default, making a context non-current implicitly forces a pipeline flush.
- * On machines that support `GL_KHR_context_flush_control`, you can control
- * whether a context performs this flush by setting the
- * [GLFW_CONTEXT_RELEASE_BEHAVIOR](@ref window_hints_ctx) window hint.
- *
- * The specified window must have an OpenGL or OpenGL ES context. Specifying
- * a window without a context will generate a @ref GLFW_NO_WINDOW_CONTEXT
- * error.
- *
- * @param[in] window The window whose context to make current, or `NULL` to
- * detach the current context.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref context_current
- * @sa glfwGetCurrentContext
- *
- * @since Added in version 3.0.
- *
- * @ingroup context
- */
-GLFWAPI void glfwMakeContextCurrent(GLFWwindow* window);
-
-/*! @brief Returns the window whose context is current on the calling thread.
- *
- * This function returns the window whose OpenGL or OpenGL ES context is
- * current on the calling thread.
- *
- * @return The window whose context is current, or `NULL` if no window's
- * context is current.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref context_current
- * @sa glfwMakeContextCurrent
- *
- * @since Added in version 3.0.
- *
- * @ingroup context
- */
-GLFWAPI GLFWwindow* glfwGetCurrentContext(void);
-
-/*! @brief Swaps the front and back buffers of the specified window.
- *
- * This function swaps the front and back buffers of the specified window when
- * rendering with OpenGL or OpenGL ES. If the swap interval is greater than
- * zero, the GPU driver waits the specified number of screen updates before
- * swapping the buffers.
- *
- * The specified window must have an OpenGL or OpenGL ES context. Specifying
- * a window without a context will generate a @ref GLFW_NO_WINDOW_CONTEXT
- * error.
- *
- * This function does not apply to Vulkan. If you are rendering with Vulkan,
- * see `vkQueuePresentKHR` instead.
- *
- * @param[in] window The window whose buffers to swap.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR.
- *
- * @remark __EGL:__ The context of the specified window must be current on the
- * calling thread.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref buffer_swap
- * @sa glfwSwapInterval
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup window
- */
-GLFWAPI void glfwSwapBuffers(GLFWwindow* window);
-
-/*! @brief Sets the swap interval for the current context.
- *
- * This function sets the swap interval for the current OpenGL or OpenGL ES
- * context, i.e. the number of screen updates to wait from the time @ref
- * glfwSwapBuffers was called before swapping the buffers and returning. This
- * is sometimes called _vertical synchronization_, _vertical retrace
- * synchronization_ or just _vsync_.
- *
- * Contexts that support either of the `WGL_EXT_swap_control_tear` and
- * `GLX_EXT_swap_control_tear` extensions also accept negative swap intervals,
- * which allow the driver to swap even if a frame arrives a little bit late.
- * You can check for the presence of these extensions using @ref
- * glfwExtensionSupported. For more information about swap tearing, see the
- * extension specifications.
- *
- * A context must be current on the calling thread. Calling this function
- * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error.
- *
- * This function does not apply to Vulkan. If you are rendering with Vulkan,
- * see the present mode of your swapchain instead.
- *
- * @param[in] interval The minimum number of screen updates to wait for
- * until the buffers are swapped by @ref glfwSwapBuffers.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_NO_CURRENT_CONTEXT and @ref GLFW_PLATFORM_ERROR.
- *
- * @remark This function is not called during context creation, leaving the
- * swap interval set to whatever is the default on that platform. This is done
- * because some swap interval extensions used by GLFW do not allow the swap
- * interval to be reset to zero once it has been set to a non-zero value.
- *
- * @remark Some GPU drivers do not honor the requested swap interval, either
- * because of a user setting that overrides the application's request or due to
- * bugs in the driver.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref buffer_swap
- * @sa glfwSwapBuffers
- *
- * @since Added in version 1.0.
- *
- * @ingroup context
- */
-GLFWAPI void glfwSwapInterval(int interval);
-
-/*! @brief Returns whether the specified extension is available.
- *
- * This function returns whether the specified
- * [API extension](@ref context_glext) is supported by the current OpenGL or
- * OpenGL ES context. It searches both for client API extension and context
- * creation API extensions.
- *
- * A context must be current on the calling thread. Calling this function
- * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error.
- *
- * As this functions retrieves and searches one or more extension strings each
- * call, it is recommended that you cache its results if it is going to be used
- * frequently. The extension strings will not change during the lifetime of
- * a context, so there is no danger in doing this.
- *
- * This function does not apply to Vulkan. If you are using Vulkan, see @ref
- * glfwGetRequiredInstanceExtensions, `vkEnumerateInstanceExtensionProperties`
- * and `vkEnumerateDeviceExtensionProperties` instead.
- *
- * @param[in] extension The ASCII encoded name of the extension.
- * @return `GLFW_TRUE` if the extension is available, or `GLFW_FALSE`
- * otherwise.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_NO_CURRENT_CONTEXT, @ref GLFW_INVALID_VALUE and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref context_glext
- * @sa glfwGetProcAddress
- *
- * @since Added in version 1.0.
- *
- * @ingroup context
- */
-GLFWAPI int glfwExtensionSupported(const char* extension);
-
-/*! @brief Returns the address of the specified function for the current
- * context.
- *
- * This function returns the address of the specified OpenGL or OpenGL ES
- * [core or extension function](@ref context_glext), if it is supported
- * by the current context.
- *
- * A context must be current on the calling thread. Calling this function
- * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error.
- *
- * This function does not apply to Vulkan. If you are rendering with Vulkan,
- * see @ref glfwGetInstanceProcAddress, `vkGetInstanceProcAddr` and
- * `vkGetDeviceProcAddr` instead.
- *
- * @param[in] procname The ASCII encoded name of the function.
- * @return The address of the function, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_NO_CURRENT_CONTEXT and @ref GLFW_PLATFORM_ERROR.
- *
- * @remark The address of a given function is not guaranteed to be the same
- * between contexts.
- *
- * @remark This function may return a non-`NULL` address despite the
- * associated version or extension not being available. Always check the
- * context version or extension string first.
- *
- * @pointer_lifetime The returned function pointer is valid until the context
- * is destroyed or the library is terminated.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref context_glext
- * @sa glfwExtensionSupported
- *
- * @since Added in version 1.0.
- *
- * @ingroup context
- */
-GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname);
-
-/*! @brief Returns whether the Vulkan loader has been found.
- *
- * This function returns whether the Vulkan loader has been found. This check
- * is performed by @ref glfwInit.
- *
- * The availability of a Vulkan loader does not by itself guarantee that window
- * surface creation or even device creation is possible. Call @ref
- * glfwGetRequiredInstanceExtensions to check whether the extensions necessary
- * for Vulkan surface creation are available and @ref
- * glfwGetPhysicalDevicePresentationSupport to check whether a queue family of
- * a physical device supports image presentation.
- *
- * @return `GLFW_TRUE` if Vulkan is available, or `GLFW_FALSE` otherwise.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref vulkan_support
- *
- * @since Added in version 3.2.
- *
- * @ingroup vulkan
- */
-GLFWAPI int glfwVulkanSupported(void);
-
-/*! @brief Returns the Vulkan instance extensions required by GLFW.
- *
- * This function returns an array of names of Vulkan instance extensions required
- * by GLFW for creating Vulkan surfaces for GLFW windows. If successful, the
- * list will always contains `VK_KHR_surface`, so if you don't require any
- * additional extensions you can pass this list directly to the
- * `VkInstanceCreateInfo` struct.
- *
- * If Vulkan is not available on the machine, this function returns `NULL` and
- * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported
- * to check whether Vulkan is available.
- *
- * If Vulkan is available but no set of extensions allowing window surface
- * creation was found, this function returns `NULL`. You may still use Vulkan
- * for off-screen rendering and compute work.
- *
- * @param[out] count Where to store the number of extensions in the returned
- * array. This is set to zero if an error occurred.
- * @return An array of ASCII encoded extension names, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_API_UNAVAILABLE.
- *
- * @remarks Additional extensions may be required by future versions of GLFW.
- * You should check if any extensions you wish to enable are already in the
- * returned array, as it is an error to specify an extension more than once in
- * the `VkInstanceCreateInfo` struct.
- *
- * @pointer_lifetime The returned array is allocated and freed by GLFW. You
- * should not free it yourself. It is guaranteed to be valid only until the
- * library is terminated.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref vulkan_ext
- * @sa glfwCreateWindowSurface
- *
- * @since Added in version 3.2.
- *
- * @ingroup vulkan
- */
-GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count);
-
-#if defined(VK_VERSION_1_0)
-
-/*! @brief Returns the address of the specified Vulkan instance function.
- *
- * This function returns the address of the specified Vulkan core or extension
- * function for the specified instance. If instance is set to `NULL` it can
- * return any function exported from the Vulkan loader, including at least the
- * following functions:
- *
- * - `vkEnumerateInstanceExtensionProperties`
- * - `vkEnumerateInstanceLayerProperties`
- * - `vkCreateInstance`
- * - `vkGetInstanceProcAddr`
- *
- * If Vulkan is not available on the machine, this function returns `NULL` and
- * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported
- * to check whether Vulkan is available.
- *
- * This function is equivalent to calling `vkGetInstanceProcAddr` with
- * a platform-specific query of the Vulkan loader as a fallback.
- *
- * @param[in] instance The Vulkan instance to query, or `NULL` to retrieve
- * functions related to instance creation.
- * @param[in] procname The ASCII encoded name of the function.
- * @return The address of the function, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_API_UNAVAILABLE.
- *
- * @pointer_lifetime The returned function pointer is valid until the library
- * is terminated.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref vulkan_proc
- *
- * @since Added in version 3.2.
- *
- * @ingroup vulkan
- */
-GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* procname);
-
-/*! @brief Returns whether the specified queue family can present images.
- *
- * This function returns whether the specified queue family of the specified
- * physical device supports presentation to the platform GLFW was built for.
- *
- * If Vulkan or the required window surface creation instance extensions are
- * not available on the machine, or if the specified instance was not created
- * with the required extensions, this function returns `GLFW_FALSE` and
- * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported
- * to check whether Vulkan is available and @ref
- * glfwGetRequiredInstanceExtensions to check what instance extensions are
- * required.
- *
- * @param[in] instance The instance that the physical device belongs to.
- * @param[in] device The physical device that the queue family belongs to.
- * @param[in] queuefamily The index of the queue family to query.
- * @return `GLFW_TRUE` if the queue family supports presentation, or
- * `GLFW_FALSE` otherwise.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function may be called from any thread. For
- * synchronization details of Vulkan objects, see the Vulkan specification.
- *
- * @sa @ref vulkan_present
- *
- * @since Added in version 3.2.
- *
- * @ingroup vulkan
- */
-GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
-
-/*! @brief Creates a Vulkan surface for the specified window.
- *
- * This function creates a Vulkan surface for the specified window.
- *
- * If the Vulkan loader was not found at initialization, this function returns
- * `VK_ERROR_INITIALIZATION_FAILED` and generates a @ref GLFW_API_UNAVAILABLE
- * error. Call @ref glfwVulkanSupported to check whether the Vulkan loader was
- * found.
- *
- * If the required window surface creation instance extensions are not
- * available or if the specified instance was not created with these extensions
- * enabled, this function returns `VK_ERROR_EXTENSION_NOT_PRESENT` and
- * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref
- * glfwGetRequiredInstanceExtensions to check what instance extensions are
- * required.
- *
- * The window surface must be destroyed before the specified Vulkan instance.
- * It is the responsibility of the caller to destroy the window surface. GLFW
- * does not destroy it for you. Call `vkDestroySurfaceKHR` to destroy the
- * surface.
- *
- * @param[in] instance The Vulkan instance to create the surface in.
- * @param[in] window The window to create the surface for.
- * @param[in] allocator The allocator to use, or `NULL` to use the default
- * allocator.
- * @param[out] surface Where to store the handle of the surface. This is set
- * to `VK_NULL_HANDLE` if an error occurred.
- * @return `VK_SUCCESS` if successful, or a Vulkan error code if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.
- *
- * @remarks If an error occurs before the creation call is made, GLFW returns
- * the Vulkan error code most appropriate for the error. Appropriate use of
- * @ref glfwVulkanSupported and @ref glfwGetRequiredInstanceExtensions should
- * eliminate almost all occurrences of these errors.
- *
- * @thread_safety This function may be called from any thread. For
- * synchronization details of Vulkan objects, see the Vulkan specification.
- *
- * @sa @ref vulkan_surface
- * @sa glfwGetRequiredInstanceExtensions
- *
- * @since Added in version 3.2.
- *
- * @ingroup vulkan
- */
-GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);
-
-#endif /*VK_VERSION_1_0*/
-
-
-/*************************************************************************
- * Global definition cleanup
- *************************************************************************/
-
-/* ------------------- BEGIN SYSTEM/COMPILER SPECIFIC -------------------- */
-
-#ifdef GLFW_WINGDIAPI_DEFINED
- #undef WINGDIAPI
- #undef GLFW_WINGDIAPI_DEFINED
-#endif
-
-#ifdef GLFW_CALLBACK_DEFINED
- #undef CALLBACK
- #undef GLFW_CALLBACK_DEFINED
-#endif
-
-/* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _glfw3_h_ */
-
diff --git a/project/vs2015/external/glfw3/lib/win32/glfw3.dll b/project/vs2015/external/glfw3/lib/win32/glfw3.dll
deleted file mode 100644
index 3e2a7f355..000000000
Binary files a/project/vs2015/external/glfw3/lib/win32/glfw3.dll and /dev/null differ
diff --git a/project/vs2015/external/glfw3/lib/win32/glfw3.lib b/project/vs2015/external/glfw3/lib/win32/glfw3.lib
deleted file mode 100644
index bec8cfc9a..000000000
Binary files a/project/vs2015/external/glfw3/lib/win32/glfw3.lib and /dev/null differ
diff --git a/project/vs2015/external/glfw3/lib/win32/glfw3dll.lib b/project/vs2015/external/glfw3/lib/win32/glfw3dll.lib
deleted file mode 100644
index 8e87d64aa..000000000
Binary files a/project/vs2015/external/glfw3/lib/win32/glfw3dll.lib and /dev/null differ
diff --git a/project/vs2015/external/openal_soft/COPYING b/project/vs2015/external/openal_soft/COPYING
deleted file mode 100644
index d0c897869..000000000
--- a/project/vs2015/external/openal_soft/COPYING
+++ /dev/null
@@ -1,484 +0,0 @@
-
- GNU LIBRARY GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
-
- Copyright (C) 1991 Free Software Foundation, Inc.
- 675 Mass Ave, Cambridge, MA 02139, USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the library GPL. It is
- numbered 2 because it goes with version 2 of the ordinary GPL.]
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
- This license, the Library General Public License, applies to some
-specially designated Free Software Foundation software, and to any
-other libraries whose authors decide to use it. You can use it for
-your libraries, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if
-you distribute copies of the library, or if you modify it.
-
- For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you. You must make sure that they, too, receive or can get the source
-code. If you link a program with the library, you must provide
-complete object files to the recipients so that they can relink them
-with the library, after making changes to the library and recompiling
-it. And you must show them these terms so they know their rights.
-
- Our method of protecting your rights has two steps: (1) copyright
-the library, and (2) offer you this license which gives you legal
-permission to copy, distribute and/or modify the library.
-
- Also, for each distributor's protection, we want to make certain
-that everyone understands that there is no warranty for this free
-library. If the library is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original
-version, so that any problems introduced by others will not reflect on
-the original authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that companies distributing free
-software will individually obtain patent licenses, thus in effect
-transforming the program into proprietary software. To prevent this,
-we have made it clear that any patent must be licensed for everyone's
-free use or not licensed at all.
-
- Most GNU software, including some libraries, is covered by the ordinary
-GNU General Public License, which was designed for utility programs. This
-license, the GNU Library General Public License, applies to certain
-designated libraries. This license is quite different from the ordinary
-one; be sure to read it in full, and don't assume that anything in it is
-the same as in the ordinary license.
-
- The reason we have a separate public license for some libraries is that
-they blur the distinction we usually make between modifying or adding to a
-program and simply using it. Linking a program with a library, without
-changing the library, is in some sense simply using the library, and is
-analogous to running a utility program or application program. However, in
-a textual and legal sense, the linked executable is a combined work, a
-derivative of the original library, and the ordinary General Public License
-treats it as such.
-
- Because of this blurred distinction, using the ordinary General
-Public License for libraries did not effectively promote software
-sharing, because most developers did not use the libraries. We
-concluded that weaker conditions might promote sharing better.
-
- However, unrestricted linking of non-free programs would deprive the
-users of those programs of all benefit from the free status of the
-libraries themselves. This Library General Public License is intended to
-permit developers of non-free programs to use free libraries, while
-preserving your freedom as a user of such programs to change the free
-libraries that are incorporated in them. (We have not seen how to achieve
-this as regards changes in header files, but we have achieved it as regards
-changes in the actual functions of the Library.) The hope is that this
-will lead to faster development of free libraries.
-
- The precise terms and conditions for copying, distribution and
-modification follow. Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library". The
-former contains code derived from the library, while the latter only
-works together with the library.
-
- Note that it is possible for a library to be covered by the ordinary
-General Public License rather than by this special one.
-
- GNU LIBRARY GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License Agreement applies to any software library which
-contains a notice placed by the copyright holder or other authorized
-party saying it may be distributed under the terms of this Library
-General Public License (also called "this License"). Each licensee is
-addressed as "you".
-
- A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
- The "Library", below, refers to any such software library or work
-which has been distributed under these terms. A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language. (Hereinafter, translation is
-included without limitation in the term "modification".)
-
- "Source code" for a work means the preferred form of the work for
-making modifications to it. For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
- Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it). Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-
- 1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
- You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-
- 2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) The modified work must itself be a software library.
-
- b) You must cause the files modified to carry prominent notices
- stating that you changed the files and the date of any change.
-
- c) You must cause the whole of the work to be licensed at no
- charge to all third parties under the terms of this License.
-
- d) If a facility in the modified Library refers to a function or a
- table of data to be supplied by an application program that uses
- the facility, other than as an argument passed when the facility
- is invoked, then you must make a good faith effort to ensure that,
- in the event an application does not supply such function or
- table, the facility still operates, and performs whatever part of
- its purpose remains meaningful.
-
- (For example, a function in a library to compute square roots has
- a purpose that is entirely well-defined independent of the
- application. Therefore, Subsection 2d requires that any
- application-supplied function or table used by this function must
- be optional: if the application does not supply it, the square
- root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library. To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License. (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.) Do not make any other change in
-these notices.
-
- Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
- This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
- 4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
- If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library". Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
- However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library". The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
- When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library. The
-threshold for this to be true is not precisely defined by law.
-
- If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work. (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
- Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-
- 6. As an exception to the Sections above, you may also compile or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
- You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License. You must supply a copy of this License. If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License. Also, you must do one
-of these things:
-
- a) Accompany the work with the complete corresponding
- machine-readable source code for the Library including whatever
- changes were used in the work (which must be distributed under
- Sections 1 and 2 above); and, if the work is an executable linked
- with the Library, with the complete machine-readable "work that
- uses the Library", as object code and/or source code, so that the
- user can modify the Library and then relink to produce a modified
- executable containing the modified Library. (It is understood
- that the user who changes the contents of definitions files in the
- Library will not necessarily be able to recompile the application
- to use the modified definitions.)
-
- b) Accompany the work with a written offer, valid for at
- least three years, to give the same user the materials
- specified in Subsection 6a, above, for a charge no more
- than the cost of performing this distribution.
-
- c) If distribution of the work is made by offering access to copy
- from a designated place, offer equivalent access to copy the above
- specified materials from the same place.
-
- d) Verify that the user has already received a copy of these
- materials or that you have already sent this user a copy.
-
- For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it. However, as a special exception,
-the source code distributed need not include anything that is normally
-distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
- It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system. Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-
- 7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
- a) Accompany the combined library with a copy of the same work
- based on the Library, uncombined with any other library
- facilities. This must be distributed under the terms of the
- Sections above.
-
- b) Give prominent notice with the combined library of the fact
- that part of it is a work based on the Library, and explaining
- where to find the accompanying uncombined form of the same work.
-
- 8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License. Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License. However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
- 9. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Library or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
- 10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all. For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded. In such case, this License incorporates the limitation as if
-written in the body of this License.
-
- 13. The Free Software Foundation may publish revised and/or new
-versions of the Library General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation. If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-
- 14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission. For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this. Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
- NO WARRANTY
-
- 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- Appendix: How to Apply These Terms to Your New Libraries
-
- If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change. You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
- To apply these terms, attach the following notices to the library. It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
-
- Copyright (C)
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the
- library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
- , 1 April 1990
- Ty Coon, President of Vice
-
-That's all there is to it!
-
diff --git a/project/vs2015/external/openal_soft/include/AL/al.h b/project/vs2015/external/openal_soft/include/AL/al.h
deleted file mode 100644
index 413b38331..000000000
--- a/project/vs2015/external/openal_soft/include/AL/al.h
+++ /dev/null
@@ -1,656 +0,0 @@
-#ifndef AL_AL_H
-#define AL_AL_H
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-#ifndef AL_API
- #if defined(AL_LIBTYPE_STATIC)
- #define AL_API
- #elif defined(_WIN32)
- #define AL_API __declspec(dllimport)
- #else
- #define AL_API extern
- #endif
-#endif
-
-#if defined(_WIN32)
- #define AL_APIENTRY __cdecl
-#else
- #define AL_APIENTRY
-#endif
-
-
-/** Deprecated macro. */
-#define OPENAL
-#define ALAPI AL_API
-#define ALAPIENTRY AL_APIENTRY
-#define AL_INVALID (-1)
-#define AL_ILLEGAL_ENUM AL_INVALID_ENUM
-#define AL_ILLEGAL_COMMAND AL_INVALID_OPERATION
-
-/** Supported AL version. */
-#define AL_VERSION_1_0
-#define AL_VERSION_1_1
-
-/** 8-bit boolean */
-typedef char ALboolean;
-
-/** character */
-typedef char ALchar;
-
-/** signed 8-bit 2's complement integer */
-typedef signed char ALbyte;
-
-/** unsigned 8-bit integer */
-typedef unsigned char ALubyte;
-
-/** signed 16-bit 2's complement integer */
-typedef short ALshort;
-
-/** unsigned 16-bit integer */
-typedef unsigned short ALushort;
-
-/** signed 32-bit 2's complement integer */
-typedef int ALint;
-
-/** unsigned 32-bit integer */
-typedef unsigned int ALuint;
-
-/** non-negative 32-bit binary integer size */
-typedef int ALsizei;
-
-/** enumerated 32-bit value */
-typedef int ALenum;
-
-/** 32-bit IEEE754 floating-point */
-typedef float ALfloat;
-
-/** 64-bit IEEE754 floating-point */
-typedef double ALdouble;
-
-/** void type (for opaque pointers only) */
-typedef void ALvoid;
-
-
-/* Enumerant values begin at column 50. No tabs. */
-
-/** "no distance model" or "no buffer" */
-#define AL_NONE 0
-
-/** Boolean False. */
-#define AL_FALSE 0
-
-/** Boolean True. */
-#define AL_TRUE 1
-
-
-/**
- * Relative source.
- * Type: ALboolean
- * Range: [AL_TRUE, AL_FALSE]
- * Default: AL_FALSE
- *
- * Specifies if the Source has relative coordinates.
- */
-#define AL_SOURCE_RELATIVE 0x202
-
-
-/**
- * Inner cone angle, in degrees.
- * Type: ALint, ALfloat
- * Range: [0 - 360]
- * Default: 360
- *
- * The angle covered by the inner cone, where the source will not attenuate.
- */
-#define AL_CONE_INNER_ANGLE 0x1001
-
-/**
- * Outer cone angle, in degrees.
- * Range: [0 - 360]
- * Default: 360
- *
- * The angle covered by the outer cone, where the source will be fully
- * attenuated.
- */
-#define AL_CONE_OUTER_ANGLE 0x1002
-
-/**
- * Source pitch.
- * Type: ALfloat
- * Range: [0.5 - 2.0]
- * Default: 1.0
- *
- * A multiplier for the frequency (sample rate) of the source's buffer.
- */
-#define AL_PITCH 0x1003
-
-/**
- * Source or listener position.
- * Type: ALfloat[3], ALint[3]
- * Default: {0, 0, 0}
- *
- * The source or listener location in three dimensional space.
- *
- * OpenAL, like OpenGL, uses a right handed coordinate system, where in a
- * frontal default view X (thumb) points right, Y points up (index finger), and
- * Z points towards the viewer/camera (middle finger).
- *
- * To switch from a left handed coordinate system, flip the sign on the Z
- * coordinate.
- */
-#define AL_POSITION 0x1004
-
-/**
- * Source direction.
- * Type: ALfloat[3], ALint[3]
- * Default: {0, 0, 0}
- *
- * Specifies the current direction in local space.
- * A zero-length vector specifies an omni-directional source (cone is ignored).
- */
-#define AL_DIRECTION 0x1005
-
-/**
- * Source or listener velocity.
- * Type: ALfloat[3], ALint[3]
- * Default: {0, 0, 0}
- *
- * Specifies the current velocity in local space.
- */
-#define AL_VELOCITY 0x1006
-
-/**
- * Source looping.
- * Type: ALboolean
- * Range: [AL_TRUE, AL_FALSE]
- * Default: AL_FALSE
- *
- * Specifies whether source is looping.
- */
-#define AL_LOOPING 0x1007
-
-/**
- * Source buffer.
- * Type: ALuint
- * Range: any valid Buffer.
- *
- * Specifies the buffer to provide sound samples.
- */
-#define AL_BUFFER 0x1009
-
-/**
- * Source or listener gain.
- * Type: ALfloat
- * Range: [0.0 - ]
- *
- * A value of 1.0 means unattenuated. Each division by 2 equals an attenuation
- * of about -6dB. Each multiplicaton by 2 equals an amplification of about
- * +6dB.
- *
- * A value of 0.0 is meaningless with respect to a logarithmic scale; it is
- * silent.
- */
-#define AL_GAIN 0x100A
-
-/**
- * Minimum source gain.
- * Type: ALfloat
- * Range: [0.0 - 1.0]
- *
- * The minimum gain allowed for a source, after distance and cone attenation is
- * applied (if applicable).
- */
-#define AL_MIN_GAIN 0x100D
-
-/**
- * Maximum source gain.
- * Type: ALfloat
- * Range: [0.0 - 1.0]
- *
- * The maximum gain allowed for a source, after distance and cone attenation is
- * applied (if applicable).
- */
-#define AL_MAX_GAIN 0x100E
-
-/**
- * Listener orientation.
- * Type: ALfloat[6]
- * Default: {0.0, 0.0, -1.0, 0.0, 1.0, 0.0}
- *
- * Effectively two three dimensional vectors. The first vector is the front (or
- * "at") and the second is the top (or "up").
- *
- * Both vectors are in local space.
- */
-#define AL_ORIENTATION 0x100F
-
-/**
- * Source state (query only).
- * Type: ALint
- * Range: [AL_INITIAL, AL_PLAYING, AL_PAUSED, AL_STOPPED]
- */
-#define AL_SOURCE_STATE 0x1010
-
-/** Source state value. */
-#define AL_INITIAL 0x1011
-#define AL_PLAYING 0x1012
-#define AL_PAUSED 0x1013
-#define AL_STOPPED 0x1014
-
-/**
- * Source Buffer Queue size (query only).
- * Type: ALint
- *
- * The number of buffers queued using alSourceQueueBuffers, minus the buffers
- * removed with alSourceUnqueueBuffers.
- */
-#define AL_BUFFERS_QUEUED 0x1015
-
-/**
- * Source Buffer Queue processed count (query only).
- * Type: ALint
- *
- * The number of queued buffers that have been fully processed, and can be
- * removed with alSourceUnqueueBuffers.
- *
- * Looping sources will never fully process buffers because they will be set to
- * play again for when the source loops.
- */
-#define AL_BUFFERS_PROCESSED 0x1016
-
-/**
- * Source reference distance.
- * Type: ALfloat
- * Range: [0.0 - ]
- * Default: 1.0
- *
- * The distance in units that no attenuation occurs.
- *
- * At 0.0, no distance attenuation ever occurs on non-linear attenuation models.
- */
-#define AL_REFERENCE_DISTANCE 0x1020
-
-/**
- * Source rolloff factor.
- * Type: ALfloat
- * Range: [0.0 - ]
- * Default: 1.0
- *
- * Multiplier to exaggerate or diminish distance attenuation.
- *
- * At 0.0, no distance attenuation ever occurs.
- */
-#define AL_ROLLOFF_FACTOR 0x1021
-
-/**
- * Outer cone gain.
- * Type: ALfloat
- * Range: [0.0 - 1.0]
- * Default: 0.0
- *
- * The gain attenuation applied when the listener is outside of the source's
- * outer cone.
- */
-#define AL_CONE_OUTER_GAIN 0x1022
-
-/**
- * Source maximum distance.
- * Type: ALfloat
- * Range: [0.0 - ]
- * Default: +inf
- *
- * The distance above which the source is not attenuated any further with a
- * clamped distance model, or where attenuation reaches 0.0 gain for linear
- * distance models with a default rolloff factor.
- */
-#define AL_MAX_DISTANCE 0x1023
-
-/** Source buffer position, in seconds */
-#define AL_SEC_OFFSET 0x1024
-/** Source buffer position, in sample frames */
-#define AL_SAMPLE_OFFSET 0x1025
-/** Source buffer position, in bytes */
-#define AL_BYTE_OFFSET 0x1026
-
-/**
- * Source type (query only).
- * Type: ALint
- * Range: [AL_STATIC, AL_STREAMING, AL_UNDETERMINED]
- *
- * A Source is Static if a Buffer has been attached using AL_BUFFER.
- *
- * A Source is Streaming if one or more Buffers have been attached using
- * alSourceQueueBuffers.
- *
- * A Source is Undetermined when it has the NULL buffer attached using
- * AL_BUFFER.
- */
-#define AL_SOURCE_TYPE 0x1027
-
-/** Source type value. */
-#define AL_STATIC 0x1028
-#define AL_STREAMING 0x1029
-#define AL_UNDETERMINED 0x1030
-
-/** Buffer format specifier. */
-#define AL_FORMAT_MONO8 0x1100
-#define AL_FORMAT_MONO16 0x1101
-#define AL_FORMAT_STEREO8 0x1102
-#define AL_FORMAT_STEREO16 0x1103
-
-/** Buffer frequency (query only). */
-#define AL_FREQUENCY 0x2001
-/** Buffer bits per sample (query only). */
-#define AL_BITS 0x2002
-/** Buffer channel count (query only). */
-#define AL_CHANNELS 0x2003
-/** Buffer data size (query only). */
-#define AL_SIZE 0x2004
-
-/**
- * Buffer state.
- *
- * Not for public use.
- */
-#define AL_UNUSED 0x2010
-#define AL_PENDING 0x2011
-#define AL_PROCESSED 0x2012
-
-
-/** No error. */
-#define AL_NO_ERROR 0
-
-/** Invalid name paramater passed to AL call. */
-#define AL_INVALID_NAME 0xA001
-
-/** Invalid enum parameter passed to AL call. */
-#define AL_INVALID_ENUM 0xA002
-
-/** Invalid value parameter passed to AL call. */
-#define AL_INVALID_VALUE 0xA003
-
-/** Illegal AL call. */
-#define AL_INVALID_OPERATION 0xA004
-
-/** Not enough memory. */
-#define AL_OUT_OF_MEMORY 0xA005
-
-
-/** Context string: Vendor ID. */
-#define AL_VENDOR 0xB001
-/** Context string: Version. */
-#define AL_VERSION 0xB002
-/** Context string: Renderer ID. */
-#define AL_RENDERER 0xB003
-/** Context string: Space-separated extension list. */
-#define AL_EXTENSIONS 0xB004
-
-
-/**
- * Doppler scale.
- * Type: ALfloat
- * Range: [0.0 - ]
- * Default: 1.0
- *
- * Scale for source and listener velocities.
- */
-#define AL_DOPPLER_FACTOR 0xC000
-AL_API void AL_APIENTRY alDopplerFactor(ALfloat value);
-
-/**
- * Doppler velocity (deprecated).
- *
- * A multiplier applied to the Speed of Sound.
- */
-#define AL_DOPPLER_VELOCITY 0xC001
-AL_API void AL_APIENTRY alDopplerVelocity(ALfloat value);
-
-/**
- * Speed of Sound, in units per second.
- * Type: ALfloat
- * Range: [0.0001 - ]
- * Default: 343.3
- *
- * The speed at which sound waves are assumed to travel, when calculating the
- * doppler effect.
- */
-#define AL_SPEED_OF_SOUND 0xC003
-AL_API void AL_APIENTRY alSpeedOfSound(ALfloat value);
-
-/**
- * Distance attenuation model.
- * Type: ALint
- * Range: [AL_NONE, AL_INVERSE_DISTANCE, AL_INVERSE_DISTANCE_CLAMPED,
- * AL_LINEAR_DISTANCE, AL_LINEAR_DISTANCE_CLAMPED,
- * AL_EXPONENT_DISTANCE, AL_EXPONENT_DISTANCE_CLAMPED]
- * Default: AL_INVERSE_DISTANCE_CLAMPED
- *
- * The model by which sources attenuate with distance.
- *
- * None - No distance attenuation.
- * Inverse - Doubling the distance halves the source gain.
- * Linear - Linear gain scaling between the reference and max distances.
- * Exponent - Exponential gain dropoff.
- *
- * Clamped variations work like the non-clamped counterparts, except the
- * distance calculated is clamped between the reference and max distances.
- */
-#define AL_DISTANCE_MODEL 0xD000
-AL_API void AL_APIENTRY alDistanceModel(ALenum distanceModel);
-
-/** Distance model value. */
-#define AL_INVERSE_DISTANCE 0xD001
-#define AL_INVERSE_DISTANCE_CLAMPED 0xD002
-#define AL_LINEAR_DISTANCE 0xD003
-#define AL_LINEAR_DISTANCE_CLAMPED 0xD004
-#define AL_EXPONENT_DISTANCE 0xD005
-#define AL_EXPONENT_DISTANCE_CLAMPED 0xD006
-
-/** Renderer State management. */
-AL_API void AL_APIENTRY alEnable(ALenum capability);
-AL_API void AL_APIENTRY alDisable(ALenum capability);
-AL_API ALboolean AL_APIENTRY alIsEnabled(ALenum capability);
-
-/** State retrieval. */
-AL_API const ALchar* AL_APIENTRY alGetString(ALenum param);
-AL_API void AL_APIENTRY alGetBooleanv(ALenum param, ALboolean *values);
-AL_API void AL_APIENTRY alGetIntegerv(ALenum param, ALint *values);
-AL_API void AL_APIENTRY alGetFloatv(ALenum param, ALfloat *values);
-AL_API void AL_APIENTRY alGetDoublev(ALenum param, ALdouble *values);
-AL_API ALboolean AL_APIENTRY alGetBoolean(ALenum param);
-AL_API ALint AL_APIENTRY alGetInteger(ALenum param);
-AL_API ALfloat AL_APIENTRY alGetFloat(ALenum param);
-AL_API ALdouble AL_APIENTRY alGetDouble(ALenum param);
-
-/**
- * Error retrieval.
- *
- * Obtain the first error generated in the AL context since the last check.
- */
-AL_API ALenum AL_APIENTRY alGetError(void);
-
-/**
- * Extension support.
- *
- * Query for the presence of an extension, and obtain any appropriate function
- * pointers and enum values.
- */
-AL_API ALboolean AL_APIENTRY alIsExtensionPresent(const ALchar *extname);
-AL_API void* AL_APIENTRY alGetProcAddress(const ALchar *fname);
-AL_API ALenum AL_APIENTRY alGetEnumValue(const ALchar *ename);
-
-
-/** Set Listener parameters */
-AL_API void AL_APIENTRY alListenerf(ALenum param, ALfloat value);
-AL_API void AL_APIENTRY alListener3f(ALenum param, ALfloat value1, ALfloat value2, ALfloat value3);
-AL_API void AL_APIENTRY alListenerfv(ALenum param, const ALfloat *values);
-AL_API void AL_APIENTRY alListeneri(ALenum param, ALint value);
-AL_API void AL_APIENTRY alListener3i(ALenum param, ALint value1, ALint value2, ALint value3);
-AL_API void AL_APIENTRY alListeneriv(ALenum param, const ALint *values);
-
-/** Get Listener parameters */
-AL_API void AL_APIENTRY alGetListenerf(ALenum param, ALfloat *value);
-AL_API void AL_APIENTRY alGetListener3f(ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3);
-AL_API void AL_APIENTRY alGetListenerfv(ALenum param, ALfloat *values);
-AL_API void AL_APIENTRY alGetListeneri(ALenum param, ALint *value);
-AL_API void AL_APIENTRY alGetListener3i(ALenum param, ALint *value1, ALint *value2, ALint *value3);
-AL_API void AL_APIENTRY alGetListeneriv(ALenum param, ALint *values);
-
-
-/** Create Source objects. */
-AL_API void AL_APIENTRY alGenSources(ALsizei n, ALuint *sources);
-/** Delete Source objects. */
-AL_API void AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources);
-/** Verify a handle is a valid Source. */
-AL_API ALboolean AL_APIENTRY alIsSource(ALuint source);
-
-/** Set Source parameters. */
-AL_API void AL_APIENTRY alSourcef(ALuint source, ALenum param, ALfloat value);
-AL_API void AL_APIENTRY alSource3f(ALuint source, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3);
-AL_API void AL_APIENTRY alSourcefv(ALuint source, ALenum param, const ALfloat *values);
-AL_API void AL_APIENTRY alSourcei(ALuint source, ALenum param, ALint value);
-AL_API void AL_APIENTRY alSource3i(ALuint source, ALenum param, ALint value1, ALint value2, ALint value3);
-AL_API void AL_APIENTRY alSourceiv(ALuint source, ALenum param, const ALint *values);
-
-/** Get Source parameters. */
-AL_API void AL_APIENTRY alGetSourcef(ALuint source, ALenum param, ALfloat *value);
-AL_API void AL_APIENTRY alGetSource3f(ALuint source, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3);
-AL_API void AL_APIENTRY alGetSourcefv(ALuint source, ALenum param, ALfloat *values);
-AL_API void AL_APIENTRY alGetSourcei(ALuint source, ALenum param, ALint *value);
-AL_API void AL_APIENTRY alGetSource3i(ALuint source, ALenum param, ALint *value1, ALint *value2, ALint *value3);
-AL_API void AL_APIENTRY alGetSourceiv(ALuint source, ALenum param, ALint *values);
-
-
-/** Play, replay, or resume (if paused) a list of Sources */
-AL_API void AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources);
-/** Stop a list of Sources */
-AL_API void AL_APIENTRY alSourceStopv(ALsizei n, const ALuint *sources);
-/** Rewind a list of Sources */
-AL_API void AL_APIENTRY alSourceRewindv(ALsizei n, const ALuint *sources);
-/** Pause a list of Sources */
-AL_API void AL_APIENTRY alSourcePausev(ALsizei n, const ALuint *sources);
-
-/** Play, replay, or resume a Source */
-AL_API void AL_APIENTRY alSourcePlay(ALuint source);
-/** Stop a Source */
-AL_API void AL_APIENTRY alSourceStop(ALuint source);
-/** Rewind a Source (set playback postiton to beginning) */
-AL_API void AL_APIENTRY alSourceRewind(ALuint source);
-/** Pause a Source */
-AL_API void AL_APIENTRY alSourcePause(ALuint source);
-
-/** Queue buffers onto a source */
-AL_API void AL_APIENTRY alSourceQueueBuffers(ALuint source, ALsizei nb, const ALuint *buffers);
-/** Unqueue processed buffers from a source */
-AL_API void AL_APIENTRY alSourceUnqueueBuffers(ALuint source, ALsizei nb, ALuint *buffers);
-
-
-/** Create Buffer objects */
-AL_API void AL_APIENTRY alGenBuffers(ALsizei n, ALuint *buffers);
-/** Delete Buffer objects */
-AL_API void AL_APIENTRY alDeleteBuffers(ALsizei n, const ALuint *buffers);
-/** Verify a handle is a valid Buffer */
-AL_API ALboolean AL_APIENTRY alIsBuffer(ALuint buffer);
-
-/** Specifies the data to be copied into a buffer */
-AL_API void AL_APIENTRY alBufferData(ALuint buffer, ALenum format, const ALvoid *data, ALsizei size, ALsizei freq);
-
-/** Set Buffer parameters, */
-AL_API void AL_APIENTRY alBufferf(ALuint buffer, ALenum param, ALfloat value);
-AL_API void AL_APIENTRY alBuffer3f(ALuint buffer, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3);
-AL_API void AL_APIENTRY alBufferfv(ALuint buffer, ALenum param, const ALfloat *values);
-AL_API void AL_APIENTRY alBufferi(ALuint buffer, ALenum param, ALint value);
-AL_API void AL_APIENTRY alBuffer3i(ALuint buffer, ALenum param, ALint value1, ALint value2, ALint value3);
-AL_API void AL_APIENTRY alBufferiv(ALuint buffer, ALenum param, const ALint *values);
-
-/** Get Buffer parameters. */
-AL_API void AL_APIENTRY alGetBufferf(ALuint buffer, ALenum param, ALfloat *value);
-AL_API void AL_APIENTRY alGetBuffer3f(ALuint buffer, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3);
-AL_API void AL_APIENTRY alGetBufferfv(ALuint buffer, ALenum param, ALfloat *values);
-AL_API void AL_APIENTRY alGetBufferi(ALuint buffer, ALenum param, ALint *value);
-AL_API void AL_APIENTRY alGetBuffer3i(ALuint buffer, ALenum param, ALint *value1, ALint *value2, ALint *value3);
-AL_API void AL_APIENTRY alGetBufferiv(ALuint buffer, ALenum param, ALint *values);
-
-/** Pointer-to-function type, useful for dynamically getting AL entry points. */
-typedef void (AL_APIENTRY *LPALENABLE)(ALenum capability);
-typedef void (AL_APIENTRY *LPALDISABLE)(ALenum capability);
-typedef ALboolean (AL_APIENTRY *LPALISENABLED)(ALenum capability);
-typedef const ALchar* (AL_APIENTRY *LPALGETSTRING)(ALenum param);
-typedef void (AL_APIENTRY *LPALGETBOOLEANV)(ALenum param, ALboolean *values);
-typedef void (AL_APIENTRY *LPALGETINTEGERV)(ALenum param, ALint *values);
-typedef void (AL_APIENTRY *LPALGETFLOATV)(ALenum param, ALfloat *values);
-typedef void (AL_APIENTRY *LPALGETDOUBLEV)(ALenum param, ALdouble *values);
-typedef ALboolean (AL_APIENTRY *LPALGETBOOLEAN)(ALenum param);
-typedef ALint (AL_APIENTRY *LPALGETINTEGER)(ALenum param);
-typedef ALfloat (AL_APIENTRY *LPALGETFLOAT)(ALenum param);
-typedef ALdouble (AL_APIENTRY *LPALGETDOUBLE)(ALenum param);
-typedef ALenum (AL_APIENTRY *LPALGETERROR)(void);
-typedef ALboolean (AL_APIENTRY *LPALISEXTENSIONPRESENT)(const ALchar *extname);
-typedef void* (AL_APIENTRY *LPALGETPROCADDRESS)(const ALchar *fname);
-typedef ALenum (AL_APIENTRY *LPALGETENUMVALUE)(const ALchar *ename);
-typedef void (AL_APIENTRY *LPALLISTENERF)(ALenum param, ALfloat value);
-typedef void (AL_APIENTRY *LPALLISTENER3F)(ALenum param, ALfloat value1, ALfloat value2, ALfloat value3);
-typedef void (AL_APIENTRY *LPALLISTENERFV)(ALenum param, const ALfloat *values);
-typedef void (AL_APIENTRY *LPALLISTENERI)(ALenum param, ALint value);
-typedef void (AL_APIENTRY *LPALLISTENER3I)(ALenum param, ALint value1, ALint value2, ALint value3);
-typedef void (AL_APIENTRY *LPALLISTENERIV)(ALenum param, const ALint *values);
-typedef void (AL_APIENTRY *LPALGETLISTENERF)(ALenum param, ALfloat *value);
-typedef void (AL_APIENTRY *LPALGETLISTENER3F)(ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3);
-typedef void (AL_APIENTRY *LPALGETLISTENERFV)(ALenum param, ALfloat *values);
-typedef void (AL_APIENTRY *LPALGETLISTENERI)(ALenum param, ALint *value);
-typedef void (AL_APIENTRY *LPALGETLISTENER3I)(ALenum param, ALint *value1, ALint *value2, ALint *value3);
-typedef void (AL_APIENTRY *LPALGETLISTENERIV)(ALenum param, ALint *values);
-typedef void (AL_APIENTRY *LPALGENSOURCES)(ALsizei n, ALuint *sources);
-typedef void (AL_APIENTRY *LPALDELETESOURCES)(ALsizei n, const ALuint *sources);
-typedef ALboolean (AL_APIENTRY *LPALISSOURCE)(ALuint source);
-typedef void (AL_APIENTRY *LPALSOURCEF)(ALuint source, ALenum param, ALfloat value);
-typedef void (AL_APIENTRY *LPALSOURCE3F)(ALuint source, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3);
-typedef void (AL_APIENTRY *LPALSOURCEFV)(ALuint source, ALenum param, const ALfloat *values);
-typedef void (AL_APIENTRY *LPALSOURCEI)(ALuint source, ALenum param, ALint value);
-typedef void (AL_APIENTRY *LPALSOURCE3I)(ALuint source, ALenum param, ALint value1, ALint value2, ALint value3);
-typedef void (AL_APIENTRY *LPALSOURCEIV)(ALuint source, ALenum param, const ALint *values);
-typedef void (AL_APIENTRY *LPALGETSOURCEF)(ALuint source, ALenum param, ALfloat *value);
-typedef void (AL_APIENTRY *LPALGETSOURCE3F)(ALuint source, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3);
-typedef void (AL_APIENTRY *LPALGETSOURCEFV)(ALuint source, ALenum param, ALfloat *values);
-typedef void (AL_APIENTRY *LPALGETSOURCEI)(ALuint source, ALenum param, ALint *value);
-typedef void (AL_APIENTRY *LPALGETSOURCE3I)(ALuint source, ALenum param, ALint *value1, ALint *value2, ALint *value3);
-typedef void (AL_APIENTRY *LPALGETSOURCEIV)(ALuint source, ALenum param, ALint *values);
-typedef void (AL_APIENTRY *LPALSOURCEPLAYV)(ALsizei n, const ALuint *sources);
-typedef void (AL_APIENTRY *LPALSOURCESTOPV)(ALsizei n, const ALuint *sources);
-typedef void (AL_APIENTRY *LPALSOURCEREWINDV)(ALsizei n, const ALuint *sources);
-typedef void (AL_APIENTRY *LPALSOURCEPAUSEV)(ALsizei n, const ALuint *sources);
-typedef void (AL_APIENTRY *LPALSOURCEPLAY)(ALuint source);
-typedef void (AL_APIENTRY *LPALSOURCESTOP)(ALuint source);
-typedef void (AL_APIENTRY *LPALSOURCEREWIND)(ALuint source);
-typedef void (AL_APIENTRY *LPALSOURCEPAUSE)(ALuint source);
-typedef void (AL_APIENTRY *LPALSOURCEQUEUEBUFFERS)(ALuint source, ALsizei nb, const ALuint *buffers);
-typedef void (AL_APIENTRY *LPALSOURCEUNQUEUEBUFFERS)(ALuint source, ALsizei nb, ALuint *buffers);
-typedef void (AL_APIENTRY *LPALGENBUFFERS)(ALsizei n, ALuint *buffers);
-typedef void (AL_APIENTRY *LPALDELETEBUFFERS)(ALsizei n, const ALuint *buffers);
-typedef ALboolean (AL_APIENTRY *LPALISBUFFER)(ALuint buffer);
-typedef void (AL_APIENTRY *LPALBUFFERDATA)(ALuint buffer, ALenum format, const ALvoid *data, ALsizei size, ALsizei freq);
-typedef void (AL_APIENTRY *LPALBUFFERF)(ALuint buffer, ALenum param, ALfloat value);
-typedef void (AL_APIENTRY *LPALBUFFER3F)(ALuint buffer, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3);
-typedef void (AL_APIENTRY *LPALBUFFERFV)(ALuint buffer, ALenum param, const ALfloat *values);
-typedef void (AL_APIENTRY *LPALBUFFERI)(ALuint buffer, ALenum param, ALint value);
-typedef void (AL_APIENTRY *LPALBUFFER3I)(ALuint buffer, ALenum param, ALint value1, ALint value2, ALint value3);
-typedef void (AL_APIENTRY *LPALBUFFERIV)(ALuint buffer, ALenum param, const ALint *values);
-typedef void (AL_APIENTRY *LPALGETBUFFERF)(ALuint buffer, ALenum param, ALfloat *value);
-typedef void (AL_APIENTRY *LPALGETBUFFER3F)(ALuint buffer, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3);
-typedef void (AL_APIENTRY *LPALGETBUFFERFV)(ALuint buffer, ALenum param, ALfloat *values);
-typedef void (AL_APIENTRY *LPALGETBUFFERI)(ALuint buffer, ALenum param, ALint *value);
-typedef void (AL_APIENTRY *LPALGETBUFFER3I)(ALuint buffer, ALenum param, ALint *value1, ALint *value2, ALint *value3);
-typedef void (AL_APIENTRY *LPALGETBUFFERIV)(ALuint buffer, ALenum param, ALint *values);
-typedef void (AL_APIENTRY *LPALDOPPLERFACTOR)(ALfloat value);
-typedef void (AL_APIENTRY *LPALDOPPLERVELOCITY)(ALfloat value);
-typedef void (AL_APIENTRY *LPALSPEEDOFSOUND)(ALfloat value);
-typedef void (AL_APIENTRY *LPALDISTANCEMODEL)(ALenum distanceModel);
-
-#if defined(__cplusplus)
-} /* extern "C" */
-#endif
-
-#endif /* AL_AL_H */
diff --git a/project/vs2015/external/openal_soft/include/AL/alc.h b/project/vs2015/external/openal_soft/include/AL/alc.h
deleted file mode 100644
index 294e8b33c..000000000
--- a/project/vs2015/external/openal_soft/include/AL/alc.h
+++ /dev/null
@@ -1,237 +0,0 @@
-#ifndef AL_ALC_H
-#define AL_ALC_H
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-#ifndef ALC_API
- #if defined(AL_LIBTYPE_STATIC)
- #define ALC_API
- #elif defined(_WIN32)
- #define ALC_API __declspec(dllimport)
- #else
- #define ALC_API extern
- #endif
-#endif
-
-#if defined(_WIN32)
- #define ALC_APIENTRY __cdecl
-#else
- #define ALC_APIENTRY
-#endif
-
-
-/** Deprecated macro. */
-#define ALCAPI ALC_API
-#define ALCAPIENTRY ALC_APIENTRY
-#define ALC_INVALID 0
-
-/** Supported ALC version? */
-#define ALC_VERSION_0_1 1
-
-/** Opaque device handle */
-typedef struct ALCdevice_struct ALCdevice;
-/** Opaque context handle */
-typedef struct ALCcontext_struct ALCcontext;
-
-/** 8-bit boolean */
-typedef char ALCboolean;
-
-/** character */
-typedef char ALCchar;
-
-/** signed 8-bit 2's complement integer */
-typedef signed char ALCbyte;
-
-/** unsigned 8-bit integer */
-typedef unsigned char ALCubyte;
-
-/** signed 16-bit 2's complement integer */
-typedef short ALCshort;
-
-/** unsigned 16-bit integer */
-typedef unsigned short ALCushort;
-
-/** signed 32-bit 2's complement integer */
-typedef int ALCint;
-
-/** unsigned 32-bit integer */
-typedef unsigned int ALCuint;
-
-/** non-negative 32-bit binary integer size */
-typedef int ALCsizei;
-
-/** enumerated 32-bit value */
-typedef int ALCenum;
-
-/** 32-bit IEEE754 floating-point */
-typedef float ALCfloat;
-
-/** 64-bit IEEE754 floating-point */
-typedef double ALCdouble;
-
-/** void type (for opaque pointers only) */
-typedef void ALCvoid;
-
-
-/* Enumerant values begin at column 50. No tabs. */
-
-/** Boolean False. */
-#define ALC_FALSE 0
-
-/** Boolean True. */
-#define ALC_TRUE 1
-
-/** Context attribute: Hz. */
-#define ALC_FREQUENCY 0x1007
-
-/** Context attribute: Hz. */
-#define ALC_REFRESH 0x1008
-
-/** Context attribute: AL_TRUE or AL_FALSE. */
-#define ALC_SYNC 0x1009
-
-/** Context attribute: requested Mono (3D) Sources. */
-#define ALC_MONO_SOURCES 0x1010
-
-/** Context attribute: requested Stereo Sources. */
-#define ALC_STEREO_SOURCES 0x1011
-
-/** No error. */
-#define ALC_NO_ERROR 0
-
-/** Invalid device handle. */
-#define ALC_INVALID_DEVICE 0xA001
-
-/** Invalid context handle. */
-#define ALC_INVALID_CONTEXT 0xA002
-
-/** Invalid enum parameter passed to an ALC call. */
-#define ALC_INVALID_ENUM 0xA003
-
-/** Invalid value parameter passed to an ALC call. */
-#define ALC_INVALID_VALUE 0xA004
-
-/** Out of memory. */
-#define ALC_OUT_OF_MEMORY 0xA005
-
-
-/** Runtime ALC version. */
-#define ALC_MAJOR_VERSION 0x1000
-#define ALC_MINOR_VERSION 0x1001
-
-/** Context attribute list properties. */
-#define ALC_ATTRIBUTES_SIZE 0x1002
-#define ALC_ALL_ATTRIBUTES 0x1003
-
-/** String for the default device specifier. */
-#define ALC_DEFAULT_DEVICE_SPECIFIER 0x1004
-/**
- * String for the given device's specifier.
- *
- * If device handle is NULL, it is instead a null-char separated list of
- * strings of known device specifiers (list ends with an empty string).
- */
-#define ALC_DEVICE_SPECIFIER 0x1005
-/** String for space-separated list of ALC extensions. */
-#define ALC_EXTENSIONS 0x1006
-
-
-/** Capture extension */
-#define ALC_EXT_CAPTURE 1
-/**
- * String for the given capture device's specifier.
- *
- * If device handle is NULL, it is instead a null-char separated list of
- * strings of known capture device specifiers (list ends with an empty string).
- */
-#define ALC_CAPTURE_DEVICE_SPECIFIER 0x310
-/** String for the default capture device specifier. */
-#define ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER 0x311
-/** Number of sample frames available for capture. */
-#define ALC_CAPTURE_SAMPLES 0x312
-
-
-/** Enumerate All extension */
-#define ALC_ENUMERATE_ALL_EXT 1
-/** String for the default extended device specifier. */
-#define ALC_DEFAULT_ALL_DEVICES_SPECIFIER 0x1012
-/**
- * String for the given extended device's specifier.
- *
- * If device handle is NULL, it is instead a null-char separated list of
- * strings of known extended device specifiers (list ends with an empty string).
- */
-#define ALC_ALL_DEVICES_SPECIFIER 0x1013
-
-
-/** Context management. */
-ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint* attrlist);
-ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context);
-ALC_API void ALC_APIENTRY alcProcessContext(ALCcontext *context);
-ALC_API void ALC_APIENTRY alcSuspendContext(ALCcontext *context);
-ALC_API void ALC_APIENTRY alcDestroyContext(ALCcontext *context);
-ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void);
-ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *context);
-
-/** Device management. */
-ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *devicename);
-ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device);
-
-
-/**
- * Error support.
- *
- * Obtain the most recent Device error.
- */
-ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device);
-
-/**
- * Extension support.
- *
- * Query for the presence of an extension, and obtain any appropriate
- * function pointers and enum values.
- */
-ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extname);
-ALC_API void* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcname);
-ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumname);
-
-/** Query function. */
-ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *device, ALCenum param);
-ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values);
-
-/** Capture function. */
-ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize);
-ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device);
-ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device);
-ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device);
-ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples);
-
-/** Pointer-to-function type, useful for dynamically getting ALC entry points. */
-typedef ALCcontext* (ALC_APIENTRY *LPALCCREATECONTEXT)(ALCdevice *device, const ALCint *attrlist);
-typedef ALCboolean (ALC_APIENTRY *LPALCMAKECONTEXTCURRENT)(ALCcontext *context);
-typedef void (ALC_APIENTRY *LPALCPROCESSCONTEXT)(ALCcontext *context);
-typedef void (ALC_APIENTRY *LPALCSUSPENDCONTEXT)(ALCcontext *context);
-typedef void (ALC_APIENTRY *LPALCDESTROYCONTEXT)(ALCcontext *context);
-typedef ALCcontext* (ALC_APIENTRY *LPALCGETCURRENTCONTEXT)(void);
-typedef ALCdevice* (ALC_APIENTRY *LPALCGETCONTEXTSDEVICE)(ALCcontext *context);
-typedef ALCdevice* (ALC_APIENTRY *LPALCOPENDEVICE)(const ALCchar *devicename);
-typedef ALCboolean (ALC_APIENTRY *LPALCCLOSEDEVICE)(ALCdevice *device);
-typedef ALCenum (ALC_APIENTRY *LPALCGETERROR)(ALCdevice *device);
-typedef ALCboolean (ALC_APIENTRY *LPALCISEXTENSIONPRESENT)(ALCdevice *device, const ALCchar *extname);
-typedef void* (ALC_APIENTRY *LPALCGETPROCADDRESS)(ALCdevice *device, const ALCchar *funcname);
-typedef ALCenum (ALC_APIENTRY *LPALCGETENUMVALUE)(ALCdevice *device, const ALCchar *enumname);
-typedef const ALCchar* (ALC_APIENTRY *LPALCGETSTRING)(ALCdevice *device, ALCenum param);
-typedef void (ALC_APIENTRY *LPALCGETINTEGERV)(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values);
-typedef ALCdevice* (ALC_APIENTRY *LPALCCAPTUREOPENDEVICE)(const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize);
-typedef ALCboolean (ALC_APIENTRY *LPALCCAPTURECLOSEDEVICE)(ALCdevice *device);
-typedef void (ALC_APIENTRY *LPALCCAPTURESTART)(ALCdevice *device);
-typedef void (ALC_APIENTRY *LPALCCAPTURESTOP)(ALCdevice *device);
-typedef void (ALC_APIENTRY *LPALCCAPTURESAMPLES)(ALCdevice *device, ALCvoid *buffer, ALCsizei samples);
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* AL_ALC_H */
diff --git a/project/vs2015/external/openal_soft/include/AL/alext.h b/project/vs2015/external/openal_soft/include/AL/alext.h
deleted file mode 100644
index 6af581aad..000000000
--- a/project/vs2015/external/openal_soft/include/AL/alext.h
+++ /dev/null
@@ -1,438 +0,0 @@
-/**
- * OpenAL cross platform audio library
- * Copyright (C) 2008 by authors.
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- * Or go to http://www.gnu.org/copyleft/lgpl.html
- */
-
-#ifndef AL_ALEXT_H
-#define AL_ALEXT_H
-
-#include
-/* Define int64_t and uint64_t types */
-#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-#include
-#elif defined(_WIN32) && defined(__GNUC__)
-#include
-#elif defined(_WIN32)
-typedef __int64 int64_t;
-typedef unsigned __int64 uint64_t;
-#else
-/* Fallback if nothing above works */
-#include
-#endif
-
-#include "alc.h"
-#include "al.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef AL_LOKI_IMA_ADPCM_format
-#define AL_LOKI_IMA_ADPCM_format 1
-#define AL_FORMAT_IMA_ADPCM_MONO16_EXT 0x10000
-#define AL_FORMAT_IMA_ADPCM_STEREO16_EXT 0x10001
-#endif
-
-#ifndef AL_LOKI_WAVE_format
-#define AL_LOKI_WAVE_format 1
-#define AL_FORMAT_WAVE_EXT 0x10002
-#endif
-
-#ifndef AL_EXT_vorbis
-#define AL_EXT_vorbis 1
-#define AL_FORMAT_VORBIS_EXT 0x10003
-#endif
-
-#ifndef AL_LOKI_quadriphonic
-#define AL_LOKI_quadriphonic 1
-#define AL_FORMAT_QUAD8_LOKI 0x10004
-#define AL_FORMAT_QUAD16_LOKI 0x10005
-#endif
-
-#ifndef AL_EXT_float32
-#define AL_EXT_float32 1
-#define AL_FORMAT_MONO_FLOAT32 0x10010
-#define AL_FORMAT_STEREO_FLOAT32 0x10011
-#endif
-
-#ifndef AL_EXT_double
-#define AL_EXT_double 1
-#define AL_FORMAT_MONO_DOUBLE_EXT 0x10012
-#define AL_FORMAT_STEREO_DOUBLE_EXT 0x10013
-#endif
-
-#ifndef AL_EXT_MULAW
-#define AL_EXT_MULAW 1
-#define AL_FORMAT_MONO_MULAW_EXT 0x10014
-#define AL_FORMAT_STEREO_MULAW_EXT 0x10015
-#endif
-
-#ifndef AL_EXT_ALAW
-#define AL_EXT_ALAW 1
-#define AL_FORMAT_MONO_ALAW_EXT 0x10016
-#define AL_FORMAT_STEREO_ALAW_EXT 0x10017
-#endif
-
-#ifndef ALC_LOKI_audio_channel
-#define ALC_LOKI_audio_channel 1
-#define ALC_CHAN_MAIN_LOKI 0x500001
-#define ALC_CHAN_PCM_LOKI 0x500002
-#define ALC_CHAN_CD_LOKI 0x500003
-#endif
-
-#ifndef AL_EXT_MCFORMATS
-#define AL_EXT_MCFORMATS 1
-#define AL_FORMAT_QUAD8 0x1204
-#define AL_FORMAT_QUAD16 0x1205
-#define AL_FORMAT_QUAD32 0x1206
-#define AL_FORMAT_REAR8 0x1207
-#define AL_FORMAT_REAR16 0x1208
-#define AL_FORMAT_REAR32 0x1209
-#define AL_FORMAT_51CHN8 0x120A
-#define AL_FORMAT_51CHN16 0x120B
-#define AL_FORMAT_51CHN32 0x120C
-#define AL_FORMAT_61CHN8 0x120D
-#define AL_FORMAT_61CHN16 0x120E
-#define AL_FORMAT_61CHN32 0x120F
-#define AL_FORMAT_71CHN8 0x1210
-#define AL_FORMAT_71CHN16 0x1211
-#define AL_FORMAT_71CHN32 0x1212
-#endif
-
-#ifndef AL_EXT_MULAW_MCFORMATS
-#define AL_EXT_MULAW_MCFORMATS 1
-#define AL_FORMAT_MONO_MULAW 0x10014
-#define AL_FORMAT_STEREO_MULAW 0x10015
-#define AL_FORMAT_QUAD_MULAW 0x10021
-#define AL_FORMAT_REAR_MULAW 0x10022
-#define AL_FORMAT_51CHN_MULAW 0x10023
-#define AL_FORMAT_61CHN_MULAW 0x10024
-#define AL_FORMAT_71CHN_MULAW 0x10025
-#endif
-
-#ifndef AL_EXT_IMA4
-#define AL_EXT_IMA4 1
-#define AL_FORMAT_MONO_IMA4 0x1300
-#define AL_FORMAT_STEREO_IMA4 0x1301
-#endif
-
-#ifndef AL_EXT_STATIC_BUFFER
-#define AL_EXT_STATIC_BUFFER 1
-typedef ALvoid (AL_APIENTRY*PFNALBUFFERDATASTATICPROC)(const ALint,ALenum,ALvoid*,ALsizei,ALsizei);
-#ifdef AL_ALEXT_PROTOTYPES
-AL_API ALvoid AL_APIENTRY alBufferDataStatic(const ALint buffer, ALenum format, ALvoid *data, ALsizei len, ALsizei freq);
-#endif
-#endif
-
-#ifndef ALC_EXT_EFX
-#define ALC_EXT_EFX 1
-#include "efx.h"
-#endif
-
-#ifndef ALC_EXT_disconnect
-#define ALC_EXT_disconnect 1
-#define ALC_CONNECTED 0x313
-#endif
-
-#ifndef ALC_EXT_thread_local_context
-#define ALC_EXT_thread_local_context 1
-typedef ALCboolean (ALC_APIENTRY*PFNALCSETTHREADCONTEXTPROC)(ALCcontext *context);
-typedef ALCcontext* (ALC_APIENTRY*PFNALCGETTHREADCONTEXTPROC)(void);
-#ifdef AL_ALEXT_PROTOTYPES
-ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context);
-ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void);
-#endif
-#endif
-
-#ifndef AL_EXT_source_distance_model
-#define AL_EXT_source_distance_model 1
-#define AL_SOURCE_DISTANCE_MODEL 0x200
-#endif
-
-#ifndef AL_SOFT_buffer_sub_data
-#define AL_SOFT_buffer_sub_data 1
-#define AL_BYTE_RW_OFFSETS_SOFT 0x1031
-#define AL_SAMPLE_RW_OFFSETS_SOFT 0x1032
-typedef ALvoid (AL_APIENTRY*PFNALBUFFERSUBDATASOFTPROC)(ALuint,ALenum,const ALvoid*,ALsizei,ALsizei);
-#ifdef AL_ALEXT_PROTOTYPES
-AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer,ALenum format,const ALvoid *data,ALsizei offset,ALsizei length);
-#endif
-#endif
-
-#ifndef AL_SOFT_loop_points
-#define AL_SOFT_loop_points 1
-#define AL_LOOP_POINTS_SOFT 0x2015
-#endif
-
-#ifndef AL_EXT_FOLDBACK
-#define AL_EXT_FOLDBACK 1
-#define AL_EXT_FOLDBACK_NAME "AL_EXT_FOLDBACK"
-#define AL_FOLDBACK_EVENT_BLOCK 0x4112
-#define AL_FOLDBACK_EVENT_START 0x4111
-#define AL_FOLDBACK_EVENT_STOP 0x4113
-#define AL_FOLDBACK_MODE_MONO 0x4101
-#define AL_FOLDBACK_MODE_STEREO 0x4102
-typedef void (AL_APIENTRY*LPALFOLDBACKCALLBACK)(ALenum,ALsizei);
-typedef void (AL_APIENTRY*LPALREQUESTFOLDBACKSTART)(ALenum,ALsizei,ALsizei,ALfloat*,LPALFOLDBACKCALLBACK);
-typedef void (AL_APIENTRY*LPALREQUESTFOLDBACKSTOP)(void);
-#ifdef AL_ALEXT_PROTOTYPES
-AL_API void AL_APIENTRY alRequestFoldbackStart(ALenum mode,ALsizei count,ALsizei length,ALfloat *mem,LPALFOLDBACKCALLBACK callback);
-AL_API void AL_APIENTRY alRequestFoldbackStop(void);
-#endif
-#endif
-
-#ifndef ALC_EXT_DEDICATED
-#define ALC_EXT_DEDICATED 1
-#define AL_DEDICATED_GAIN 0x0001
-#define AL_EFFECT_DEDICATED_DIALOGUE 0x9001
-#define AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT 0x9000
-#endif
-
-#ifndef AL_SOFT_buffer_samples
-#define AL_SOFT_buffer_samples 1
-/* Channel configurations */
-#define AL_MONO_SOFT 0x1500
-#define AL_STEREO_SOFT 0x1501
-#define AL_REAR_SOFT 0x1502
-#define AL_QUAD_SOFT 0x1503
-#define AL_5POINT1_SOFT 0x1504
-#define AL_6POINT1_SOFT 0x1505
-#define AL_7POINT1_SOFT 0x1506
-
-/* Sample types */
-#define AL_BYTE_SOFT 0x1400
-#define AL_UNSIGNED_BYTE_SOFT 0x1401
-#define AL_SHORT_SOFT 0x1402
-#define AL_UNSIGNED_SHORT_SOFT 0x1403
-#define AL_INT_SOFT 0x1404
-#define AL_UNSIGNED_INT_SOFT 0x1405
-#define AL_FLOAT_SOFT 0x1406
-#define AL_DOUBLE_SOFT 0x1407
-#define AL_BYTE3_SOFT 0x1408
-#define AL_UNSIGNED_BYTE3_SOFT 0x1409
-
-/* Storage formats */
-#define AL_MONO8_SOFT 0x1100
-#define AL_MONO16_SOFT 0x1101
-#define AL_MONO32F_SOFT 0x10010
-#define AL_STEREO8_SOFT 0x1102
-#define AL_STEREO16_SOFT 0x1103
-#define AL_STEREO32F_SOFT 0x10011
-#define AL_QUAD8_SOFT 0x1204
-#define AL_QUAD16_SOFT 0x1205
-#define AL_QUAD32F_SOFT 0x1206
-#define AL_REAR8_SOFT 0x1207
-#define AL_REAR16_SOFT 0x1208
-#define AL_REAR32F_SOFT 0x1209
-#define AL_5POINT1_8_SOFT 0x120A
-#define AL_5POINT1_16_SOFT 0x120B
-#define AL_5POINT1_32F_SOFT 0x120C
-#define AL_6POINT1_8_SOFT 0x120D
-#define AL_6POINT1_16_SOFT 0x120E
-#define AL_6POINT1_32F_SOFT 0x120F
-#define AL_7POINT1_8_SOFT 0x1210
-#define AL_7POINT1_16_SOFT 0x1211
-#define AL_7POINT1_32F_SOFT 0x1212
-
-/* Buffer attributes */
-#define AL_INTERNAL_FORMAT_SOFT 0x2008
-#define AL_BYTE_LENGTH_SOFT 0x2009
-#define AL_SAMPLE_LENGTH_SOFT 0x200A
-#define AL_SEC_LENGTH_SOFT 0x200B
-
-typedef void (AL_APIENTRY*LPALBUFFERSAMPLESSOFT)(ALuint,ALuint,ALenum,ALsizei,ALenum,ALenum,const ALvoid*);
-typedef void (AL_APIENTRY*LPALBUFFERSUBSAMPLESSOFT)(ALuint,ALsizei,ALsizei,ALenum,ALenum,const ALvoid*);
-typedef void (AL_APIENTRY*LPALGETBUFFERSAMPLESSOFT)(ALuint,ALsizei,ALsizei,ALenum,ALenum,ALvoid*);
-typedef ALboolean (AL_APIENTRY*LPALISBUFFERFORMATSUPPORTEDSOFT)(ALenum);
-#ifdef AL_ALEXT_PROTOTYPES
-AL_API void AL_APIENTRY alBufferSamplesSOFT(ALuint buffer, ALuint samplerate, ALenum internalformat, ALsizei samples, ALenum channels, ALenum type, const ALvoid *data);
-AL_API void AL_APIENTRY alBufferSubSamplesSOFT(ALuint buffer, ALsizei offset, ALsizei samples, ALenum channels, ALenum type, const ALvoid *data);
-AL_API void AL_APIENTRY alGetBufferSamplesSOFT(ALuint buffer, ALsizei offset, ALsizei samples, ALenum channels, ALenum type, ALvoid *data);
-AL_API ALboolean AL_APIENTRY alIsBufferFormatSupportedSOFT(ALenum format);
-#endif
-#endif
-
-#ifndef AL_SOFT_direct_channels
-#define AL_SOFT_direct_channels 1
-#define AL_DIRECT_CHANNELS_SOFT 0x1033
-#endif
-
-#ifndef ALC_SOFT_loopback
-#define ALC_SOFT_loopback 1
-#define ALC_FORMAT_CHANNELS_SOFT 0x1990
-#define ALC_FORMAT_TYPE_SOFT 0x1991
-
-/* Sample types */
-#define ALC_BYTE_SOFT 0x1400
-#define ALC_UNSIGNED_BYTE_SOFT 0x1401
-#define ALC_SHORT_SOFT 0x1402
-#define ALC_UNSIGNED_SHORT_SOFT 0x1403
-#define ALC_INT_SOFT 0x1404
-#define ALC_UNSIGNED_INT_SOFT 0x1405
-#define ALC_FLOAT_SOFT 0x1406
-
-/* Channel configurations */
-#define ALC_MONO_SOFT 0x1500
-#define ALC_STEREO_SOFT 0x1501
-#define ALC_QUAD_SOFT 0x1503
-#define ALC_5POINT1_SOFT 0x1504
-#define ALC_6POINT1_SOFT 0x1505
-#define ALC_7POINT1_SOFT 0x1506
-
-typedef ALCdevice* (ALC_APIENTRY*LPALCLOOPBACKOPENDEVICESOFT)(const ALCchar*);
-typedef ALCboolean (ALC_APIENTRY*LPALCISRENDERFORMATSUPPORTEDSOFT)(ALCdevice*,ALCsizei,ALCenum,ALCenum);
-typedef void (ALC_APIENTRY*LPALCRENDERSAMPLESSOFT)(ALCdevice*,ALCvoid*,ALCsizei);
-#ifdef AL_ALEXT_PROTOTYPES
-ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName);
-ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type);
-ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples);
-#endif
-#endif
-
-#ifndef AL_EXT_STEREO_ANGLES
-#define AL_EXT_STEREO_ANGLES 1
-#define AL_STEREO_ANGLES 0x1030
-#endif
-
-#ifndef AL_EXT_SOURCE_RADIUS
-#define AL_EXT_SOURCE_RADIUS 1
-#define AL_SOURCE_RADIUS 0x1031
-#endif
-
-#ifndef AL_SOFT_source_latency
-#define AL_SOFT_source_latency 1
-#define AL_SAMPLE_OFFSET_LATENCY_SOFT 0x1200
-#define AL_SEC_OFFSET_LATENCY_SOFT 0x1201
-typedef int64_t ALint64SOFT;
-typedef uint64_t ALuint64SOFT;
-typedef void (AL_APIENTRY*LPALSOURCEDSOFT)(ALuint,ALenum,ALdouble);
-typedef void (AL_APIENTRY*LPALSOURCE3DSOFT)(ALuint,ALenum,ALdouble,ALdouble,ALdouble);
-typedef void (AL_APIENTRY*LPALSOURCEDVSOFT)(ALuint,ALenum,const ALdouble*);
-typedef void (AL_APIENTRY*LPALGETSOURCEDSOFT)(ALuint,ALenum,ALdouble*);
-typedef void (AL_APIENTRY*LPALGETSOURCE3DSOFT)(ALuint,ALenum,ALdouble*,ALdouble*,ALdouble*);
-typedef void (AL_APIENTRY*LPALGETSOURCEDVSOFT)(ALuint,ALenum,ALdouble*);
-typedef void (AL_APIENTRY*LPALSOURCEI64SOFT)(ALuint,ALenum,ALint64SOFT);
-typedef void (AL_APIENTRY*LPALSOURCE3I64SOFT)(ALuint,ALenum,ALint64SOFT,ALint64SOFT,ALint64SOFT);
-typedef void (AL_APIENTRY*LPALSOURCEI64VSOFT)(ALuint,ALenum,const ALint64SOFT*);
-typedef void (AL_APIENTRY*LPALGETSOURCEI64SOFT)(ALuint,ALenum,ALint64SOFT*);
-typedef void (AL_APIENTRY*LPALGETSOURCE3I64SOFT)(ALuint,ALenum,ALint64SOFT*,ALint64SOFT*,ALint64SOFT*);
-typedef void (AL_APIENTRY*LPALGETSOURCEI64VSOFT)(ALuint,ALenum,ALint64SOFT*);
-#ifdef AL_ALEXT_PROTOTYPES
-AL_API void AL_APIENTRY alSourcedSOFT(ALuint source, ALenum param, ALdouble value);
-AL_API void AL_APIENTRY alSource3dSOFT(ALuint source, ALenum param, ALdouble value1, ALdouble value2, ALdouble value3);
-AL_API void AL_APIENTRY alSourcedvSOFT(ALuint source, ALenum param, const ALdouble *values);
-AL_API void AL_APIENTRY alGetSourcedSOFT(ALuint source, ALenum param, ALdouble *value);
-AL_API void AL_APIENTRY alGetSource3dSOFT(ALuint source, ALenum param, ALdouble *value1, ALdouble *value2, ALdouble *value3);
-AL_API void AL_APIENTRY alGetSourcedvSOFT(ALuint source, ALenum param, ALdouble *values);
-AL_API void AL_APIENTRY alSourcei64SOFT(ALuint source, ALenum param, ALint64SOFT value);
-AL_API void AL_APIENTRY alSource3i64SOFT(ALuint source, ALenum param, ALint64SOFT value1, ALint64SOFT value2, ALint64SOFT value3);
-AL_API void AL_APIENTRY alSourcei64vSOFT(ALuint source, ALenum param, const ALint64SOFT *values);
-AL_API void AL_APIENTRY alGetSourcei64SOFT(ALuint source, ALenum param, ALint64SOFT *value);
-AL_API void AL_APIENTRY alGetSource3i64SOFT(ALuint source, ALenum param, ALint64SOFT *value1, ALint64SOFT *value2, ALint64SOFT *value3);
-AL_API void AL_APIENTRY alGetSourcei64vSOFT(ALuint source, ALenum param, ALint64SOFT *values);
-#endif
-#endif
-
-#ifndef ALC_EXT_DEFAULT_FILTER_ORDER
-#define ALC_EXT_DEFAULT_FILTER_ORDER 1
-#define ALC_DEFAULT_FILTER_ORDER 0x1100
-#endif
-
-#ifndef AL_SOFT_deferred_updates
-#define AL_SOFT_deferred_updates 1
-#define AL_DEFERRED_UPDATES_SOFT 0xC002
-typedef ALvoid (AL_APIENTRY*LPALDEFERUPDATESSOFT)(void);
-typedef ALvoid (AL_APIENTRY*LPALPROCESSUPDATESSOFT)(void);
-#ifdef AL_ALEXT_PROTOTYPES
-AL_API ALvoid AL_APIENTRY alDeferUpdatesSOFT(void);
-AL_API ALvoid AL_APIENTRY alProcessUpdatesSOFT(void);
-#endif
-#endif
-
-#ifndef AL_SOFT_block_alignment
-#define AL_SOFT_block_alignment 1
-#define AL_UNPACK_BLOCK_ALIGNMENT_SOFT 0x200C
-#define AL_PACK_BLOCK_ALIGNMENT_SOFT 0x200D
-#endif
-
-#ifndef AL_SOFT_MSADPCM
-#define AL_SOFT_MSADPCM 1
-#define AL_FORMAT_MONO_MSADPCM_SOFT 0x1302
-#define AL_FORMAT_STEREO_MSADPCM_SOFT 0x1303
-#endif
-
-#ifndef AL_SOFT_source_length
-#define AL_SOFT_source_length 1
-/*#define AL_BYTE_LENGTH_SOFT 0x2009*/
-/*#define AL_SAMPLE_LENGTH_SOFT 0x200A*/
-/*#define AL_SEC_LENGTH_SOFT 0x200B*/
-#endif
-
-#ifndef ALC_SOFT_pause_device
-#define ALC_SOFT_pause_device 1
-typedef void (ALC_APIENTRY*LPALCDEVICEPAUSESOFT)(ALCdevice *device);
-typedef void (ALC_APIENTRY*LPALCDEVICERESUMESOFT)(ALCdevice *device);
-#ifdef AL_ALEXT_PROTOTYPES
-ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device);
-ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device);
-#endif
-#endif
-
-#ifndef AL_EXT_BFORMAT
-#define AL_EXT_BFORMAT 1
-#define AL_FORMAT_BFORMAT2D_8 0x20021
-#define AL_FORMAT_BFORMAT2D_16 0x20022
-#define AL_FORMAT_BFORMAT2D_FLOAT32 0x20023
-#define AL_FORMAT_BFORMAT3D_8 0x20031
-#define AL_FORMAT_BFORMAT3D_16 0x20032
-#define AL_FORMAT_BFORMAT3D_FLOAT32 0x20033
-#endif
-
-#ifndef AL_EXT_MULAW_BFORMAT
-#define AL_EXT_MULAW_BFORMAT 1
-#define AL_FORMAT_BFORMAT2D_MULAW 0x10031
-#define AL_FORMAT_BFORMAT3D_MULAW 0x10032
-#endif
-
-#ifndef ALC_SOFT_HRTF
-#define ALC_SOFT_HRTF 1
-#define ALC_HRTF_SOFT 0x1992
-#define ALC_DONT_CARE_SOFT 0x0002
-#define ALC_HRTF_STATUS_SOFT 0x1993
-#define ALC_HRTF_DISABLED_SOFT 0x0000
-#define ALC_HRTF_ENABLED_SOFT 0x0001
-#define ALC_HRTF_DENIED_SOFT 0x0002
-#define ALC_HRTF_REQUIRED_SOFT 0x0003
-#define ALC_HRTF_HEADPHONES_DETECTED_SOFT 0x0004
-#define ALC_HRTF_UNSUPPORTED_FORMAT_SOFT 0x0005
-#define ALC_NUM_HRTF_SPECIFIERS_SOFT 0x1994
-#define ALC_HRTF_SPECIFIER_SOFT 0x1995
-#define ALC_HRTF_ID_SOFT 0x1996
-typedef const ALCchar* (ALC_APIENTRY*LPALCGETSTRINGISOFT)(ALCdevice *device, ALCenum paramName, ALCsizei index);
-typedef ALCboolean (ALC_APIENTRY*LPALCRESETDEVICESOFT)(ALCdevice *device, const ALCint *attribs);
-#ifdef AL_ALEXT_PROTOTYPES
-ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum paramName, ALCsizei index);
-ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCint *attribs);
-#endif
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/project/vs2015/external/openal_soft/include/AL/efx-creative.h b/project/vs2015/external/openal_soft/include/AL/efx-creative.h
deleted file mode 100644
index 0a04c982e..000000000
--- a/project/vs2015/external/openal_soft/include/AL/efx-creative.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* The tokens that would be defined here are already defined in efx.h. This
- * empty file is here to provide compatibility with Windows-based projects
- * that would include it. */
diff --git a/project/vs2015/external/openal_soft/include/AL/efx-presets.h b/project/vs2015/external/openal_soft/include/AL/efx-presets.h
deleted file mode 100644
index 8539fd517..000000000
--- a/project/vs2015/external/openal_soft/include/AL/efx-presets.h
+++ /dev/null
@@ -1,402 +0,0 @@
-/* Reverb presets for EFX */
-
-#ifndef EFX_PRESETS_H
-#define EFX_PRESETS_H
-
-#ifndef EFXEAXREVERBPROPERTIES_DEFINED
-#define EFXEAXREVERBPROPERTIES_DEFINED
-typedef struct {
- float flDensity;
- float flDiffusion;
- float flGain;
- float flGainHF;
- float flGainLF;
- float flDecayTime;
- float flDecayHFRatio;
- float flDecayLFRatio;
- float flReflectionsGain;
- float flReflectionsDelay;
- float flReflectionsPan[3];
- float flLateReverbGain;
- float flLateReverbDelay;
- float flLateReverbPan[3];
- float flEchoTime;
- float flEchoDepth;
- float flModulationTime;
- float flModulationDepth;
- float flAirAbsorptionGainHF;
- float flHFReference;
- float flLFReference;
- float flRoomRolloffFactor;
- int iDecayHFLimit;
-} EFXEAXREVERBPROPERTIES, *LPEFXEAXREVERBPROPERTIES;
-#endif
-
-/* Default Presets */
-
-#define EFX_REVERB_PRESET_GENERIC \
- { 1.0000f, 1.0000f, 0.3162f, 0.8913f, 1.0000f, 1.4900f, 0.8300f, 1.0000f, 0.0500f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_PADDEDCELL \
- { 0.1715f, 1.0000f, 0.3162f, 0.0010f, 1.0000f, 0.1700f, 0.1000f, 1.0000f, 0.2500f, 0.0010f, { 0.0000f, 0.0000f, 0.0000f }, 1.2691f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_ROOM \
- { 0.4287f, 1.0000f, 0.3162f, 0.5929f, 1.0000f, 0.4000f, 0.8300f, 1.0000f, 0.1503f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 1.0629f, 0.0030f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_BATHROOM \
- { 0.1715f, 1.0000f, 0.3162f, 0.2512f, 1.0000f, 1.4900f, 0.5400f, 1.0000f, 0.6531f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 3.2734f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_LIVINGROOM \
- { 0.9766f, 1.0000f, 0.3162f, 0.0010f, 1.0000f, 0.5000f, 0.1000f, 1.0000f, 0.2051f, 0.0030f, { 0.0000f, 0.0000f, 0.0000f }, 0.2805f, 0.0040f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_STONEROOM \
- { 1.0000f, 1.0000f, 0.3162f, 0.7079f, 1.0000f, 2.3100f, 0.6400f, 1.0000f, 0.4411f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.1003f, 0.0170f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_AUDITORIUM \
- { 1.0000f, 1.0000f, 0.3162f, 0.5781f, 1.0000f, 4.3200f, 0.5900f, 1.0000f, 0.4032f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.7170f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_CONCERTHALL \
- { 1.0000f, 1.0000f, 0.3162f, 0.5623f, 1.0000f, 3.9200f, 0.7000f, 1.0000f, 0.2427f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.9977f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_CAVE \
- { 1.0000f, 1.0000f, 0.3162f, 1.0000f, 1.0000f, 2.9100f, 1.3000f, 1.0000f, 0.5000f, 0.0150f, { 0.0000f, 0.0000f, 0.0000f }, 0.7063f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_ARENA \
- { 1.0000f, 1.0000f, 0.3162f, 0.4477f, 1.0000f, 7.2400f, 0.3300f, 1.0000f, 0.2612f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.0186f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_HANGAR \
- { 1.0000f, 1.0000f, 0.3162f, 0.3162f, 1.0000f, 10.0500f, 0.2300f, 1.0000f, 0.5000f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.2560f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_CARPETEDHALLWAY \
- { 0.4287f, 1.0000f, 0.3162f, 0.0100f, 1.0000f, 0.3000f, 0.1000f, 1.0000f, 0.1215f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 0.1531f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_HALLWAY \
- { 0.3645f, 1.0000f, 0.3162f, 0.7079f, 1.0000f, 1.4900f, 0.5900f, 1.0000f, 0.2458f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.6615f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_STONECORRIDOR \
- { 1.0000f, 1.0000f, 0.3162f, 0.7612f, 1.0000f, 2.7000f, 0.7900f, 1.0000f, 0.2472f, 0.0130f, { 0.0000f, 0.0000f, 0.0000f }, 1.5758f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_ALLEY \
- { 1.0000f, 0.3000f, 0.3162f, 0.7328f, 1.0000f, 1.4900f, 0.8600f, 1.0000f, 0.2500f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.9954f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 0.9500f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_FOREST \
- { 1.0000f, 0.3000f, 0.3162f, 0.0224f, 1.0000f, 1.4900f, 0.5400f, 1.0000f, 0.0525f, 0.1620f, { 0.0000f, 0.0000f, 0.0000f }, 0.7682f, 0.0880f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_CITY \
- { 1.0000f, 0.5000f, 0.3162f, 0.3981f, 1.0000f, 1.4900f, 0.6700f, 1.0000f, 0.0730f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.1427f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_MOUNTAINS \
- { 1.0000f, 0.2700f, 0.3162f, 0.0562f, 1.0000f, 1.4900f, 0.2100f, 1.0000f, 0.0407f, 0.3000f, { 0.0000f, 0.0000f, 0.0000f }, 0.1919f, 0.1000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_QUARRY \
- { 1.0000f, 1.0000f, 0.3162f, 0.3162f, 1.0000f, 1.4900f, 0.8300f, 1.0000f, 0.0000f, 0.0610f, { 0.0000f, 0.0000f, 0.0000f }, 1.7783f, 0.0250f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 0.7000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_PLAIN \
- { 1.0000f, 0.2100f, 0.3162f, 0.1000f, 1.0000f, 1.4900f, 0.5000f, 1.0000f, 0.0585f, 0.1790f, { 0.0000f, 0.0000f, 0.0000f }, 0.1089f, 0.1000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_PARKINGLOT \
- { 1.0000f, 1.0000f, 0.3162f, 1.0000f, 1.0000f, 1.6500f, 1.5000f, 1.0000f, 0.2082f, 0.0080f, { 0.0000f, 0.0000f, 0.0000f }, 0.2652f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_SEWERPIPE \
- { 0.3071f, 0.8000f, 0.3162f, 0.3162f, 1.0000f, 2.8100f, 0.1400f, 1.0000f, 1.6387f, 0.0140f, { 0.0000f, 0.0000f, 0.0000f }, 3.2471f, 0.0210f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_UNDERWATER \
- { 0.3645f, 1.0000f, 0.3162f, 0.0100f, 1.0000f, 1.4900f, 0.1000f, 1.0000f, 0.5963f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 7.0795f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 1.1800f, 0.3480f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_DRUGGED \
- { 0.4287f, 0.5000f, 0.3162f, 1.0000f, 1.0000f, 8.3900f, 1.3900f, 1.0000f, 0.8760f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 3.1081f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 1.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_DIZZY \
- { 0.3645f, 0.6000f, 0.3162f, 0.6310f, 1.0000f, 17.2300f, 0.5600f, 1.0000f, 0.1392f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.4937f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.8100f, 0.3100f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_PSYCHOTIC \
- { 0.0625f, 0.5000f, 0.3162f, 0.8404f, 1.0000f, 7.5600f, 0.9100f, 1.0000f, 0.4864f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 2.4378f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 4.0000f, 1.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
-
-/* Castle Presets */
-
-#define EFX_REVERB_PRESET_CASTLE_SMALLROOM \
- { 1.0000f, 0.8900f, 0.3162f, 0.3981f, 0.1000f, 1.2200f, 0.8300f, 0.3100f, 0.8913f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 1.9953f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_CASTLE_SHORTPASSAGE \
- { 1.0000f, 0.8900f, 0.3162f, 0.3162f, 0.1000f, 2.3200f, 0.8300f, 0.3100f, 0.8913f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_CASTLE_MEDIUMROOM \
- { 1.0000f, 0.9300f, 0.3162f, 0.2818f, 0.1000f, 2.0400f, 0.8300f, 0.4600f, 0.6310f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 1.5849f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1550f, 0.0300f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_CASTLE_LARGEROOM \
- { 1.0000f, 0.8200f, 0.3162f, 0.2818f, 0.1259f, 2.5300f, 0.8300f, 0.5000f, 0.4467f, 0.0340f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.1850f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_CASTLE_LONGPASSAGE \
- { 1.0000f, 0.8900f, 0.3162f, 0.3981f, 0.1000f, 3.4200f, 0.8300f, 0.3100f, 0.8913f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_CASTLE_HALL \
- { 1.0000f, 0.8100f, 0.3162f, 0.2818f, 0.1778f, 3.1400f, 0.7900f, 0.6200f, 0.1778f, 0.0560f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_CASTLE_CUPBOARD \
- { 1.0000f, 0.8900f, 0.3162f, 0.2818f, 0.1000f, 0.6700f, 0.8700f, 0.3100f, 1.4125f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 3.5481f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_CASTLE_COURTYARD \
- { 1.0000f, 0.4200f, 0.3162f, 0.4467f, 0.1995f, 2.1300f, 0.6100f, 0.2300f, 0.2239f, 0.1600f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0360f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.3700f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_CASTLE_ALCOVE \
- { 1.0000f, 0.8900f, 0.3162f, 0.5012f, 0.1000f, 1.6400f, 0.8700f, 0.3100f, 1.0000f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0340f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 }
-
-/* Factory Presets */
-
-#define EFX_REVERB_PRESET_FACTORY_SMALLROOM \
- { 0.3645f, 0.8200f, 0.3162f, 0.7943f, 0.5012f, 1.7200f, 0.6500f, 1.3100f, 0.7079f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.7783f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.1190f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_FACTORY_SHORTPASSAGE \
- { 0.3645f, 0.6400f, 0.2512f, 0.7943f, 0.5012f, 2.5300f, 0.6500f, 1.3100f, 1.0000f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0380f, { 0.0000f, 0.0000f, 0.0000f }, 0.1350f, 0.2300f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_FACTORY_MEDIUMROOM \
- { 0.4287f, 0.8200f, 0.2512f, 0.7943f, 0.5012f, 2.7600f, 0.6500f, 1.3100f, 0.2818f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.1740f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_FACTORY_LARGEROOM \
- { 0.4287f, 0.7500f, 0.2512f, 0.7079f, 0.6310f, 4.2400f, 0.5100f, 1.3100f, 0.1778f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.2310f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_FACTORY_LONGPASSAGE \
- { 0.3645f, 0.6400f, 0.2512f, 0.7943f, 0.5012f, 4.0600f, 0.6500f, 1.3100f, 1.0000f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0370f, { 0.0000f, 0.0000f, 0.0000f }, 0.1350f, 0.2300f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_FACTORY_HALL \
- { 0.4287f, 0.7500f, 0.3162f, 0.7079f, 0.6310f, 7.4300f, 0.5100f, 1.3100f, 0.0631f, 0.0730f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0270f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_FACTORY_CUPBOARD \
- { 0.3071f, 0.6300f, 0.2512f, 0.7943f, 0.5012f, 0.4900f, 0.6500f, 1.3100f, 1.2589f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.9953f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.1070f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_FACTORY_COURTYARD \
- { 0.3071f, 0.5700f, 0.3162f, 0.3162f, 0.6310f, 2.3200f, 0.2900f, 0.5600f, 0.2239f, 0.1400f, { 0.0000f, 0.0000f, 0.0000f }, 0.3981f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2900f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_FACTORY_ALCOVE \
- { 0.3645f, 0.5900f, 0.2512f, 0.7943f, 0.5012f, 3.1400f, 0.6500f, 1.3100f, 1.4125f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.0000f, 0.0380f, { 0.0000f, 0.0000f, 0.0000f }, 0.1140f, 0.1000f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
-
-/* Ice Palace Presets */
-
-#define EFX_REVERB_PRESET_ICEPALACE_SMALLROOM \
- { 1.0000f, 0.8400f, 0.3162f, 0.5623f, 0.2818f, 1.5100f, 1.5300f, 0.2700f, 0.8913f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1640f, 0.1400f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_ICEPALACE_SHORTPASSAGE \
- { 1.0000f, 0.7500f, 0.3162f, 0.5623f, 0.2818f, 1.7900f, 1.4600f, 0.2800f, 0.5012f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0190f, { 0.0000f, 0.0000f, 0.0000f }, 0.1770f, 0.0900f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_ICEPALACE_MEDIUMROOM \
- { 1.0000f, 0.8700f, 0.3162f, 0.5623f, 0.4467f, 2.2200f, 1.5300f, 0.3200f, 0.3981f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0270f, { 0.0000f, 0.0000f, 0.0000f }, 0.1860f, 0.1200f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_ICEPALACE_LARGEROOM \
- { 1.0000f, 0.8100f, 0.3162f, 0.5623f, 0.4467f, 3.1400f, 1.5300f, 0.3200f, 0.2512f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 1.0000f, 0.0270f, { 0.0000f, 0.0000f, 0.0000f }, 0.2140f, 0.1100f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_ICEPALACE_LONGPASSAGE \
- { 1.0000f, 0.7700f, 0.3162f, 0.5623f, 0.3981f, 3.0100f, 1.4600f, 0.2800f, 0.7943f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0250f, { 0.0000f, 0.0000f, 0.0000f }, 0.1860f, 0.0400f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_ICEPALACE_HALL \
- { 1.0000f, 0.7600f, 0.3162f, 0.4467f, 0.5623f, 5.4900f, 1.5300f, 0.3800f, 0.1122f, 0.0540f, { 0.0000f, 0.0000f, 0.0000f }, 0.6310f, 0.0520f, { 0.0000f, 0.0000f, 0.0000f }, 0.2260f, 0.1100f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_ICEPALACE_CUPBOARD \
- { 1.0000f, 0.8300f, 0.3162f, 0.5012f, 0.2239f, 0.7600f, 1.5300f, 0.2600f, 1.1220f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.9953f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.1430f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_ICEPALACE_COURTYARD \
- { 1.0000f, 0.5900f, 0.3162f, 0.2818f, 0.3162f, 2.0400f, 1.2000f, 0.3800f, 0.3162f, 0.1730f, { 0.0000f, 0.0000f, 0.0000f }, 0.3162f, 0.0430f, { 0.0000f, 0.0000f, 0.0000f }, 0.2350f, 0.4800f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_ICEPALACE_ALCOVE \
- { 1.0000f, 0.8400f, 0.3162f, 0.5623f, 0.2818f, 2.7600f, 1.4600f, 0.2800f, 1.1220f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1610f, 0.0900f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
-
-/* Space Station Presets */
-
-#define EFX_REVERB_PRESET_SPACESTATION_SMALLROOM \
- { 0.2109f, 0.7000f, 0.3162f, 0.7079f, 0.8913f, 1.7200f, 0.8200f, 0.5500f, 0.7943f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0130f, { 0.0000f, 0.0000f, 0.0000f }, 0.1880f, 0.2600f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_SPACESTATION_SHORTPASSAGE \
- { 0.2109f, 0.8700f, 0.3162f, 0.6310f, 0.8913f, 3.5700f, 0.5000f, 0.5500f, 1.0000f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.1720f, 0.2000f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_SPACESTATION_MEDIUMROOM \
- { 0.2109f, 0.7500f, 0.3162f, 0.6310f, 0.8913f, 3.0100f, 0.5000f, 0.5500f, 0.3981f, 0.0340f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0350f, { 0.0000f, 0.0000f, 0.0000f }, 0.2090f, 0.3100f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_SPACESTATION_LARGEROOM \
- { 0.3645f, 0.8100f, 0.3162f, 0.6310f, 0.8913f, 3.8900f, 0.3800f, 0.6100f, 0.3162f, 0.0560f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0350f, { 0.0000f, 0.0000f, 0.0000f }, 0.2330f, 0.2800f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_SPACESTATION_LONGPASSAGE \
- { 0.4287f, 0.8200f, 0.3162f, 0.6310f, 0.8913f, 4.6200f, 0.6200f, 0.5500f, 1.0000f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0310f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2300f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_SPACESTATION_HALL \
- { 0.4287f, 0.8700f, 0.3162f, 0.6310f, 0.8913f, 7.1100f, 0.3800f, 0.6100f, 0.1778f, 0.1000f, { 0.0000f, 0.0000f, 0.0000f }, 0.6310f, 0.0470f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2500f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_SPACESTATION_CUPBOARD \
- { 0.1715f, 0.5600f, 0.3162f, 0.7079f, 0.8913f, 0.7900f, 0.8100f, 0.5500f, 1.4125f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.7783f, 0.0180f, { 0.0000f, 0.0000f, 0.0000f }, 0.1810f, 0.3100f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_SPACESTATION_ALCOVE \
- { 0.2109f, 0.7800f, 0.3162f, 0.7079f, 0.8913f, 1.1600f, 0.8100f, 0.5500f, 1.4125f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.0000f, 0.0180f, { 0.0000f, 0.0000f, 0.0000f }, 0.1920f, 0.2100f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 }
-
-/* Wooden Galleon Presets */
-
-#define EFX_REVERB_PRESET_WOODEN_SMALLROOM \
- { 1.0000f, 1.0000f, 0.3162f, 0.1122f, 0.3162f, 0.7900f, 0.3200f, 0.8700f, 1.0000f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_WOODEN_SHORTPASSAGE \
- { 1.0000f, 1.0000f, 0.3162f, 0.1259f, 0.3162f, 1.7500f, 0.5000f, 0.8700f, 0.8913f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.6310f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_WOODEN_MEDIUMROOM \
- { 1.0000f, 1.0000f, 0.3162f, 0.1000f, 0.2818f, 1.4700f, 0.4200f, 0.8200f, 0.8913f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_WOODEN_LARGEROOM \
- { 1.0000f, 1.0000f, 0.3162f, 0.0891f, 0.2818f, 2.6500f, 0.3300f, 0.8200f, 0.8913f, 0.0660f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_WOODEN_LONGPASSAGE \
- { 1.0000f, 1.0000f, 0.3162f, 0.1000f, 0.3162f, 1.9900f, 0.4000f, 0.7900f, 1.0000f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.4467f, 0.0360f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_WOODEN_HALL \
- { 1.0000f, 1.0000f, 0.3162f, 0.0794f, 0.2818f, 3.4500f, 0.3000f, 0.8200f, 0.8913f, 0.0880f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0630f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_WOODEN_CUPBOARD \
- { 1.0000f, 1.0000f, 0.3162f, 0.1413f, 0.3162f, 0.5600f, 0.4600f, 0.9100f, 1.1220f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0280f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_WOODEN_COURTYARD \
- { 1.0000f, 0.6500f, 0.3162f, 0.0794f, 0.3162f, 1.7900f, 0.3500f, 0.7900f, 0.5623f, 0.1230f, { 0.0000f, 0.0000f, 0.0000f }, 0.1000f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_WOODEN_ALCOVE \
- { 1.0000f, 1.0000f, 0.3162f, 0.1259f, 0.3162f, 1.2200f, 0.6200f, 0.9100f, 1.1220f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
-
-/* Sports Presets */
-
-#define EFX_REVERB_PRESET_SPORT_EMPTYSTADIUM \
- { 1.0000f, 1.0000f, 0.3162f, 0.4467f, 0.7943f, 6.2600f, 0.5100f, 1.1000f, 0.0631f, 0.1830f, { 0.0000f, 0.0000f, 0.0000f }, 0.3981f, 0.0380f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_SPORT_SQUASHCOURT \
- { 1.0000f, 0.7500f, 0.3162f, 0.3162f, 0.7943f, 2.2200f, 0.9100f, 1.1600f, 0.4467f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1260f, 0.1900f, 0.2500f, 0.0000f, 0.9943f, 7176.8999f, 211.2000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_SPORT_SMALLSWIMMINGPOOL \
- { 1.0000f, 0.7000f, 0.3162f, 0.7943f, 0.8913f, 2.7600f, 1.2500f, 1.1400f, 0.6310f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1790f, 0.1500f, 0.8950f, 0.1900f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_SPORT_LARGESWIMMINGPOOL \
- { 1.0000f, 0.8200f, 0.3162f, 0.7943f, 1.0000f, 5.4900f, 1.3100f, 1.1400f, 0.4467f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 0.5012f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2220f, 0.5500f, 1.1590f, 0.2100f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_SPORT_GYMNASIUM \
- { 1.0000f, 0.8100f, 0.3162f, 0.4467f, 0.8913f, 3.1400f, 1.0600f, 1.3500f, 0.3981f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.5623f, 0.0450f, { 0.0000f, 0.0000f, 0.0000f }, 0.1460f, 0.1400f, 0.2500f, 0.0000f, 0.9943f, 7176.8999f, 211.2000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_SPORT_FULLSTADIUM \
- { 1.0000f, 1.0000f, 0.3162f, 0.0708f, 0.7943f, 5.2500f, 0.1700f, 0.8000f, 0.1000f, 0.1880f, { 0.0000f, 0.0000f, 0.0000f }, 0.2818f, 0.0380f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_SPORT_STADIUMTANNOY \
- { 1.0000f, 0.7800f, 0.3162f, 0.5623f, 0.5012f, 2.5300f, 0.8800f, 0.6800f, 0.2818f, 0.2300f, { 0.0000f, 0.0000f, 0.0000f }, 0.5012f, 0.0630f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-/* Prefab Presets */
-
-#define EFX_REVERB_PRESET_PREFAB_WORKSHOP \
- { 0.4287f, 1.0000f, 0.3162f, 0.1413f, 0.3981f, 0.7600f, 1.0000f, 1.0000f, 1.0000f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_PREFAB_SCHOOLROOM \
- { 0.4022f, 0.6900f, 0.3162f, 0.6310f, 0.5012f, 0.9800f, 0.4500f, 0.1800f, 1.4125f, 0.0170f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0150f, { 0.0000f, 0.0000f, 0.0000f }, 0.0950f, 0.1400f, 0.2500f, 0.0000f, 0.9943f, 7176.8999f, 211.2000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_PREFAB_PRACTISEROOM \
- { 0.4022f, 0.8700f, 0.3162f, 0.3981f, 0.5012f, 1.1200f, 0.5600f, 0.1800f, 1.2589f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.0950f, 0.1400f, 0.2500f, 0.0000f, 0.9943f, 7176.8999f, 211.2000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_PREFAB_OUTHOUSE \
- { 1.0000f, 0.8200f, 0.3162f, 0.1122f, 0.1585f, 1.3800f, 0.3800f, 0.3500f, 0.8913f, 0.0240f, { 0.0000f, 0.0000f, -0.0000f }, 0.6310f, 0.0440f, { 0.0000f, 0.0000f, 0.0000f }, 0.1210f, 0.1700f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 107.5000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_PREFAB_CARAVAN \
- { 1.0000f, 1.0000f, 0.3162f, 0.0891f, 0.1259f, 0.4300f, 1.5000f, 1.0000f, 1.0000f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.9953f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
-
-/* Dome and Pipe Presets */
-
-#define EFX_REVERB_PRESET_DOME_TOMB \
- { 1.0000f, 0.7900f, 0.3162f, 0.3548f, 0.2239f, 4.1800f, 0.2100f, 0.1000f, 0.3868f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 1.6788f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 0.1770f, 0.1900f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_PIPE_SMALL \
- { 1.0000f, 1.0000f, 0.3162f, 0.3548f, 0.2239f, 5.0400f, 0.1000f, 0.1000f, 0.5012f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 2.5119f, 0.0150f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_DOME_SAINTPAULS \
- { 1.0000f, 0.8700f, 0.3162f, 0.3548f, 0.2239f, 10.4800f, 0.1900f, 0.1000f, 0.1778f, 0.0900f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0420f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.1200f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_PIPE_LONGTHIN \
- { 0.2560f, 0.9100f, 0.3162f, 0.4467f, 0.2818f, 9.2100f, 0.1800f, 0.1000f, 0.7079f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_PIPE_LARGE \
- { 1.0000f, 1.0000f, 0.3162f, 0.3548f, 0.2239f, 8.4500f, 0.1000f, 0.1000f, 0.3981f, 0.0460f, { 0.0000f, 0.0000f, 0.0000f }, 1.5849f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_PIPE_RESONANT \
- { 0.1373f, 0.9100f, 0.3162f, 0.4467f, 0.2818f, 6.8100f, 0.1800f, 0.1000f, 0.7079f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.0000f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x0 }
-
-/* Outdoors Presets */
-
-#define EFX_REVERB_PRESET_OUTDOORS_BACKYARD \
- { 1.0000f, 0.4500f, 0.3162f, 0.2512f, 0.5012f, 1.1200f, 0.3400f, 0.4600f, 0.4467f, 0.0690f, { 0.0000f, 0.0000f, -0.0000f }, 0.7079f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.2180f, 0.3400f, 0.2500f, 0.0000f, 0.9943f, 4399.1001f, 242.9000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_OUTDOORS_ROLLINGPLAINS \
- { 1.0000f, 0.0000f, 0.3162f, 0.0112f, 0.6310f, 2.1300f, 0.2100f, 0.4600f, 0.1778f, 0.3000f, { 0.0000f, 0.0000f, -0.0000f }, 0.4467f, 0.0190f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 4399.1001f, 242.9000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_OUTDOORS_DEEPCANYON \
- { 1.0000f, 0.7400f, 0.3162f, 0.1778f, 0.6310f, 3.8900f, 0.2100f, 0.4600f, 0.3162f, 0.2230f, { 0.0000f, 0.0000f, -0.0000f }, 0.3548f, 0.0190f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 4399.1001f, 242.9000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_OUTDOORS_CREEK \
- { 1.0000f, 0.3500f, 0.3162f, 0.1778f, 0.5012f, 2.1300f, 0.2100f, 0.4600f, 0.3981f, 0.1150f, { 0.0000f, 0.0000f, -0.0000f }, 0.1995f, 0.0310f, { 0.0000f, 0.0000f, 0.0000f }, 0.2180f, 0.3400f, 0.2500f, 0.0000f, 0.9943f, 4399.1001f, 242.9000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_OUTDOORS_VALLEY \
- { 1.0000f, 0.2800f, 0.3162f, 0.0282f, 0.1585f, 2.8800f, 0.2600f, 0.3500f, 0.1413f, 0.2630f, { 0.0000f, 0.0000f, -0.0000f }, 0.3981f, 0.1000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.3400f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 107.5000f, 0.0000f, 0x0 }
-
-/* Mood Presets */
-
-#define EFX_REVERB_PRESET_MOOD_HEAVEN \
- { 1.0000f, 0.9400f, 0.3162f, 0.7943f, 0.4467f, 5.0400f, 1.1200f, 0.5600f, 0.2427f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0800f, 2.7420f, 0.0500f, 0.9977f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_MOOD_HELL \
- { 1.0000f, 0.5700f, 0.3162f, 0.3548f, 0.4467f, 3.5700f, 0.4900f, 2.0000f, 0.0000f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1100f, 0.0400f, 2.1090f, 0.5200f, 0.9943f, 5000.0000f, 139.5000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_MOOD_MEMORY \
- { 1.0000f, 0.8500f, 0.3162f, 0.6310f, 0.3548f, 4.0600f, 0.8200f, 0.5600f, 0.0398f, 0.0000f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.4740f, 0.4500f, 0.9886f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
-
-/* Driving Presets */
-
-#define EFX_REVERB_PRESET_DRIVING_COMMENTATOR \
- { 1.0000f, 0.0000f, 0.3162f, 0.5623f, 0.5012f, 2.4200f, 0.8800f, 0.6800f, 0.1995f, 0.0930f, { 0.0000f, 0.0000f, 0.0000f }, 0.2512f, 0.0170f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9886f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_DRIVING_PITGARAGE \
- { 0.4287f, 0.5900f, 0.3162f, 0.7079f, 0.5623f, 1.7200f, 0.9300f, 0.8700f, 0.5623f, 0.0000f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.1100f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_DRIVING_INCAR_RACER \
- { 0.0832f, 0.8000f, 0.3162f, 1.0000f, 0.7943f, 0.1700f, 2.0000f, 0.4100f, 1.7783f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0150f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10268.2002f, 251.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_DRIVING_INCAR_SPORTS \
- { 0.0832f, 0.8000f, 0.3162f, 0.6310f, 1.0000f, 0.1700f, 0.7500f, 0.4100f, 1.0000f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 0.5623f, 0.0000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10268.2002f, 251.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_DRIVING_INCAR_LUXURY \
- { 0.2560f, 1.0000f, 0.3162f, 0.1000f, 0.5012f, 0.1300f, 0.4100f, 0.4600f, 0.7943f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.5849f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10268.2002f, 251.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_DRIVING_FULLGRANDSTAND \
- { 1.0000f, 1.0000f, 0.3162f, 0.2818f, 0.6310f, 3.0100f, 1.3700f, 1.2800f, 0.3548f, 0.0900f, { 0.0000f, 0.0000f, 0.0000f }, 0.1778f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10420.2002f, 250.0000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_DRIVING_EMPTYGRANDSTAND \
- { 1.0000f, 1.0000f, 0.3162f, 1.0000f, 0.7943f, 4.6200f, 1.7500f, 1.4000f, 0.2082f, 0.0900f, { 0.0000f, 0.0000f, 0.0000f }, 0.2512f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10420.2002f, 250.0000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_DRIVING_TUNNEL \
- { 1.0000f, 0.8100f, 0.3162f, 0.3981f, 0.8913f, 3.4200f, 0.9400f, 1.3100f, 0.7079f, 0.0510f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0470f, { 0.0000f, 0.0000f, 0.0000f }, 0.2140f, 0.0500f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 155.3000f, 0.0000f, 0x1 }
-
-/* City Presets */
-
-#define EFX_REVERB_PRESET_CITY_STREETS \
- { 1.0000f, 0.7800f, 0.3162f, 0.7079f, 0.8913f, 1.7900f, 1.1200f, 0.9100f, 0.2818f, 0.0460f, { 0.0000f, 0.0000f, 0.0000f }, 0.1995f, 0.0280f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_CITY_SUBWAY \
- { 1.0000f, 0.7400f, 0.3162f, 0.7079f, 0.8913f, 3.0100f, 1.2300f, 0.9100f, 0.7079f, 0.0460f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0280f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 0.2100f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_CITY_MUSEUM \
- { 1.0000f, 0.8200f, 0.3162f, 0.1778f, 0.1778f, 3.2800f, 1.4000f, 0.5700f, 0.2512f, 0.0390f, { 0.0000f, 0.0000f, -0.0000f }, 0.8913f, 0.0340f, { 0.0000f, 0.0000f, 0.0000f }, 0.1300f, 0.1700f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 107.5000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_CITY_LIBRARY \
- { 1.0000f, 0.8200f, 0.3162f, 0.2818f, 0.0891f, 2.7600f, 0.8900f, 0.4100f, 0.3548f, 0.0290f, { 0.0000f, 0.0000f, -0.0000f }, 0.8913f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.1300f, 0.1700f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 107.5000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_CITY_UNDERPASS \
- { 1.0000f, 0.8200f, 0.3162f, 0.4467f, 0.8913f, 3.5700f, 1.1200f, 0.9100f, 0.3981f, 0.0590f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0370f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.1400f, 0.2500f, 0.0000f, 0.9920f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_CITY_ABANDONED \
- { 1.0000f, 0.6900f, 0.3162f, 0.7943f, 0.8913f, 3.2800f, 1.1700f, 0.9100f, 0.4467f, 0.0440f, { 0.0000f, 0.0000f, 0.0000f }, 0.2818f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2000f, 0.2500f, 0.0000f, 0.9966f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-/* Misc. Presets */
-
-#define EFX_REVERB_PRESET_DUSTYROOM \
- { 0.3645f, 0.5600f, 0.3162f, 0.7943f, 0.7079f, 1.7900f, 0.3800f, 0.2100f, 0.5012f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0060f, { 0.0000f, 0.0000f, 0.0000f }, 0.2020f, 0.0500f, 0.2500f, 0.0000f, 0.9886f, 13046.0000f, 163.3000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_CHAPEL \
- { 1.0000f, 0.8400f, 0.3162f, 0.5623f, 1.0000f, 4.6200f, 0.6400f, 1.2300f, 0.4467f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.1100f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_SMALLWATERROOM \
- { 1.0000f, 0.7000f, 0.3162f, 0.4477f, 1.0000f, 1.5100f, 1.2500f, 1.1400f, 0.8913f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1790f, 0.1500f, 0.8950f, 0.1900f, 0.9920f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
-
-#endif /* EFX_PRESETS_H */
diff --git a/project/vs2015/external/openal_soft/include/AL/efx.h b/project/vs2015/external/openal_soft/include/AL/efx.h
deleted file mode 100644
index 57766983f..000000000
--- a/project/vs2015/external/openal_soft/include/AL/efx.h
+++ /dev/null
@@ -1,761 +0,0 @@
-#ifndef AL_EFX_H
-#define AL_EFX_H
-
-
-#include "alc.h"
-#include "al.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define ALC_EXT_EFX_NAME "ALC_EXT_EFX"
-
-#define ALC_EFX_MAJOR_VERSION 0x20001
-#define ALC_EFX_MINOR_VERSION 0x20002
-#define ALC_MAX_AUXILIARY_SENDS 0x20003
-
-
-/* Listener properties. */
-#define AL_METERS_PER_UNIT 0x20004
-
-/* Source properties. */
-#define AL_DIRECT_FILTER 0x20005
-#define AL_AUXILIARY_SEND_FILTER 0x20006
-#define AL_AIR_ABSORPTION_FACTOR 0x20007
-#define AL_ROOM_ROLLOFF_FACTOR 0x20008
-#define AL_CONE_OUTER_GAINHF 0x20009
-#define AL_DIRECT_FILTER_GAINHF_AUTO 0x2000A
-#define AL_AUXILIARY_SEND_FILTER_GAIN_AUTO 0x2000B
-#define AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO 0x2000C
-
-
-/* Effect properties. */
-
-/* Reverb effect parameters */
-#define AL_REVERB_DENSITY 0x0001
-#define AL_REVERB_DIFFUSION 0x0002
-#define AL_REVERB_GAIN 0x0003
-#define AL_REVERB_GAINHF 0x0004
-#define AL_REVERB_DECAY_TIME 0x0005
-#define AL_REVERB_DECAY_HFRATIO 0x0006
-#define AL_REVERB_REFLECTIONS_GAIN 0x0007
-#define AL_REVERB_REFLECTIONS_DELAY 0x0008
-#define AL_REVERB_LATE_REVERB_GAIN 0x0009
-#define AL_REVERB_LATE_REVERB_DELAY 0x000A
-#define AL_REVERB_AIR_ABSORPTION_GAINHF 0x000B
-#define AL_REVERB_ROOM_ROLLOFF_FACTOR 0x000C
-#define AL_REVERB_DECAY_HFLIMIT 0x000D
-
-/* EAX Reverb effect parameters */
-#define AL_EAXREVERB_DENSITY 0x0001
-#define AL_EAXREVERB_DIFFUSION 0x0002
-#define AL_EAXREVERB_GAIN 0x0003
-#define AL_EAXREVERB_GAINHF 0x0004
-#define AL_EAXREVERB_GAINLF 0x0005
-#define AL_EAXREVERB_DECAY_TIME 0x0006
-#define AL_EAXREVERB_DECAY_HFRATIO 0x0007
-#define AL_EAXREVERB_DECAY_LFRATIO 0x0008
-#define AL_EAXREVERB_REFLECTIONS_GAIN 0x0009
-#define AL_EAXREVERB_REFLECTIONS_DELAY 0x000A
-#define AL_EAXREVERB_REFLECTIONS_PAN 0x000B
-#define AL_EAXREVERB_LATE_REVERB_GAIN 0x000C
-#define AL_EAXREVERB_LATE_REVERB_DELAY 0x000D
-#define AL_EAXREVERB_LATE_REVERB_PAN 0x000E
-#define AL_EAXREVERB_ECHO_TIME 0x000F
-#define AL_EAXREVERB_ECHO_DEPTH 0x0010
-#define AL_EAXREVERB_MODULATION_TIME 0x0011
-#define AL_EAXREVERB_MODULATION_DEPTH 0x0012
-#define AL_EAXREVERB_AIR_ABSORPTION_GAINHF 0x0013
-#define AL_EAXREVERB_HFREFERENCE 0x0014
-#define AL_EAXREVERB_LFREFERENCE 0x0015
-#define AL_EAXREVERB_ROOM_ROLLOFF_FACTOR 0x0016
-#define AL_EAXREVERB_DECAY_HFLIMIT 0x0017
-
-/* Chorus effect parameters */
-#define AL_CHORUS_WAVEFORM 0x0001
-#define AL_CHORUS_PHASE 0x0002
-#define AL_CHORUS_RATE 0x0003
-#define AL_CHORUS_DEPTH 0x0004
-#define AL_CHORUS_FEEDBACK 0x0005
-#define AL_CHORUS_DELAY 0x0006
-
-/* Distortion effect parameters */
-#define AL_DISTORTION_EDGE 0x0001
-#define AL_DISTORTION_GAIN 0x0002
-#define AL_DISTORTION_LOWPASS_CUTOFF 0x0003
-#define AL_DISTORTION_EQCENTER 0x0004
-#define AL_DISTORTION_EQBANDWIDTH 0x0005
-
-/* Echo effect parameters */
-#define AL_ECHO_DELAY 0x0001
-#define AL_ECHO_LRDELAY 0x0002
-#define AL_ECHO_DAMPING 0x0003
-#define AL_ECHO_FEEDBACK 0x0004
-#define AL_ECHO_SPREAD 0x0005
-
-/* Flanger effect parameters */
-#define AL_FLANGER_WAVEFORM 0x0001
-#define AL_FLANGER_PHASE 0x0002
-#define AL_FLANGER_RATE 0x0003
-#define AL_FLANGER_DEPTH 0x0004
-#define AL_FLANGER_FEEDBACK 0x0005
-#define AL_FLANGER_DELAY 0x0006
-
-/* Frequency shifter effect parameters */
-#define AL_FREQUENCY_SHIFTER_FREQUENCY 0x0001
-#define AL_FREQUENCY_SHIFTER_LEFT_DIRECTION 0x0002
-#define AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION 0x0003
-
-/* Vocal morpher effect parameters */
-#define AL_VOCAL_MORPHER_PHONEMEA 0x0001
-#define AL_VOCAL_MORPHER_PHONEMEA_COARSE_TUNING 0x0002
-#define AL_VOCAL_MORPHER_PHONEMEB 0x0003
-#define AL_VOCAL_MORPHER_PHONEMEB_COARSE_TUNING 0x0004
-#define AL_VOCAL_MORPHER_WAVEFORM 0x0005
-#define AL_VOCAL_MORPHER_RATE 0x0006
-
-/* Pitchshifter effect parameters */
-#define AL_PITCH_SHIFTER_COARSE_TUNE 0x0001
-#define AL_PITCH_SHIFTER_FINE_TUNE 0x0002
-
-/* Ringmodulator effect parameters */
-#define AL_RING_MODULATOR_FREQUENCY 0x0001
-#define AL_RING_MODULATOR_HIGHPASS_CUTOFF 0x0002
-#define AL_RING_MODULATOR_WAVEFORM 0x0003
-
-/* Autowah effect parameters */
-#define AL_AUTOWAH_ATTACK_TIME 0x0001
-#define AL_AUTOWAH_RELEASE_TIME 0x0002
-#define AL_AUTOWAH_RESONANCE 0x0003
-#define AL_AUTOWAH_PEAK_GAIN 0x0004
-
-/* Compressor effect parameters */
-#define AL_COMPRESSOR_ONOFF 0x0001
-
-/* Equalizer effect parameters */
-#define AL_EQUALIZER_LOW_GAIN 0x0001
-#define AL_EQUALIZER_LOW_CUTOFF 0x0002
-#define AL_EQUALIZER_MID1_GAIN 0x0003
-#define AL_EQUALIZER_MID1_CENTER 0x0004
-#define AL_EQUALIZER_MID1_WIDTH 0x0005
-#define AL_EQUALIZER_MID2_GAIN 0x0006
-#define AL_EQUALIZER_MID2_CENTER 0x0007
-#define AL_EQUALIZER_MID2_WIDTH 0x0008
-#define AL_EQUALIZER_HIGH_GAIN 0x0009
-#define AL_EQUALIZER_HIGH_CUTOFF 0x000A
-
-/* Effect type */
-#define AL_EFFECT_FIRST_PARAMETER 0x0000
-#define AL_EFFECT_LAST_PARAMETER 0x8000
-#define AL_EFFECT_TYPE 0x8001
-
-/* Effect types, used with the AL_EFFECT_TYPE property */
-#define AL_EFFECT_NULL 0x0000
-#define AL_EFFECT_REVERB 0x0001
-#define AL_EFFECT_CHORUS 0x0002
-#define AL_EFFECT_DISTORTION 0x0003
-#define AL_EFFECT_ECHO 0x0004
-#define AL_EFFECT_FLANGER 0x0005
-#define AL_EFFECT_FREQUENCY_SHIFTER 0x0006
-#define AL_EFFECT_VOCAL_MORPHER 0x0007
-#define AL_EFFECT_PITCH_SHIFTER 0x0008
-#define AL_EFFECT_RING_MODULATOR 0x0009
-#define AL_EFFECT_AUTOWAH 0x000A
-#define AL_EFFECT_COMPRESSOR 0x000B
-#define AL_EFFECT_EQUALIZER 0x000C
-#define AL_EFFECT_EAXREVERB 0x8000
-
-/* Auxiliary Effect Slot properties. */
-#define AL_EFFECTSLOT_EFFECT 0x0001
-#define AL_EFFECTSLOT_GAIN 0x0002
-#define AL_EFFECTSLOT_AUXILIARY_SEND_AUTO 0x0003
-
-/* NULL Auxiliary Slot ID to disable a source send. */
-#define AL_EFFECTSLOT_NULL 0x0000
-
-
-/* Filter properties. */
-
-/* Lowpass filter parameters */
-#define AL_LOWPASS_GAIN 0x0001
-#define AL_LOWPASS_GAINHF 0x0002
-
-/* Highpass filter parameters */
-#define AL_HIGHPASS_GAIN 0x0001
-#define AL_HIGHPASS_GAINLF 0x0002
-
-/* Bandpass filter parameters */
-#define AL_BANDPASS_GAIN 0x0001
-#define AL_BANDPASS_GAINLF 0x0002
-#define AL_BANDPASS_GAINHF 0x0003
-
-/* Filter type */
-#define AL_FILTER_FIRST_PARAMETER 0x0000
-#define AL_FILTER_LAST_PARAMETER 0x8000
-#define AL_FILTER_TYPE 0x8001
-
-/* Filter types, used with the AL_FILTER_TYPE property */
-#define AL_FILTER_NULL 0x0000
-#define AL_FILTER_LOWPASS 0x0001
-#define AL_FILTER_HIGHPASS 0x0002
-#define AL_FILTER_BANDPASS 0x0003
-
-
-/* Effect object function types. */
-typedef void (AL_APIENTRY *LPALGENEFFECTS)(ALsizei, ALuint*);
-typedef void (AL_APIENTRY *LPALDELETEEFFECTS)(ALsizei, const ALuint*);
-typedef ALboolean (AL_APIENTRY *LPALISEFFECT)(ALuint);
-typedef void (AL_APIENTRY *LPALEFFECTI)(ALuint, ALenum, ALint);
-typedef void (AL_APIENTRY *LPALEFFECTIV)(ALuint, ALenum, const ALint*);
-typedef void (AL_APIENTRY *LPALEFFECTF)(ALuint, ALenum, ALfloat);
-typedef void (AL_APIENTRY *LPALEFFECTFV)(ALuint, ALenum, const ALfloat*);
-typedef void (AL_APIENTRY *LPALGETEFFECTI)(ALuint, ALenum, ALint*);
-typedef void (AL_APIENTRY *LPALGETEFFECTIV)(ALuint, ALenum, ALint*);
-typedef void (AL_APIENTRY *LPALGETEFFECTF)(ALuint, ALenum, ALfloat*);
-typedef void (AL_APIENTRY *LPALGETEFFECTFV)(ALuint, ALenum, ALfloat*);
-
-/* Filter object function types. */
-typedef void (AL_APIENTRY *LPALGENFILTERS)(ALsizei, ALuint*);
-typedef void (AL_APIENTRY *LPALDELETEFILTERS)(ALsizei, const ALuint*);
-typedef ALboolean (AL_APIENTRY *LPALISFILTER)(ALuint);
-typedef void (AL_APIENTRY *LPALFILTERI)(ALuint, ALenum, ALint);
-typedef void (AL_APIENTRY *LPALFILTERIV)(ALuint, ALenum, const ALint*);
-typedef void (AL_APIENTRY *LPALFILTERF)(ALuint, ALenum, ALfloat);
-typedef void (AL_APIENTRY *LPALFILTERFV)(ALuint, ALenum, const ALfloat*);
-typedef void (AL_APIENTRY *LPALGETFILTERI)(ALuint, ALenum, ALint*);
-typedef void (AL_APIENTRY *LPALGETFILTERIV)(ALuint, ALenum, ALint*);
-typedef void (AL_APIENTRY *LPALGETFILTERF)(ALuint, ALenum, ALfloat*);
-typedef void (AL_APIENTRY *LPALGETFILTERFV)(ALuint, ALenum, ALfloat*);
-
-/* Auxiliary Effect Slot object function types. */
-typedef void (AL_APIENTRY *LPALGENAUXILIARYEFFECTSLOTS)(ALsizei, ALuint*);
-typedef void (AL_APIENTRY *LPALDELETEAUXILIARYEFFECTSLOTS)(ALsizei, const ALuint*);
-typedef ALboolean (AL_APIENTRY *LPALISAUXILIARYEFFECTSLOT)(ALuint);
-typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTI)(ALuint, ALenum, ALint);
-typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTIV)(ALuint, ALenum, const ALint*);
-typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTF)(ALuint, ALenum, ALfloat);
-typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTFV)(ALuint, ALenum, const ALfloat*);
-typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTI)(ALuint, ALenum, ALint*);
-typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTIV)(ALuint, ALenum, ALint*);
-typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTF)(ALuint, ALenum, ALfloat*);
-typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTFV)(ALuint, ALenum, ALfloat*);
-
-#ifdef AL_ALEXT_PROTOTYPES
-AL_API ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects);
-AL_API ALvoid AL_APIENTRY alDeleteEffects(ALsizei n, const ALuint *effects);
-AL_API ALboolean AL_APIENTRY alIsEffect(ALuint effect);
-AL_API ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint iValue);
-AL_API ALvoid AL_APIENTRY alEffectiv(ALuint effect, ALenum param, const ALint *piValues);
-AL_API ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat flValue);
-AL_API ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, const ALfloat *pflValues);
-AL_API ALvoid AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *piValue);
-AL_API ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *piValues);
-AL_API ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *pflValue);
-AL_API ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *pflValues);
-
-AL_API ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters);
-AL_API ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, const ALuint *filters);
-AL_API ALboolean AL_APIENTRY alIsFilter(ALuint filter);
-AL_API ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint iValue);
-AL_API ALvoid AL_APIENTRY alFilteriv(ALuint filter, ALenum param, const ALint *piValues);
-AL_API ALvoid AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat flValue);
-AL_API ALvoid AL_APIENTRY alFilterfv(ALuint filter, ALenum param, const ALfloat *pflValues);
-AL_API ALvoid AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint *piValue);
-AL_API ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *piValues);
-AL_API ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *pflValue);
-AL_API ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *pflValues);
-
-AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots);
-AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint *effectslots);
-AL_API ALboolean AL_APIENTRY alIsAuxiliaryEffectSlot(ALuint effectslot);
-AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint iValue);
-AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, const ALint *piValues);
-AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat flValue);
-AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, const ALfloat *pflValues);
-AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint *piValue);
-AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALint *piValues);
-AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat *pflValue);
-AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfloat *pflValues);
-#endif
-
-/* Filter ranges and defaults. */
-
-/* Lowpass filter */
-#define AL_LOWPASS_MIN_GAIN (0.0f)
-#define AL_LOWPASS_MAX_GAIN (1.0f)
-#define AL_LOWPASS_DEFAULT_GAIN (1.0f)
-
-#define AL_LOWPASS_MIN_GAINHF (0.0f)
-#define AL_LOWPASS_MAX_GAINHF (1.0f)
-#define AL_LOWPASS_DEFAULT_GAINHF (1.0f)
-
-/* Highpass filter */
-#define AL_HIGHPASS_MIN_GAIN (0.0f)
-#define AL_HIGHPASS_MAX_GAIN (1.0f)
-#define AL_HIGHPASS_DEFAULT_GAIN (1.0f)
-
-#define AL_HIGHPASS_MIN_GAINLF (0.0f)
-#define AL_HIGHPASS_MAX_GAINLF (1.0f)
-#define AL_HIGHPASS_DEFAULT_GAINLF (1.0f)
-
-/* Bandpass filter */
-#define AL_BANDPASS_MIN_GAIN (0.0f)
-#define AL_BANDPASS_MAX_GAIN (1.0f)
-#define AL_BANDPASS_DEFAULT_GAIN (1.0f)
-
-#define AL_BANDPASS_MIN_GAINHF (0.0f)
-#define AL_BANDPASS_MAX_GAINHF (1.0f)
-#define AL_BANDPASS_DEFAULT_GAINHF (1.0f)
-
-#define AL_BANDPASS_MIN_GAINLF (0.0f)
-#define AL_BANDPASS_MAX_GAINLF (1.0f)
-#define AL_BANDPASS_DEFAULT_GAINLF (1.0f)
-
-
-/* Effect parameter ranges and defaults. */
-
-/* Standard reverb effect */
-#define AL_REVERB_MIN_DENSITY (0.0f)
-#define AL_REVERB_MAX_DENSITY (1.0f)
-#define AL_REVERB_DEFAULT_DENSITY (1.0f)
-
-#define AL_REVERB_MIN_DIFFUSION (0.0f)
-#define AL_REVERB_MAX_DIFFUSION (1.0f)
-#define AL_REVERB_DEFAULT_DIFFUSION (1.0f)
-
-#define AL_REVERB_MIN_GAIN (0.0f)
-#define AL_REVERB_MAX_GAIN (1.0f)
-#define AL_REVERB_DEFAULT_GAIN (0.32f)
-
-#define AL_REVERB_MIN_GAINHF (0.0f)
-#define AL_REVERB_MAX_GAINHF (1.0f)
-#define AL_REVERB_DEFAULT_GAINHF (0.89f)
-
-#define AL_REVERB_MIN_DECAY_TIME (0.1f)
-#define AL_REVERB_MAX_DECAY_TIME (20.0f)
-#define AL_REVERB_DEFAULT_DECAY_TIME (1.49f)
-
-#define AL_REVERB_MIN_DECAY_HFRATIO (0.1f)
-#define AL_REVERB_MAX_DECAY_HFRATIO (2.0f)
-#define AL_REVERB_DEFAULT_DECAY_HFRATIO (0.83f)
-
-#define AL_REVERB_MIN_REFLECTIONS_GAIN (0.0f)
-#define AL_REVERB_MAX_REFLECTIONS_GAIN (3.16f)
-#define AL_REVERB_DEFAULT_REFLECTIONS_GAIN (0.05f)
-
-#define AL_REVERB_MIN_REFLECTIONS_DELAY (0.0f)
-#define AL_REVERB_MAX_REFLECTIONS_DELAY (0.3f)
-#define AL_REVERB_DEFAULT_REFLECTIONS_DELAY (0.007f)
-
-#define AL_REVERB_MIN_LATE_REVERB_GAIN (0.0f)
-#define AL_REVERB_MAX_LATE_REVERB_GAIN (10.0f)
-#define AL_REVERB_DEFAULT_LATE_REVERB_GAIN (1.26f)
-
-#define AL_REVERB_MIN_LATE_REVERB_DELAY (0.0f)
-#define AL_REVERB_MAX_LATE_REVERB_DELAY (0.1f)
-#define AL_REVERB_DEFAULT_LATE_REVERB_DELAY (0.011f)
-
-#define AL_REVERB_MIN_AIR_ABSORPTION_GAINHF (0.892f)
-#define AL_REVERB_MAX_AIR_ABSORPTION_GAINHF (1.0f)
-#define AL_REVERB_DEFAULT_AIR_ABSORPTION_GAINHF (0.994f)
-
-#define AL_REVERB_MIN_ROOM_ROLLOFF_FACTOR (0.0f)
-#define AL_REVERB_MAX_ROOM_ROLLOFF_FACTOR (10.0f)
-#define AL_REVERB_DEFAULT_ROOM_ROLLOFF_FACTOR (0.0f)
-
-#define AL_REVERB_MIN_DECAY_HFLIMIT AL_FALSE
-#define AL_REVERB_MAX_DECAY_HFLIMIT AL_TRUE
-#define AL_REVERB_DEFAULT_DECAY_HFLIMIT AL_TRUE
-
-/* EAX reverb effect */
-#define AL_EAXREVERB_MIN_DENSITY (0.0f)
-#define AL_EAXREVERB_MAX_DENSITY (1.0f)
-#define AL_EAXREVERB_DEFAULT_DENSITY (1.0f)
-
-#define AL_EAXREVERB_MIN_DIFFUSION (0.0f)
-#define AL_EAXREVERB_MAX_DIFFUSION (1.0f)
-#define AL_EAXREVERB_DEFAULT_DIFFUSION (1.0f)
-
-#define AL_EAXREVERB_MIN_GAIN (0.0f)
-#define AL_EAXREVERB_MAX_GAIN (1.0f)
-#define AL_EAXREVERB_DEFAULT_GAIN (0.32f)
-
-#define AL_EAXREVERB_MIN_GAINHF (0.0f)
-#define AL_EAXREVERB_MAX_GAINHF (1.0f)
-#define AL_EAXREVERB_DEFAULT_GAINHF (0.89f)
-
-#define AL_EAXREVERB_MIN_GAINLF (0.0f)
-#define AL_EAXREVERB_MAX_GAINLF (1.0f)
-#define AL_EAXREVERB_DEFAULT_GAINLF (1.0f)
-
-#define AL_EAXREVERB_MIN_DECAY_TIME (0.1f)
-#define AL_EAXREVERB_MAX_DECAY_TIME (20.0f)
-#define AL_EAXREVERB_DEFAULT_DECAY_TIME (1.49f)
-
-#define AL_EAXREVERB_MIN_DECAY_HFRATIO (0.1f)
-#define AL_EAXREVERB_MAX_DECAY_HFRATIO (2.0f)
-#define AL_EAXREVERB_DEFAULT_DECAY_HFRATIO (0.83f)
-
-#define AL_EAXREVERB_MIN_DECAY_LFRATIO (0.1f)
-#define AL_EAXREVERB_MAX_DECAY_LFRATIO (2.0f)
-#define AL_EAXREVERB_DEFAULT_DECAY_LFRATIO (1.0f)
-
-#define AL_EAXREVERB_MIN_REFLECTIONS_GAIN (0.0f)
-#define AL_EAXREVERB_MAX_REFLECTIONS_GAIN (3.16f)
-#define AL_EAXREVERB_DEFAULT_REFLECTIONS_GAIN (0.05f)
-
-#define AL_EAXREVERB_MIN_REFLECTIONS_DELAY (0.0f)
-#define AL_EAXREVERB_MAX_REFLECTIONS_DELAY (0.3f)
-#define AL_EAXREVERB_DEFAULT_REFLECTIONS_DELAY (0.007f)
-
-#define AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ (0.0f)
-
-#define AL_EAXREVERB_MIN_LATE_REVERB_GAIN (0.0f)
-#define AL_EAXREVERB_MAX_LATE_REVERB_GAIN (10.0f)
-#define AL_EAXREVERB_DEFAULT_LATE_REVERB_GAIN (1.26f)
-
-#define AL_EAXREVERB_MIN_LATE_REVERB_DELAY (0.0f)
-#define AL_EAXREVERB_MAX_LATE_REVERB_DELAY (0.1f)
-#define AL_EAXREVERB_DEFAULT_LATE_REVERB_DELAY (0.011f)
-
-#define AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ (0.0f)
-
-#define AL_EAXREVERB_MIN_ECHO_TIME (0.075f)
-#define AL_EAXREVERB_MAX_ECHO_TIME (0.25f)
-#define AL_EAXREVERB_DEFAULT_ECHO_TIME (0.25f)
-
-#define AL_EAXREVERB_MIN_ECHO_DEPTH (0.0f)
-#define AL_EAXREVERB_MAX_ECHO_DEPTH (1.0f)
-#define AL_EAXREVERB_DEFAULT_ECHO_DEPTH (0.0f)
-
-#define AL_EAXREVERB_MIN_MODULATION_TIME (0.04f)
-#define AL_EAXREVERB_MAX_MODULATION_TIME (4.0f)
-#define AL_EAXREVERB_DEFAULT_MODULATION_TIME (0.25f)
-
-#define AL_EAXREVERB_MIN_MODULATION_DEPTH (0.0f)
-#define AL_EAXREVERB_MAX_MODULATION_DEPTH (1.0f)
-#define AL_EAXREVERB_DEFAULT_MODULATION_DEPTH (0.0f)
-
-#define AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF (0.892f)
-#define AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF (1.0f)
-#define AL_EAXREVERB_DEFAULT_AIR_ABSORPTION_GAINHF (0.994f)
-
-#define AL_EAXREVERB_MIN_HFREFERENCE (1000.0f)
-#define AL_EAXREVERB_MAX_HFREFERENCE (20000.0f)
-#define AL_EAXREVERB_DEFAULT_HFREFERENCE (5000.0f)
-
-#define AL_EAXREVERB_MIN_LFREFERENCE (20.0f)
-#define AL_EAXREVERB_MAX_LFREFERENCE (1000.0f)
-#define AL_EAXREVERB_DEFAULT_LFREFERENCE (250.0f)
-
-#define AL_EAXREVERB_MIN_ROOM_ROLLOFF_FACTOR (0.0f)
-#define AL_EAXREVERB_MAX_ROOM_ROLLOFF_FACTOR (10.0f)
-#define AL_EAXREVERB_DEFAULT_ROOM_ROLLOFF_FACTOR (0.0f)
-
-#define AL_EAXREVERB_MIN_DECAY_HFLIMIT AL_FALSE
-#define AL_EAXREVERB_MAX_DECAY_HFLIMIT AL_TRUE
-#define AL_EAXREVERB_DEFAULT_DECAY_HFLIMIT AL_TRUE
-
-/* Chorus effect */
-#define AL_CHORUS_WAVEFORM_SINUSOID (0)
-#define AL_CHORUS_WAVEFORM_TRIANGLE (1)
-
-#define AL_CHORUS_MIN_WAVEFORM (0)
-#define AL_CHORUS_MAX_WAVEFORM (1)
-#define AL_CHORUS_DEFAULT_WAVEFORM (1)
-
-#define AL_CHORUS_MIN_PHASE (-180)
-#define AL_CHORUS_MAX_PHASE (180)
-#define AL_CHORUS_DEFAULT_PHASE (90)
-
-#define AL_CHORUS_MIN_RATE (0.0f)
-#define AL_CHORUS_MAX_RATE (10.0f)
-#define AL_CHORUS_DEFAULT_RATE (1.1f)
-
-#define AL_CHORUS_MIN_DEPTH (0.0f)
-#define AL_CHORUS_MAX_DEPTH (1.0f)
-#define AL_CHORUS_DEFAULT_DEPTH (0.1f)
-
-#define AL_CHORUS_MIN_FEEDBACK (-1.0f)
-#define AL_CHORUS_MAX_FEEDBACK (1.0f)
-#define AL_CHORUS_DEFAULT_FEEDBACK (0.25f)
-
-#define AL_CHORUS_MIN_DELAY (0.0f)
-#define AL_CHORUS_MAX_DELAY (0.016f)
-#define AL_CHORUS_DEFAULT_DELAY (0.016f)
-
-/* Distortion effect */
-#define AL_DISTORTION_MIN_EDGE (0.0f)
-#define AL_DISTORTION_MAX_EDGE (1.0f)
-#define AL_DISTORTION_DEFAULT_EDGE (0.2f)
-
-#define AL_DISTORTION_MIN_GAIN (0.01f)
-#define AL_DISTORTION_MAX_GAIN (1.0f)
-#define AL_DISTORTION_DEFAULT_GAIN (0.05f)
-
-#define AL_DISTORTION_MIN_LOWPASS_CUTOFF (80.0f)
-#define AL_DISTORTION_MAX_LOWPASS_CUTOFF (24000.0f)
-#define AL_DISTORTION_DEFAULT_LOWPASS_CUTOFF (8000.0f)
-
-#define AL_DISTORTION_MIN_EQCENTER (80.0f)
-#define AL_DISTORTION_MAX_EQCENTER (24000.0f)
-#define AL_DISTORTION_DEFAULT_EQCENTER (3600.0f)
-
-#define AL_DISTORTION_MIN_EQBANDWIDTH (80.0f)
-#define AL_DISTORTION_MAX_EQBANDWIDTH (24000.0f)
-#define AL_DISTORTION_DEFAULT_EQBANDWIDTH (3600.0f)
-
-/* Echo effect */
-#define AL_ECHO_MIN_DELAY (0.0f)
-#define AL_ECHO_MAX_DELAY (0.207f)
-#define AL_ECHO_DEFAULT_DELAY (0.1f)
-
-#define AL_ECHO_MIN_LRDELAY (0.0f)
-#define AL_ECHO_MAX_LRDELAY (0.404f)
-#define AL_ECHO_DEFAULT_LRDELAY (0.1f)
-
-#define AL_ECHO_MIN_DAMPING (0.0f)
-#define AL_ECHO_MAX_DAMPING (0.99f)
-#define AL_ECHO_DEFAULT_DAMPING (0.5f)
-
-#define AL_ECHO_MIN_FEEDBACK (0.0f)
-#define AL_ECHO_MAX_FEEDBACK (1.0f)
-#define AL_ECHO_DEFAULT_FEEDBACK (0.5f)
-
-#define AL_ECHO_MIN_SPREAD (-1.0f)
-#define AL_ECHO_MAX_SPREAD (1.0f)
-#define AL_ECHO_DEFAULT_SPREAD (-1.0f)
-
-/* Flanger effect */
-#define AL_FLANGER_WAVEFORM_SINUSOID (0)
-#define AL_FLANGER_WAVEFORM_TRIANGLE (1)
-
-#define AL_FLANGER_MIN_WAVEFORM (0)
-#define AL_FLANGER_MAX_WAVEFORM (1)
-#define AL_FLANGER_DEFAULT_WAVEFORM (1)
-
-#define AL_FLANGER_MIN_PHASE (-180)
-#define AL_FLANGER_MAX_PHASE (180)
-#define AL_FLANGER_DEFAULT_PHASE (0)
-
-#define AL_FLANGER_MIN_RATE (0.0f)
-#define AL_FLANGER_MAX_RATE (10.0f)
-#define AL_FLANGER_DEFAULT_RATE (0.27f)
-
-#define AL_FLANGER_MIN_DEPTH (0.0f)
-#define AL_FLANGER_MAX_DEPTH (1.0f)
-#define AL_FLANGER_DEFAULT_DEPTH (1.0f)
-
-#define AL_FLANGER_MIN_FEEDBACK (-1.0f)
-#define AL_FLANGER_MAX_FEEDBACK (1.0f)
-#define AL_FLANGER_DEFAULT_FEEDBACK (-0.5f)
-
-#define AL_FLANGER_MIN_DELAY (0.0f)
-#define AL_FLANGER_MAX_DELAY (0.004f)
-#define AL_FLANGER_DEFAULT_DELAY (0.002f)
-
-/* Frequency shifter effect */
-#define AL_FREQUENCY_SHIFTER_MIN_FREQUENCY (0.0f)
-#define AL_FREQUENCY_SHIFTER_MAX_FREQUENCY (24000.0f)
-#define AL_FREQUENCY_SHIFTER_DEFAULT_FREQUENCY (0.0f)
-
-#define AL_FREQUENCY_SHIFTER_MIN_LEFT_DIRECTION (0)
-#define AL_FREQUENCY_SHIFTER_MAX_LEFT_DIRECTION (2)
-#define AL_FREQUENCY_SHIFTER_DEFAULT_LEFT_DIRECTION (0)
-
-#define AL_FREQUENCY_SHIFTER_DIRECTION_DOWN (0)
-#define AL_FREQUENCY_SHIFTER_DIRECTION_UP (1)
-#define AL_FREQUENCY_SHIFTER_DIRECTION_OFF (2)
-
-#define AL_FREQUENCY_SHIFTER_MIN_RIGHT_DIRECTION (0)
-#define AL_FREQUENCY_SHIFTER_MAX_RIGHT_DIRECTION (2)
-#define AL_FREQUENCY_SHIFTER_DEFAULT_RIGHT_DIRECTION (0)
-
-/* Vocal morpher effect */
-#define AL_VOCAL_MORPHER_MIN_PHONEMEA (0)
-#define AL_VOCAL_MORPHER_MAX_PHONEMEA (29)
-#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEA (0)
-
-#define AL_VOCAL_MORPHER_MIN_PHONEMEA_COARSE_TUNING (-24)
-#define AL_VOCAL_MORPHER_MAX_PHONEMEA_COARSE_TUNING (24)
-#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEA_COARSE_TUNING (0)
-
-#define AL_VOCAL_MORPHER_MIN_PHONEMEB (0)
-#define AL_VOCAL_MORPHER_MAX_PHONEMEB (29)
-#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEB (10)
-
-#define AL_VOCAL_MORPHER_MIN_PHONEMEB_COARSE_TUNING (-24)
-#define AL_VOCAL_MORPHER_MAX_PHONEMEB_COARSE_TUNING (24)
-#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEB_COARSE_TUNING (0)
-
-#define AL_VOCAL_MORPHER_PHONEME_A (0)
-#define AL_VOCAL_MORPHER_PHONEME_E (1)
-#define AL_VOCAL_MORPHER_PHONEME_I (2)
-#define AL_VOCAL_MORPHER_PHONEME_O (3)
-#define AL_VOCAL_MORPHER_PHONEME_U (4)
-#define AL_VOCAL_MORPHER_PHONEME_AA (5)
-#define AL_VOCAL_MORPHER_PHONEME_AE (6)
-#define AL_VOCAL_MORPHER_PHONEME_AH (7)
-#define AL_VOCAL_MORPHER_PHONEME_AO (8)
-#define AL_VOCAL_MORPHER_PHONEME_EH (9)
-#define AL_VOCAL_MORPHER_PHONEME_ER (10)
-#define AL_VOCAL_MORPHER_PHONEME_IH (11)
-#define AL_VOCAL_MORPHER_PHONEME_IY (12)
-#define AL_VOCAL_MORPHER_PHONEME_UH (13)
-#define AL_VOCAL_MORPHER_PHONEME_UW (14)
-#define AL_VOCAL_MORPHER_PHONEME_B (15)
-#define AL_VOCAL_MORPHER_PHONEME_D (16)
-#define AL_VOCAL_MORPHER_PHONEME_F (17)
-#define AL_VOCAL_MORPHER_PHONEME_G (18)
-#define AL_VOCAL_MORPHER_PHONEME_J (19)
-#define AL_VOCAL_MORPHER_PHONEME_K (20)
-#define AL_VOCAL_MORPHER_PHONEME_L (21)
-#define AL_VOCAL_MORPHER_PHONEME_M (22)
-#define AL_VOCAL_MORPHER_PHONEME_N (23)
-#define AL_VOCAL_MORPHER_PHONEME_P (24)
-#define AL_VOCAL_MORPHER_PHONEME_R (25)
-#define AL_VOCAL_MORPHER_PHONEME_S (26)
-#define AL_VOCAL_MORPHER_PHONEME_T (27)
-#define AL_VOCAL_MORPHER_PHONEME_V (28)
-#define AL_VOCAL_MORPHER_PHONEME_Z (29)
-
-#define AL_VOCAL_MORPHER_WAVEFORM_SINUSOID (0)
-#define AL_VOCAL_MORPHER_WAVEFORM_TRIANGLE (1)
-#define AL_VOCAL_MORPHER_WAVEFORM_SAWTOOTH (2)
-
-#define AL_VOCAL_MORPHER_MIN_WAVEFORM (0)
-#define AL_VOCAL_MORPHER_MAX_WAVEFORM (2)
-#define AL_VOCAL_MORPHER_DEFAULT_WAVEFORM (0)
-
-#define AL_VOCAL_MORPHER_MIN_RATE (0.0f)
-#define AL_VOCAL_MORPHER_MAX_RATE (10.0f)
-#define AL_VOCAL_MORPHER_DEFAULT_RATE (1.41f)
-
-/* Pitch shifter effect */
-#define AL_PITCH_SHIFTER_MIN_COARSE_TUNE (-12)
-#define AL_PITCH_SHIFTER_MAX_COARSE_TUNE (12)
-#define AL_PITCH_SHIFTER_DEFAULT_COARSE_TUNE (12)
-
-#define AL_PITCH_SHIFTER_MIN_FINE_TUNE (-50)
-#define AL_PITCH_SHIFTER_MAX_FINE_TUNE (50)
-#define AL_PITCH_SHIFTER_DEFAULT_FINE_TUNE (0)
-
-/* Ring modulator effect */
-#define AL_RING_MODULATOR_MIN_FREQUENCY (0.0f)
-#define AL_RING_MODULATOR_MAX_FREQUENCY (8000.0f)
-#define AL_RING_MODULATOR_DEFAULT_FREQUENCY (440.0f)
-
-#define AL_RING_MODULATOR_MIN_HIGHPASS_CUTOFF (0.0f)
-#define AL_RING_MODULATOR_MAX_HIGHPASS_CUTOFF (24000.0f)
-#define AL_RING_MODULATOR_DEFAULT_HIGHPASS_CUTOFF (800.0f)
-
-#define AL_RING_MODULATOR_SINUSOID (0)
-#define AL_RING_MODULATOR_SAWTOOTH (1)
-#define AL_RING_MODULATOR_SQUARE (2)
-
-#define AL_RING_MODULATOR_MIN_WAVEFORM (0)
-#define AL_RING_MODULATOR_MAX_WAVEFORM (2)
-#define AL_RING_MODULATOR_DEFAULT_WAVEFORM (0)
-
-/* Autowah effect */
-#define AL_AUTOWAH_MIN_ATTACK_TIME (0.0001f)
-#define AL_AUTOWAH_MAX_ATTACK_TIME (1.0f)
-#define AL_AUTOWAH_DEFAULT_ATTACK_TIME (0.06f)
-
-#define AL_AUTOWAH_MIN_RELEASE_TIME (0.0001f)
-#define AL_AUTOWAH_MAX_RELEASE_TIME (1.0f)
-#define AL_AUTOWAH_DEFAULT_RELEASE_TIME (0.06f)
-
-#define AL_AUTOWAH_MIN_RESONANCE (2.0f)
-#define AL_AUTOWAH_MAX_RESONANCE (1000.0f)
-#define AL_AUTOWAH_DEFAULT_RESONANCE (1000.0f)
-
-#define AL_AUTOWAH_MIN_PEAK_GAIN (0.00003f)
-#define AL_AUTOWAH_MAX_PEAK_GAIN (31621.0f)
-#define AL_AUTOWAH_DEFAULT_PEAK_GAIN (11.22f)
-
-/* Compressor effect */
-#define AL_COMPRESSOR_MIN_ONOFF (0)
-#define AL_COMPRESSOR_MAX_ONOFF (1)
-#define AL_COMPRESSOR_DEFAULT_ONOFF (1)
-
-/* Equalizer effect */
-#define AL_EQUALIZER_MIN_LOW_GAIN (0.126f)
-#define AL_EQUALIZER_MAX_LOW_GAIN (7.943f)
-#define AL_EQUALIZER_DEFAULT_LOW_GAIN (1.0f)
-
-#define AL_EQUALIZER_MIN_LOW_CUTOFF (50.0f)
-#define AL_EQUALIZER_MAX_LOW_CUTOFF (800.0f)
-#define AL_EQUALIZER_DEFAULT_LOW_CUTOFF (200.0f)
-
-#define AL_EQUALIZER_MIN_MID1_GAIN (0.126f)
-#define AL_EQUALIZER_MAX_MID1_GAIN (7.943f)
-#define AL_EQUALIZER_DEFAULT_MID1_GAIN (1.0f)
-
-#define AL_EQUALIZER_MIN_MID1_CENTER (200.0f)
-#define AL_EQUALIZER_MAX_MID1_CENTER (3000.0f)
-#define AL_EQUALIZER_DEFAULT_MID1_CENTER (500.0f)
-
-#define AL_EQUALIZER_MIN_MID1_WIDTH (0.01f)
-#define AL_EQUALIZER_MAX_MID1_WIDTH (1.0f)
-#define AL_EQUALIZER_DEFAULT_MID1_WIDTH (1.0f)
-
-#define AL_EQUALIZER_MIN_MID2_GAIN (0.126f)
-#define AL_EQUALIZER_MAX_MID2_GAIN (7.943f)
-#define AL_EQUALIZER_DEFAULT_MID2_GAIN (1.0f)
-
-#define AL_EQUALIZER_MIN_MID2_CENTER (1000.0f)
-#define AL_EQUALIZER_MAX_MID2_CENTER (8000.0f)
-#define AL_EQUALIZER_DEFAULT_MID2_CENTER (3000.0f)
-
-#define AL_EQUALIZER_MIN_MID2_WIDTH (0.01f)
-#define AL_EQUALIZER_MAX_MID2_WIDTH (1.0f)
-#define AL_EQUALIZER_DEFAULT_MID2_WIDTH (1.0f)
-
-#define AL_EQUALIZER_MIN_HIGH_GAIN (0.126f)
-#define AL_EQUALIZER_MAX_HIGH_GAIN (7.943f)
-#define AL_EQUALIZER_DEFAULT_HIGH_GAIN (1.0f)
-
-#define AL_EQUALIZER_MIN_HIGH_CUTOFF (4000.0f)
-#define AL_EQUALIZER_MAX_HIGH_CUTOFF (16000.0f)
-#define AL_EQUALIZER_DEFAULT_HIGH_CUTOFF (6000.0f)
-
-
-/* Source parameter value ranges and defaults. */
-#define AL_MIN_AIR_ABSORPTION_FACTOR (0.0f)
-#define AL_MAX_AIR_ABSORPTION_FACTOR (10.0f)
-#define AL_DEFAULT_AIR_ABSORPTION_FACTOR (0.0f)
-
-#define AL_MIN_ROOM_ROLLOFF_FACTOR (0.0f)
-#define AL_MAX_ROOM_ROLLOFF_FACTOR (10.0f)
-#define AL_DEFAULT_ROOM_ROLLOFF_FACTOR (0.0f)
-
-#define AL_MIN_CONE_OUTER_GAINHF (0.0f)
-#define AL_MAX_CONE_OUTER_GAINHF (1.0f)
-#define AL_DEFAULT_CONE_OUTER_GAINHF (1.0f)
-
-#define AL_MIN_DIRECT_FILTER_GAINHF_AUTO AL_FALSE
-#define AL_MAX_DIRECT_FILTER_GAINHF_AUTO AL_TRUE
-#define AL_DEFAULT_DIRECT_FILTER_GAINHF_AUTO AL_TRUE
-
-#define AL_MIN_AUXILIARY_SEND_FILTER_GAIN_AUTO AL_FALSE
-#define AL_MAX_AUXILIARY_SEND_FILTER_GAIN_AUTO AL_TRUE
-#define AL_DEFAULT_AUXILIARY_SEND_FILTER_GAIN_AUTO AL_TRUE
-
-#define AL_MIN_AUXILIARY_SEND_FILTER_GAINHF_AUTO AL_FALSE
-#define AL_MAX_AUXILIARY_SEND_FILTER_GAINHF_AUTO AL_TRUE
-#define AL_DEFAULT_AUXILIARY_SEND_FILTER_GAINHF_AUTO AL_TRUE
-
-
-/* Listener parameter value ranges and defaults. */
-#define AL_MIN_METERS_PER_UNIT FLT_MIN
-#define AL_MAX_METERS_PER_UNIT FLT_MAX
-#define AL_DEFAULT_METERS_PER_UNIT (1.0f)
-
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* AL_EFX_H */
diff --git a/project/vs2015/external/openal_soft/lib/win32/OpenAL32.dll b/project/vs2015/external/openal_soft/lib/win32/OpenAL32.dll
deleted file mode 100644
index 1e3bddd56..000000000
Binary files a/project/vs2015/external/openal_soft/lib/win32/OpenAL32.dll and /dev/null differ
diff --git a/project/vs2015/external/openal_soft/lib/win32/OpenAL32.lib b/project/vs2015/external/openal_soft/lib/win32/OpenAL32.lib
deleted file mode 100644
index 8bdca11eb..000000000
Binary files a/project/vs2015/external/openal_soft/lib/win32/OpenAL32.lib and /dev/null differ
diff --git a/project/vs2015/external/openal_soft/lib/win64/OpenAL32.dll b/project/vs2015/external/openal_soft/lib/win64/OpenAL32.dll
deleted file mode 100644
index e24538a5f..000000000
Binary files a/project/vs2015/external/openal_soft/lib/win64/OpenAL32.dll and /dev/null differ
diff --git a/project/vs2015/external/openal_soft/lib/win64/OpenAL32.lib b/project/vs2015/external/openal_soft/lib/win64/OpenAL32.lib
deleted file mode 100644
index 3d6e9abfa..000000000
Binary files a/project/vs2015/external/openal_soft/lib/win64/OpenAL32.lib and /dev/null differ
diff --git a/project/vs2015/raylib.sln b/project/vs2015/raylib.sln
index 0ac22f5ec..2ea3c9c24 100644
--- a/project/vs2015/raylib.sln
+++ b/project/vs2015/raylib.sln
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
-VisualStudioVersion = 14.0.25123.0
+VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_basic_window", "examples\core_basic_window.vcxproj", "{0981CA98-E4A5-4DF1-987F-A41D09131EFC}"
EndProject
@@ -13,20 +13,34 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{87
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug_DLL|x86 = Debug_DLL|x86
Debug|x86 = Debug|x86
+ Release_DLL|x86 = Release_DLL|x86
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug_DLL|x86.ActiveCfg = Debug_DLL|Win32
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug_DLL|x86.Build.0 = Debug_DLL|Win32
{0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug|x86.ActiveCfg = Debug|Win32
{0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug|x86.Build.0 = Debug|Win32
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release_DLL|x86.ActiveCfg = Release_DLL|Win32
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release_DLL|x86.Build.0 = Release_DLL|Win32
{0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release|x86.ActiveCfg = Release|Win32
{0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release|x86.Build.0 = Release|Win32
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug_DLL|x86.ActiveCfg = Debug_DLL|Win32
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug_DLL|x86.Build.0 = Debug_DLL|Win32
{E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug|x86.ActiveCfg = Debug|Win32
{E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug|x86.Build.0 = Debug|Win32
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release_DLL|x86.ActiveCfg = Release_DLL|Win32
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release_DLL|x86.Build.0 = Release_DLL|Win32
{E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release|x86.ActiveCfg = Release|Win32
{E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release|x86.Build.0 = Release|Win32
+ {B655E850-3322-42F7-941D-6AC18FD66CA1}.Debug_DLL|x86.ActiveCfg = Debug_DLL|Win32
+ {B655E850-3322-42F7-941D-6AC18FD66CA1}.Debug_DLL|x86.Build.0 = Debug_DLL|Win32
{B655E850-3322-42F7-941D-6AC18FD66CA1}.Debug|x86.ActiveCfg = Debug|Win32
{B655E850-3322-42F7-941D-6AC18FD66CA1}.Debug|x86.Build.0 = Debug|Win32
+ {B655E850-3322-42F7-941D-6AC18FD66CA1}.Release_DLL|x86.ActiveCfg = Release_DLL|Win32
+ {B655E850-3322-42F7-941D-6AC18FD66CA1}.Release_DLL|x86.Build.0 = Release_DLL|Win32
{B655E850-3322-42F7-941D-6AC18FD66CA1}.Release|x86.ActiveCfg = Release|Win32
{B655E850-3322-42F7-941D-6AC18FD66CA1}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
diff --git a/project/vs2015/raylib/build.bat b/project/vs2015/raylib/build.bat
deleted file mode 100644
index a00e8d1a9..000000000
--- a/project/vs2015/raylib/build.bat
+++ /dev/null
@@ -1,20 +0,0 @@
-@echo off
-set Libraries=glfw3.lib raylib.lib user32.lib gdi32.lib shell32.lib
-set CompilerFlags= /MD /Z7 /FC /nologo
-set LinkerFlags=-subsystem:Console
-set bits=x86
-set LibraryLocation=..\deps\lib\%bits%\
-
-for %%* in (.) do set CurrDirName=%%~nx*
-mkdir build > NUL 2> NUL
-pushd build
-IF NOT DEFINED vcvars_called (
- call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" %bits%
- set vcvars_called=1
-)
-REM xcopy %LibraryLocation%glfw3.dll > NUL 2> NUL
-ctime -begin %CurrDirName%.ctm
-cl %CompilerFlags% ..\code\main.cpp /I..\deps\include /link -incremental:no /LIBPATH:%LibraryLocation% %Libraries% %LinkerFlags% -out:main.exe
-set LastError=%ERRORLEVEL%
-ctime -end %CurrDirName%.ctm
-popd
\ No newline at end of file
diff --git a/project/vs2015/raylib/raylib.vcxproj b/project/vs2015/raylib/raylib.vcxproj
index 37e8b1837..97ce13e6d 100644
--- a/project/vs2015/raylib/raylib.vcxproj
+++ b/project/vs2015/raylib/raylib.vcxproj
@@ -1,10 +1,18 @@

+
+ Debug_DLL
+ Win32
+
Debug
Win32
+
+ Release_DLL
+ Win32
+
Release
Win32
@@ -23,6 +31,12 @@
v140
Unicode
+
+ DynamicLibrary
+ true
+ v140
+ Unicode
+
StaticLibrary
false
@@ -30,6 +44,13 @@
true
Unicode
+
+ DynamicLibrary
+ false
+ v140
+ true
+ Unicode
+
@@ -38,17 +59,30 @@
+
+
+
+
+
+
$(SolutionDir)$(ProjectName)\$(Configuration)\
+
+ $(SolutionDir)$(ProjectName)\$(Configuration)\
+
$(SolutionDir)$(ProjectName)\$(Configuration)\
$(SolutionDir)$(ProjectName)\$(Configuration)\temp
+
+ $(SolutionDir)$(ProjectName)\$(Configuration)\
+ $(SolutionDir)$(ProjectName)\$(Configuration)\temp
+
@@ -57,7 +91,26 @@
Disabled
WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP
CompileAsC
- $(SolutionDir)..\..\src\external\openal_soft\include;$(SolutionDir)..\..\src\external\glfw3\include;$(SolutionDir)..\..\src\external;%(AdditionalIncludeDirectories)
+ $(SolutionDir)..\..\src\external\glfw\include;$(SolutionDir)..\..\release\include
+ MultiThreadedDebug
+
+
+ Windows
+
+
+ %(AdditionalLibraryDirectories)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP;BUILD_LIBTYPE_SHARED
+ CompileAsC
+ $(SolutionDir)..\..\src\external\glfw\include;$(SolutionDir)..\..\release\include
+ MultiThreadedDebug
Windows
@@ -75,8 +128,28 @@
true
true
WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP
- $(SolutionDir)..\..\release\include;$(SolutionDir)..\..\src\external;%(AdditionalIncludeDirectories)
+ $(SolutionDir)..\..\src\external\glfw\include;$(SolutionDir)..\..\release\include
CompileAsC
+ MultiThreaded
+
+
+ Windows
+ true
+ true
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP;BUILD_LIBTYPE_SHARED
+ $(SolutionDir)..\..\src\external\glfw\include;$(SolutionDir)..\..\release\include
+ CompileAsC
+ MultiThreaded
Windows
@@ -90,8 +163,10 @@
+
+
diff --git a/project/vs2017.UWP/raylib.App.UWP/App.cpp b/project/vs2017.UWP/raylib.App.UWP/App.cpp
new file mode 100644
index 000000000..375b668c0
--- /dev/null
+++ b/project/vs2017.UWP/raylib.App.UWP/App.cpp
@@ -0,0 +1,558 @@
+#include "pch.h"
+#include "app.h"
+
+#include "raylib.h"
+
+using namespace Windows::ApplicationModel::Core;
+using namespace Windows::ApplicationModel::Activation;
+using namespace Windows::UI::Core;
+using namespace Windows::UI::Input;
+using namespace Windows::Devices::Input;
+using namespace Windows::Foundation;
+using namespace Windows::Foundation::Collections;
+using namespace Windows::Gaming::Input;
+using namespace Windows::Graphics::Display;
+using namespace Microsoft::WRL;
+using namespace Platform;
+
+using namespace raylibUWP;
+
+/*
+To-do list
+ - Cache reference to our CoreWindow?
+ - Implement gestures
+*/
+
+/* INPUT CODE */
+// Stand-ins for "core.c" variables
+#define MAX_GAMEPADS 4 // Max number of gamepads supported
+#define MAX_GAMEPAD_BUTTONS 32 // Max bumber of buttons supported (per gamepad)
+#define MAX_GAMEPAD_AXIS 8 // Max number of axis supported (per gamepad)
+static bool gamepadReady[MAX_GAMEPADS] = { false }; // Flag to know if gamepad is ready
+static float gamepadAxisState[MAX_GAMEPADS][MAX_GAMEPAD_AXIS]; // Gamepad axis state
+static char previousGamepadState[MAX_GAMEPADS][MAX_GAMEPAD_BUTTONS]; // Previous gamepad buttons state
+static char currentGamepadState[MAX_GAMEPADS][MAX_GAMEPAD_BUTTONS]; // Current gamepad buttons state
+
+static char previousKeyState[512] = { 0 }; // Contains previous frame keyboard state
+static char currentKeyState[512] = { 0 }; // Contains current frame keyboard state
+
+//...
+static char previousMouseState[3] = { 0 }; // Registers previous mouse button state
+static char currentMouseState[3] = { 0 }; // Registers current mouse button state
+static int previousMouseWheelY = 0; // Registers previous mouse wheel variation
+static int currentMouseWheelY = 0; // Registers current mouse wheel variation
+
+static bool cursorOnScreen = false; // Tracks if cursor is inside client area
+static bool cursorHidden = false; // Track if cursor is hidden
+
+static Vector2 mousePosition;
+static Vector2 mouseDelta; // NOTE: Added to keep track of mouse movement while the cursor is locked - no equivalent in "core.c"
+static bool toggleCursorLock;
+
+CoreCursor ^regularCursor = ref new CoreCursor(CoreCursorType::Arrow, 0); // The "visible arrow" cursor type
+
+// Helper to process key events
+void ProcessKeyEvent(Windows::System::VirtualKey key, int action)
+{
+ using Windows::System::VirtualKey;
+ switch (key)
+ {
+ case VirtualKey::Space: currentKeyState[KEY_SPACE] = action; break;
+ case VirtualKey::Escape: currentKeyState[KEY_ESCAPE] = action; break;
+ case VirtualKey::Enter: currentKeyState[KEY_ENTER] = action; break;
+ case VirtualKey::Delete: currentKeyState[KEY_BACKSPACE] = action; break;
+ case VirtualKey::Right: currentKeyState[KEY_RIGHT] = action; break;
+ case VirtualKey::Left: currentKeyState[KEY_LEFT] = action; break;
+ case VirtualKey::Down: currentKeyState[KEY_DOWN] = action; break;
+ case VirtualKey::Up: currentKeyState[KEY_UP] = action; break;
+ case VirtualKey::F1: currentKeyState[KEY_F1] = action; break;
+ case VirtualKey::F2: currentKeyState[KEY_F2] = action; break;
+ case VirtualKey::F3: currentKeyState[KEY_F4] = action; break;
+ case VirtualKey::F4: currentKeyState[KEY_F5] = action; break;
+ case VirtualKey::F5: currentKeyState[KEY_F6] = action; break;
+ case VirtualKey::F6: currentKeyState[KEY_F7] = action; break;
+ case VirtualKey::F7: currentKeyState[KEY_F8] = action; break;
+ case VirtualKey::F8: currentKeyState[KEY_F9] = action; break;
+ case VirtualKey::F9: currentKeyState[KEY_F10] = action; break;
+ case VirtualKey::F10: currentKeyState[KEY_F11] = action; break;
+ case VirtualKey::F11: currentKeyState[KEY_F12] = action; break;
+ case VirtualKey::LeftShift: currentKeyState[KEY_LEFT_SHIFT] = action; break;
+ case VirtualKey::LeftControl: currentKeyState[KEY_LEFT_CONTROL] = action; break;
+ case VirtualKey::LeftMenu: currentKeyState[KEY_LEFT_ALT] = action; break; // NOTE: Potential UWP bug with Alt key: https://social.msdn.microsoft.com/Forums/windowsapps/en-US/9bebfb0a-7637-400e-8bda-e55620091407/unexpected-behavior-in-windowscoreuicorephysicalkeystatusismenukeydown
+ case VirtualKey::RightShift: currentKeyState[KEY_RIGHT_SHIFT] = action; break;
+ case VirtualKey::RightControl: currentKeyState[KEY_RIGHT_CONTROL] = action; break;
+ case VirtualKey::RightMenu: currentKeyState[KEY_RIGHT_ALT] = action; break;
+ case VirtualKey::Number0: currentKeyState[KEY_ZERO] = action; break;
+ case VirtualKey::Number1: currentKeyState[KEY_ONE] = action; break;
+ case VirtualKey::Number2: currentKeyState[KEY_TWO] = action; break;
+ case VirtualKey::Number3: currentKeyState[KEY_THREE] = action; break;
+ case VirtualKey::Number4: currentKeyState[KEY_FOUR] = action; break;
+ case VirtualKey::Number5: currentKeyState[KEY_FIVE] = action; break;
+ case VirtualKey::Number6: currentKeyState[KEY_SIX] = action; break;
+ case VirtualKey::Number7: currentKeyState[KEY_SEVEN] = action; break;
+ case VirtualKey::Number8: currentKeyState[KEY_EIGHT] = action; break;
+ case VirtualKey::Number9: currentKeyState[KEY_NINE] = action; break;
+ case VirtualKey::A: currentKeyState[KEY_A] = action; break;
+ case VirtualKey::B: currentKeyState[KEY_B] = action; break;
+ case VirtualKey::C: currentKeyState[KEY_C] = action; break;
+ case VirtualKey::D: currentKeyState[KEY_D] = action; break;
+ case VirtualKey::E: currentKeyState[KEY_E] = action; break;
+ case VirtualKey::F: currentKeyState[KEY_F] = action; break;
+ case VirtualKey::G: currentKeyState[KEY_G] = action; break;
+ case VirtualKey::H: currentKeyState[KEY_H] = action; break;
+ case VirtualKey::I: currentKeyState[KEY_I] = action; break;
+ case VirtualKey::J: currentKeyState[KEY_J] = action; break;
+ case VirtualKey::K: currentKeyState[KEY_K] = action; break;
+ case VirtualKey::L: currentKeyState[KEY_L] = action; break;
+ case VirtualKey::M: currentKeyState[KEY_M] = action; break;
+ case VirtualKey::N: currentKeyState[KEY_N] = action; break;
+ case VirtualKey::O: currentKeyState[KEY_O] = action; break;
+ case VirtualKey::P: currentKeyState[KEY_P] = action; break;
+ case VirtualKey::Q: currentKeyState[KEY_Q] = action; break;
+ case VirtualKey::R: currentKeyState[KEY_R] = action; break;
+ case VirtualKey::S: currentKeyState[KEY_S] = action; break;
+ case VirtualKey::T: currentKeyState[KEY_T] = action; break;
+ case VirtualKey::U: currentKeyState[KEY_U] = action; break;
+ case VirtualKey::V: currentKeyState[KEY_V] = action; break;
+ case VirtualKey::W: currentKeyState[KEY_W] = action; break;
+ case VirtualKey::X: currentKeyState[KEY_X] = action; break;
+ case VirtualKey::Y: currentKeyState[KEY_Y] = action; break;
+ case VirtualKey::Z: currentKeyState[KEY_Z] = action; break;
+
+ }
+}
+
+/* CALLBACKS */
+void App::PointerPressed(CoreWindow^ window, PointerEventArgs^ args)
+{
+ if (args->CurrentPoint->Properties->IsLeftButtonPressed)
+ {
+ currentMouseState[MOUSE_LEFT_BUTTON] = 1;
+ }
+ if (args->CurrentPoint->Properties->IsRightButtonPressed)
+ {
+ currentMouseState[MOUSE_RIGHT_BUTTON] = 1;
+ }
+ if (args->CurrentPoint->Properties->IsMiddleButtonPressed)
+ {
+ currentMouseState[MOUSE_MIDDLE_BUTTON] = 1;
+ }
+}
+
+void App::PointerReleased(CoreWindow ^window, PointerEventArgs^ args)
+{
+ if (!(args->CurrentPoint->Properties->IsLeftButtonPressed))
+ {
+ currentMouseState[MOUSE_LEFT_BUTTON] = 0;
+ }
+ if (!(args->CurrentPoint->Properties->IsRightButtonPressed))
+ {
+ currentMouseState[MOUSE_RIGHT_BUTTON] = 0;
+ }
+ if (!(args->CurrentPoint->Properties->IsMiddleButtonPressed))
+ {
+ currentMouseState[MOUSE_MIDDLE_BUTTON] = 0;
+ }
+}
+
+void App::PointerWheelChanged(CoreWindow ^window, PointerEventArgs^ args)
+{
+ // TODO: Scale the MouseWheelDelta to match GLFW's mouse wheel sensitivity.
+ currentMouseWheelY += args->CurrentPoint->Properties->MouseWheelDelta;
+}
+
+void App::MouseMoved(Windows::Devices::Input::MouseDevice^ mouseDevice, Windows::Devices::Input::MouseEventArgs^ args)
+{
+ mouseDelta.x += args->MouseDelta.X;
+ mouseDelta.y += args->MouseDelta.Y;
+}
+
+void App::OnKeyDown(CoreWindow ^ sender, KeyEventArgs ^ args)
+{
+ ProcessKeyEvent(args->VirtualKey, 1);
+}
+
+void App::OnKeyUp(CoreWindow ^ sender, KeyEventArgs ^ args)
+{
+ ProcessKeyEvent(args->VirtualKey, 0);
+}
+
+/* REIMPLEMENTED FROM CORE.C */
+// Get one key state
+static bool GetKeyStatus(int key)
+{
+ return currentKeyState[key];
+}
+
+// Show mouse cursor
+void UWPShowCursor()
+{
+ CoreWindow::GetForCurrentThread()->PointerCursor = regularCursor;
+ cursorHidden = false;
+}
+
+// Hides mouse cursor
+void UWPHideCursor()
+{
+ CoreWindow::GetForCurrentThread()->PointerCursor = nullptr;
+ cursorHidden = true;
+}
+
+// Set mouse position XY
+void UWPSetMousePosition(Vector2 position)
+{
+ CoreWindow ^window = CoreWindow::GetForCurrentThread();
+ Point mousePosScreen = Point(position.x + window->Bounds.X, position.y + window->Bounds.Y);
+ window->PointerPosition = mousePosScreen;
+ mousePosition = position;
+}
+// Enables cursor (unlock cursor)
+void UWPEnableCursor()
+{
+ UWPShowCursor();
+ UWPSetMousePosition(mousePosition); // The mouse is hidden in the center of the screen - move it to where it should appear
+ toggleCursorLock = false;
+}
+
+// Disables cursor (lock cursor)
+void UWPDisableCursor()
+{
+ UWPHideCursor();
+ toggleCursorLock = true;
+}
+
+// Get one mouse button state
+static bool UWPGetMouseButtonStatus(int button)
+{
+ return currentMouseState[button];
+}
+
+// Poll (store) all input events
+void UWP_PollInput()
+{
+ // Register previous keyboard state
+ for (int k = 0; k < 512; k++) previousKeyState[k] = currentKeyState[k];
+
+ // Process Mouse
+ {
+ // Register previous mouse states
+ for (int i = 0; i < 3; i++) previousMouseState[i] = currentMouseState[i];
+ previousMouseWheelY = currentMouseWheelY;
+ currentMouseWheelY = 0;
+
+ CoreWindow ^window = CoreWindow::GetForCurrentThread();
+ if (toggleCursorLock)
+ {
+ // Track cursor movement delta, recenter it on the client
+ mousePosition.x += mouseDelta.x;
+ mousePosition.y += mouseDelta.y;
+
+ // Why we're not using UWPSetMousePosition here...
+ // UWPSetMousePosition changes the "mousePosition" variable to match where the cursor actually is.
+ // Our cursor is locked to the middle of screen, and we don't want that reflected in "mousePosition"
+ Vector2 centerClient = { (float)(GetScreenWidth() / 2), (float)(GetScreenHeight() / 2) };
+ window->PointerPosition = Point(centerClient.x + window->Bounds.X, centerClient.y + window->Bounds.Y);
+ }
+ else
+ {
+ // Record the cursor's position relative to the client
+ mousePosition.x = window->PointerPosition.X - window->Bounds.X;
+ mousePosition.y = window->PointerPosition.Y - window->Bounds.Y;
+ }
+
+ mouseDelta = { 0 ,0 };
+ }
+
+ // Process Gamepads
+ {
+ // Check if gamepads are ready
+ for (int i = 0; i < MAX_GAMEPADS; i++)
+ {
+ // HACK: UWP keeps a contiguous list of gamepads. For the interest of time I'm just doing a 1:1 mapping of
+ // connected gamepads with their spot in the list, but this has serious robustness problems
+ // e.g. player 1, 2, and 3 are playing a game - if player2 disconnects, p3's controller would now be mapped to p2's character since p3 is now second in the list.
+
+ gamepadReady[i] = (i < Gamepad::Gamepads->Size);
+ }
+
+ // Get current gamepad state
+ for (int i = 0; i < MAX_GAMEPADS; i++)
+ {
+ if (gamepadReady[i])
+ {
+ // Register previous gamepad states
+ for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) previousGamepadState[i][k] = currentGamepadState[i][k];
+
+ // Get current gamepad state
+ auto gamepad = Gamepad::Gamepads->GetAt(i);
+ GamepadReading reading = gamepad->GetCurrentReading();
+
+ // NOTE: Maybe it would be wiser to redefine the gamepad button mappings in "raylib.h" for the UWP platform instead of remapping them manually
+ currentGamepadState[i][GAMEPAD_XBOX_BUTTON_A] = ((reading.Buttons & GamepadButtons::A) == GamepadButtons::A);
+ currentGamepadState[i][GAMEPAD_XBOX_BUTTON_B] = ((reading.Buttons & GamepadButtons::B) == GamepadButtons::B);
+ currentGamepadState[i][GAMEPAD_XBOX_BUTTON_X] = ((reading.Buttons & GamepadButtons::X) == GamepadButtons::X);
+ currentGamepadState[i][GAMEPAD_XBOX_BUTTON_Y] = ((reading.Buttons & GamepadButtons::Y) == GamepadButtons::Y);
+ currentGamepadState[i][GAMEPAD_XBOX_BUTTON_LB] = ((reading.Buttons & GamepadButtons::LeftShoulder) == GamepadButtons::LeftShoulder);
+ currentGamepadState[i][GAMEPAD_XBOX_BUTTON_RB] = ((reading.Buttons & GamepadButtons::RightShoulder) == GamepadButtons::RightShoulder);
+ currentGamepadState[i][GAMEPAD_XBOX_BUTTON_SELECT] = ((reading.Buttons & GamepadButtons::View) == GamepadButtons::View); // Changed for XB1 Controller
+ currentGamepadState[i][GAMEPAD_XBOX_BUTTON_START] = ((reading.Buttons & GamepadButtons::Menu) == GamepadButtons::Menu); // Changed for XB1 Controller
+ currentGamepadState[i][GAMEPAD_XBOX_BUTTON_UP] = ((reading.Buttons & GamepadButtons::DPadUp) == GamepadButtons::DPadUp);
+ currentGamepadState[i][GAMEPAD_XBOX_BUTTON_RIGHT] = ((reading.Buttons & GamepadButtons::DPadRight) == GamepadButtons::DPadRight);
+ currentGamepadState[i][GAMEPAD_XBOX_BUTTON_DOWN] = ((reading.Buttons & GamepadButtons::DPadLeft) == GamepadButtons::DPadDown);
+ currentGamepadState[i][GAMEPAD_XBOX_BUTTON_LEFT] = ((reading.Buttons & GamepadButtons::DPadDown) == GamepadButtons::DPadLeft);
+ currentGamepadState[i][GAMEPAD_XBOX_BUTTON_HOME] = false; // Home button not supported by UWP
+
+ // Get current axis state
+ gamepadAxisState[i][GAMEPAD_XBOX_AXIS_LEFT_X] = reading.LeftThumbstickX;
+ gamepadAxisState[i][GAMEPAD_XBOX_AXIS_LEFT_Y] = reading.LeftThumbstickY;
+ gamepadAxisState[i][GAMEPAD_XBOX_AXIS_RIGHT_X] = reading.RightThumbstickX;
+ gamepadAxisState[i][GAMEPAD_XBOX_AXIS_RIGHT_Y] = reading.RightThumbstickY;
+ gamepadAxisState[i][GAMEPAD_XBOX_AXIS_LT] = reading.LeftTrigger;
+ gamepadAxisState[i][GAMEPAD_XBOX_AXIS_RT] = reading.RightTrigger;
+ }
+ }
+ }
+
+}
+
+// The following functions were ripped from core.c and have *no additional work done on them*
+// Detect if a key has been pressed once
+bool UWPIsKeyPressed(int key)
+{
+ bool pressed = false;
+
+ if ((currentKeyState[key] != previousKeyState[key]) && (currentKeyState[key] == 1))
+ pressed = true;
+ else pressed = false;
+
+ return pressed;
+}
+
+// Detect if a key is being pressed (key held down)
+bool UWPIsKeyDown(int key)
+{
+ if (GetKeyStatus(key) == 1) return true;
+ else return false;
+}
+
+// Detect if a key has been released once
+bool UWPIsKeyReleased(int key)
+{
+ bool released = false;
+
+ if ((currentKeyState[key] != previousKeyState[key]) && (currentKeyState[key] == 0)) released = true;
+ else released = false;
+
+ return released;
+}
+
+// Detect if a key is NOT being pressed (key not held down)
+bool UWPIsKeyUp(int key)
+{
+ if (GetKeyStatus(key) == 0) return true;
+ else return false;
+}
+
+/* OTHER CODE */
+
+// Helper to convert a length in device-independent pixels (DIPs) to a length in physical pixels.
+inline float ConvertDipsToPixels(float dips, float dpi)
+{
+ static const float dipsPerInch = 96.0f;
+ return floor(dips * dpi / dipsPerInch + 0.5f); // Round to nearest integer.
+}
+
+// Implementation of the IFrameworkViewSource interface, necessary to run our app.
+ref class SimpleApplicationSource sealed : Windows::ApplicationModel::Core::IFrameworkViewSource
+{
+public:
+ virtual Windows::ApplicationModel::Core::IFrameworkView^ CreateView()
+ {
+ return ref new App();
+ }
+};
+
+// The main function creates an IFrameworkViewSource for our app, and runs the app.
+[Platform::MTAThread]
+int main(Platform::Array^)
+{
+ auto simpleApplicationSource = ref new SimpleApplicationSource();
+ CoreApplication::Run(simpleApplicationSource);
+
+ return 0;
+}
+
+App::App() :
+ mWindowClosed(false),
+ mWindowVisible(true)
+{
+}
+
+// The first method called when the IFrameworkView is being created.
+void App::Initialize(CoreApplicationView^ applicationView)
+{
+ // Register event handlers for app lifecycle. This example includes Activated, so that we
+ // can make the CoreWindow active and start rendering on the window.
+ applicationView->Activated += ref new TypedEventHandler(this, &App::OnActivated);
+
+ // Logic for other event handlers could go here.
+ // Information about the Suspending and Resuming event handlers can be found here:
+ // http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh994930.aspx
+
+ CoreApplication::Resuming += ref new EventHandler(this, &App::OnResuming);
+}
+
+// Called when the CoreWindow object is created (or re-created).
+void App::SetWindow(CoreWindow^ window)
+{
+ window->SizeChanged += ref new TypedEventHandler(this, &App::OnWindowSizeChanged);
+ window->VisibilityChanged += ref new TypedEventHandler(this, &App::OnVisibilityChanged);
+ window->Closed += ref new TypedEventHandler(this, &App::OnWindowClosed);
+
+ window->PointerPressed += ref new TypedEventHandler(this, &App::PointerPressed);
+ window->PointerReleased += ref new TypedEventHandler(this, &App::PointerReleased);
+ window->PointerWheelChanged += ref new TypedEventHandler(this, &App::PointerWheelChanged);
+ window->KeyDown += ref new TypedEventHandler(this, &App::OnKeyDown);
+ window->KeyUp += ref new TypedEventHandler(this, &App::OnKeyUp);
+
+ Windows::Devices::Input::MouseDevice::GetForCurrentView()->MouseMoved += ref new TypedEventHandler(this, &App::MouseMoved);
+
+ DisplayInformation^ currentDisplayInformation = DisplayInformation::GetForCurrentView();
+ currentDisplayInformation->DpiChanged += ref new TypedEventHandler(this, &App::OnDpiChanged);
+ currentDisplayInformation->OrientationChanged += ref new TypedEventHandler(this, &App::OnOrientationChanged);
+
+ // The CoreWindow has been created, so EGL can be initialized.
+ InitWindow(800, 450, (EGLNativeWindowType)window);
+}
+
+// Initializes scene resources
+void App::Load(Platform::String^ entryPoint)
+{
+ // InitWindow() --> rlglInit()
+}
+
+static int posX = 100;
+static int posY = 100;
+static int time = 0;
+// This method is called after the window becomes active.
+void App::Run()
+{
+ while (!mWindowClosed)
+ {
+ if (mWindowVisible)
+ {
+ // Draw
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+
+ posX += gamepadAxisState[GAMEPAD_PLAYER1][GAMEPAD_XBOX_AXIS_LEFT_X] * 5;
+ posY += gamepadAxisState[GAMEPAD_PLAYER1][GAMEPAD_XBOX_AXIS_LEFT_Y] * -5;
+ DrawRectangle(posX, posY, 400, 100, RED);
+
+ DrawLine(0, 0, GetScreenWidth(), GetScreenHeight(), BLUE);
+
+ DrawCircle(mousePosition.x, mousePosition.y, 40, BLUE);
+
+ if(UWPIsKeyDown(KEY_S))
+ {
+ DrawCircle(100, 100, 100, BLUE);
+ }
+
+ if(UWPIsKeyPressed(KEY_A))
+ {
+ posX -= 50;
+ UWPEnableCursor();
+ }
+ if (UWPIsKeyPressed(KEY_D))
+ {
+ posX += 50;
+
+ UWPDisableCursor();
+ }
+
+ if(currentKeyState[KEY_LEFT_ALT])
+ DrawRectangle(250, 250, 20, 20, BLACK);
+ if (currentKeyState[KEY_BACKSPACE])
+ DrawRectangle(280, 250, 20, 20, BLACK);
+
+ if (currentMouseState[MOUSE_LEFT_BUTTON])
+ DrawRectangle(280, 250, 20, 20, BLACK);
+
+ static int pos = 0;
+ pos -= currentMouseWheelY;
+ DrawRectangle(280, pos + 50, 20, 20, BLACK);
+
+ DrawRectangle(250, 280 + (time++ % 60), 10, 10, PURPLE);
+
+ EndDrawing();
+ UWP_PollInput();
+
+ CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
+ }
+ else
+ {
+ CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
+ }
+ }
+
+ CloseWindow();
+}
+
+// Terminate events do not cause Uninitialize to be called. It will be called if your IFrameworkView
+// class is torn down while the app is in the foreground.
+void App::Uninitialize()
+{
+ // CloseWindow();
+}
+
+// Application lifecycle event handler.
+void App::OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args)
+{
+ // Run() won't start until the CoreWindow is activated.
+ CoreWindow::GetForCurrentThread()->Activate();
+}
+
+void App::OnResuming(Object^ sender, Object^ args)
+{
+ // Restore any data or state that was unloaded on suspend. By default, data
+ // and state are persisted when resuming from suspend. Note that this event
+ // does not occur if the app was previously terminated.
+}
+
+void App::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args)
+{
+ // TODO: Update window and render area size
+ //m_deviceResources->SetLogicalSize(Size(sender->Bounds.Width, sender->Bounds.Height));
+ //m_main->UpdateForWindowSizeChange();
+}
+
+// Window event handlers.
+void App::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args)
+{
+ mWindowVisible = args->Visible;
+
+ // raylib core has the variable windowMinimized to register state,
+ // it should be modifyed by this event...
+}
+
+void App::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args)
+{
+ mWindowClosed = true;
+
+ // raylib core has the variable windowShouldClose to register state,
+ // it should be modifyed by this event...
+}
+
+void App::OnDpiChanged(DisplayInformation^ sender, Object^ args)
+{
+ //m_deviceResources->SetDpi(sender->LogicalDpi);
+ //m_main->UpdateForWindowSizeChange();
+}
+
+void App::OnOrientationChanged(DisplayInformation^ sender, Object^ args)
+{
+ //m_deviceResources->SetCurrentOrientation(sender->CurrentOrientation);
+ //m_main->UpdateForWindowSizeChange();
+}
diff --git a/project/vs2017.UWP/raylib.App.UWP/App.h b/project/vs2017.UWP/raylib.App.UWP/App.h
new file mode 100644
index 000000000..5b58528ba
--- /dev/null
+++ b/project/vs2017.UWP/raylib.App.UWP/App.h
@@ -0,0 +1,49 @@
+#pragma once
+
+#include
+
+#include "pch.h"
+
+namespace raylibUWP
+{
+ ref class App sealed : public Windows::ApplicationModel::Core::IFrameworkView
+ {
+ public:
+ App();
+
+ // IFrameworkView Methods.
+ virtual void Initialize(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView);
+ virtual void SetWindow(Windows::UI::Core::CoreWindow^ window);
+ virtual void Load(Platform::String^ entryPoint);
+ virtual void Run();
+ virtual void Uninitialize();
+
+ protected:
+
+ // Application lifecycle event handlers.
+ void OnActivated(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView, Windows::ApplicationModel::Activation::IActivatedEventArgs^ args);
+ void OnResuming(Platform::Object^ sender, Platform::Object^ args);
+
+ // Window event handlers.
+ void OnWindowSizeChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ args);
+ void OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args);
+ void OnWindowClosed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CoreWindowEventArgs^ args);
+
+ // DisplayInformation event handlers.
+ void OnDpiChanged(Windows::Graphics::Display::DisplayInformation^ sender, Platform::Object^ args);
+ void OnOrientationChanged(Windows::Graphics::Display::DisplayInformation^ sender, Platform::Object^ args);
+
+ // Input event handlers
+ void PointerPressed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
+ void PointerReleased(Windows::UI::Core::CoreWindow ^sender, Windows::UI::Core::PointerEventArgs^ args);
+ void PointerWheelChanged(Windows::UI::Core::CoreWindow ^sender, Windows::UI::Core::PointerEventArgs^ args);
+ void MouseMoved(Windows::Devices::Input::MouseDevice^ mouseDevice, Windows::Devices::Input::MouseEventArgs^ args);
+ void OnKeyDown(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::KeyEventArgs ^ args);
+ void OnKeyUp(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::KeyEventArgs ^ args);
+
+ private:
+
+ bool mWindowClosed;
+ bool mWindowVisible;
+ };
+}
diff --git a/project/vs2017.UWP/raylib.App.UWP/Assets/Logo.scale-100.png b/project/vs2017.UWP/raylib.App.UWP/Assets/Logo.scale-100.png
new file mode 100644
index 000000000..e26771cb3
Binary files /dev/null and b/project/vs2017.UWP/raylib.App.UWP/Assets/Logo.scale-100.png differ
diff --git a/project/vs2017.UWP/raylib.App.UWP/Assets/SmallLogo.scale-100.png b/project/vs2017.UWP/raylib.App.UWP/Assets/SmallLogo.scale-100.png
new file mode 100644
index 000000000..1eb0d9d52
Binary files /dev/null and b/project/vs2017.UWP/raylib.App.UWP/Assets/SmallLogo.scale-100.png differ
diff --git a/project/vs2017.UWP/raylib.App.UWP/Assets/SplashScreen.scale-100.png b/project/vs2017.UWP/raylib.App.UWP/Assets/SplashScreen.scale-100.png
new file mode 100644
index 000000000..c951e031b
Binary files /dev/null and b/project/vs2017.UWP/raylib.App.UWP/Assets/SplashScreen.scale-100.png differ
diff --git a/project/vs2017.UWP/raylib.App.UWP/Assets/StoreLogo.scale-100.png b/project/vs2017.UWP/raylib.App.UWP/Assets/StoreLogo.scale-100.png
new file mode 100644
index 000000000..dcb672712
Binary files /dev/null and b/project/vs2017.UWP/raylib.App.UWP/Assets/StoreLogo.scale-100.png differ
diff --git a/project/vs2017.UWP/raylib.App.UWP/Assets/WideLogo.scale-100.png b/project/vs2017.UWP/raylib.App.UWP/Assets/WideLogo.scale-100.png
new file mode 100644
index 000000000..9dd94b628
Binary files /dev/null and b/project/vs2017.UWP/raylib.App.UWP/Assets/WideLogo.scale-100.png differ
diff --git a/project/vs2017.UWP/raylib.App.UWP/Package.appxmanifest b/project/vs2017.UWP/raylib.App.UWP/Package.appxmanifest
new file mode 100644
index 000000000..f0f568628
--- /dev/null
+++ b/project/vs2017.UWP/raylib.App.UWP/Package.appxmanifest
@@ -0,0 +1,26 @@
+
+
+
+
+
+ raylibUWP
+ Alumno
+ Assets\StoreLogo.png
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/project/vs2017.UWP/raylib.App.UWP/packages.config b/project/vs2017.UWP/raylib.App.UWP/packages.config
new file mode 100644
index 000000000..70c3dea0e
--- /dev/null
+++ b/project/vs2017.UWP/raylib.App.UWP/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/project/vs2017.UWP/raylib.App.UWP/pch.cpp b/project/vs2017.UWP/raylib.App.UWP/pch.cpp
new file mode 100644
index 000000000..bcb5590be
--- /dev/null
+++ b/project/vs2017.UWP/raylib.App.UWP/pch.cpp
@@ -0,0 +1 @@
+#include "pch.h"
diff --git a/project/vs2017.UWP/raylib.App.UWP/pch.h b/project/vs2017.UWP/raylib.App.UWP/pch.h
new file mode 100644
index 000000000..dcbd23785
--- /dev/null
+++ b/project/vs2017.UWP/raylib.App.UWP/pch.h
@@ -0,0 +1,16 @@
+#pragma once
+
+#include
+#include
+
+// OpenGL ES includes
+#include
+#include
+
+// EGL includes
+#include
+#include
+#include
+
+// ANGLE include for Windows Store
+#include
\ No newline at end of file
diff --git a/project/vs2017.UWP/raylib.App.UWP/raylib.App.UWP.TemporaryKey.pfx b/project/vs2017.UWP/raylib.App.UWP/raylib.App.UWP.TemporaryKey.pfx
new file mode 100644
index 000000000..0ada3be01
Binary files /dev/null and b/project/vs2017.UWP/raylib.App.UWP/raylib.App.UWP.TemporaryKey.pfx differ
diff --git a/project/vs2017.UWP/raylib.App.UWP/raylib.App.UWP.filters b/project/vs2017.UWP/raylib.App.UWP/raylib.App.UWP.filters
new file mode 100644
index 000000000..4e83c9790
--- /dev/null
+++ b/project/vs2017.UWP/raylib.App.UWP/raylib.App.UWP.filters
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ Assets
+
+
+ Assets
+
+
+ Assets
+
+
+ Assets
+
+
+ Assets
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {d16954bb-de54-472b-ac10-ecab10d3fdc8}
+
+
+
\ No newline at end of file
diff --git a/project/vs2017.UWP/raylib.App.UWP/raylib.App.UWP.user b/project/vs2017.UWP/raylib.App.UWP/raylib.App.UWP.user
new file mode 100644
index 000000000..abe8dd896
--- /dev/null
+++ b/project/vs2017.UWP/raylib.App.UWP/raylib.App.UWP.user
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/project/vs2017/examples/core_basic_window.vcxproj b/project/vs2017/examples/core_basic_window.vcxproj
new file mode 100644
index 000000000..7b4d4a8cd
--- /dev/null
+++ b/project/vs2017/examples/core_basic_window.vcxproj
@@ -0,0 +1,182 @@
+
+
+
+
+ Debug_DLL
+ Win32
+
+
+ Debug
+ Win32
+
+
+ Release_DLL
+ Win32
+
+
+ Release
+ Win32
+
+
+
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}
+ Win32Proj
+ core_basic_window
+ 10.0.14393.0
+ core_basic_window
+
+
+
+ Application
+ true
+ v141
+ Unicode
+
+
+ Application
+ true
+ v141
+ Unicode
+
+
+ Application
+ false
+ v141
+ true
+ Unicode
+
+
+ Application
+ false
+ v141
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(ProjectDir)$(ProjectName)\$(Configuration)\
+ $(ProjectDir)$(ProjectName)\$(Configuration)\temp
+
+
+ true
+ $(ProjectDir)$(ProjectName)\$(Configuration)\
+ $(ProjectDir)$(ProjectName)\$(Configuration)\temp
+
+
+ false
+ $(ProjectDir)$(ProjectName)\$(Configuration)\
+ $(ProjectDir)$(ProjectName)\$(Configuration)\temp
+
+
+ false
+ $(ProjectDir)$(ProjectName)\$(Configuration)\
+ $(ProjectDir)$(ProjectName)\$(Configuration)\temp
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\release\include;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ %(AdditionalLibraryDirectories)
+ kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\release\include;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ %(AdditionalLibraryDirectories)
+ kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\release\include;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ %(AdditionalLibraryDirectories)
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\release\include;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ %(AdditionalLibraryDirectories)
+
+
+
+
+
+
+
+ {e89d61ac-55de-4482-afd4-df7242ebc859}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/project/vs2017/examples/core_basic_window_cpp.vcxproj b/project/vs2017/examples/core_basic_window_cpp.vcxproj
new file mode 100644
index 000000000..a015690cd
--- /dev/null
+++ b/project/vs2017/examples/core_basic_window_cpp.vcxproj
@@ -0,0 +1,180 @@
+
+
+
+
+ Debug_DLL
+ Win32
+
+
+ Debug
+ Win32
+
+
+ Release_DLL
+ Win32
+
+
+ Release
+ Win32
+
+
+
+ {B655E850-3322-42F7-941D-6AC18FD66CA1}
+ Win32Proj
+ raylib_example_cpp
+ 10.0.14393.0
+ core_basic_window_cpp
+
+
+
+ Application
+ true
+ v141
+ Unicode
+
+
+ Application
+ true
+ v141
+ Unicode
+
+
+ Application
+ false
+ v141
+ true
+ Unicode
+
+
+ Application
+ false
+ v141
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(ProjectDir)$(ProjectName)\$(Configuration)
+ $(ProjectDir)$(ProjectName)\$(Configuration)\temp
+
+
+ true
+ $(ProjectDir)$(ProjectName)\$(Configuration)
+ $(ProjectDir)$(ProjectName)\$(Configuration)\temp
+
+
+ false
+ $(ProjectDir)$(ProjectName)\$(Configuration)
+ $(ProjectDir)$(ProjectName)\$(Configuration)\temp
+
+
+ false
+ $(ProjectDir)$(ProjectName)\$(Configuration)
+ $(ProjectDir)$(ProjectName)\$(Configuration)\temp
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ $(SolutionDir)..\..\release\include;%(AdditionalIncludeDirectories)
+ CompileAsCpp
+
+
+ Console
+ true
+ kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)..\..\release\libs\win32\msvc;%(AdditionalLibraryDirectories)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ $(SolutionDir)..\..\release\include;%(AdditionalIncludeDirectories)
+ CompileAsCpp
+
+
+ Console
+ true
+ kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)..\..\release\libs\win32\msvc;%(AdditionalLibraryDirectories)
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ CompileAsCpp
+ $(SolutionDir)..\..\release\include;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ true
+ true
+ $(SolutionDir)..\..\release\libs\win32\msvc;%(AdditionalLibraryDirectories)
+ kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ CompileAsCpp
+ $(SolutionDir)..\..\release\include;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ true
+ true
+ %(AdditionalLibraryDirectories)
+ kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+ {e89d61ac-55de-4482-afd4-df7242ebc859}
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/project/vs2017/raylib.sln b/project/vs2017/raylib.sln
new file mode 100644
index 000000000..77378c847
--- /dev/null
+++ b/project/vs2017/raylib.sln
@@ -0,0 +1,57 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.27130.2024
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_basic_window", "examples\core_basic_window.vcxproj", "{0981CA98-E4A5-4DF1-987F-A41D09131EFC}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "raylib", "raylib\raylib.vcxproj", "{E89D61AC-55DE-4482-AFD4-DF7242EBC859}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_basic_window_cpp", "examples\core_basic_window_cpp.vcxproj", "{B655E850-3322-42F7-941D-6AC18FD66CA1}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug_DLL|x86 = Debug_DLL|x86
+ Debug|x86 = Debug|x86
+ Release_DLL|x86 = Release_DLL|x86
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug_DLL|x86.ActiveCfg = Debug_DLL|Win32
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug_DLL|x86.Build.0 = Debug_DLL|Win32
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug|x86.ActiveCfg = Debug|Win32
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug|x86.Build.0 = Debug|Win32
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release_DLL|x86.ActiveCfg = Release_DLL|Win32
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release_DLL|x86.Build.0 = Release_DLL|Win32
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release|x86.ActiveCfg = Release|Win32
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release|x86.Build.0 = Release|Win32
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug_DLL|x86.ActiveCfg = Debug_DLL|Win32
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug_DLL|x86.Build.0 = Debug_DLL|Win32
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug|x86.ActiveCfg = Debug|Win32
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug|x86.Build.0 = Debug|Win32
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release_DLL|x86.ActiveCfg = Release_DLL|Win32
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release_DLL|x86.Build.0 = Release_DLL|Win32
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release|x86.ActiveCfg = Release|Win32
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release|x86.Build.0 = Release|Win32
+ {B655E850-3322-42F7-941D-6AC18FD66CA1}.Debug_DLL|x86.ActiveCfg = Debug_DLL|Win32
+ {B655E850-3322-42F7-941D-6AC18FD66CA1}.Debug_DLL|x86.Build.0 = Debug_DLL|Win32
+ {B655E850-3322-42F7-941D-6AC18FD66CA1}.Debug|x86.ActiveCfg = Debug|Win32
+ {B655E850-3322-42F7-941D-6AC18FD66CA1}.Debug|x86.Build.0 = Debug|Win32
+ {B655E850-3322-42F7-941D-6AC18FD66CA1}.Release_DLL|x86.ActiveCfg = Release_DLL|Win32
+ {B655E850-3322-42F7-941D-6AC18FD66CA1}.Release_DLL|x86.Build.0 = Release_DLL|Win32
+ {B655E850-3322-42F7-941D-6AC18FD66CA1}.Release|x86.ActiveCfg = Release|Win32
+ {B655E850-3322-42F7-941D-6AC18FD66CA1}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1}
+ {B655E850-3322-42F7-941D-6AC18FD66CA1} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29}
+ EndGlobalSection
+EndGlobal
diff --git a/project/vs2017/raylib/raylib.vcxproj b/project/vs2017/raylib/raylib.vcxproj
new file mode 100644
index 000000000..582067933
--- /dev/null
+++ b/project/vs2017/raylib/raylib.vcxproj
@@ -0,0 +1,197 @@
+
+
+
+
+ Debug_DLL
+ Win32
+
+
+ Debug
+ Win32
+
+
+ Release_DLL
+ Win32
+
+
+ Release
+ Win32
+
+
+
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}
+ Win32Proj
+ raylib
+ 10.0.14393.0
+
+
+
+ StaticLibrary
+ true
+ v141
+ Unicode
+
+
+ DynamicLibrary
+ true
+ v141
+ Unicode
+
+
+ StaticLibrary
+ false
+ v141
+ true
+ Unicode
+
+
+ DynamicLibrary
+ false
+ v141
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(SolutionDir)$(ProjectName)\$(Configuration)\
+
+
+ $(SolutionDir)$(ProjectName)\$(Configuration)\
+
+
+ $(SolutionDir)$(ProjectName)\$(Configuration)\
+ $(SolutionDir)$(ProjectName)\$(Configuration)\temp
+
+
+ $(SolutionDir)$(ProjectName)\$(Configuration)\
+ $(SolutionDir)$(ProjectName)\$(Configuration)\temp
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP
+ CompileAsC
+ $(SolutionDir)..\..\release\include;$(SolutionDir)..\..\src\external\glfw\include
+
+
+ Windows
+
+
+ %(AdditionalLibraryDirectories)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP;BUILD_LIBTYPE_SHARED
+ CompileAsC
+ $(SolutionDir)..\..\release\include;$(SolutionDir)..\..\src\external\glfw\include
+ MultiThreadedDebug
+
+
+ Windows
+
+
+ %(AdditionalLibraryDirectories)
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP
+ $(SolutionDir)..\..\release\include;$(SolutionDir)..\..\src\external\glfw\include
+ CompileAsC
+
+
+ Windows
+ true
+ true
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP;BUILD_LIBTYPE_SHARED
+ $(SolutionDir)..\..\release\include;$(SolutionDir)..\..\src\external\glfw\include
+ CompileAsC
+ MultiThreaded
+
+
+ Windows
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/raylib.pc.in b/raylib.pc.in
new file mode 100644
index 000000000..d71a5e2ce
--- /dev/null
+++ b/raylib.pc.in
@@ -0,0 +1,13 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: raylib
+Description: Simple and easy-to-use library to learn videogames programming
+URL: http://github.com/raysan5/raylib
+Version: @PROJECT_VERSION@
+Libs: -L${libdir} -lraylib
+Libs.private: @PKG_CONFIG_LIBS_PRIVATE@
+Requires.private:
+Cflags: -I${includedir}
diff --git a/release/README.md b/release/README.md
index 7189365b8..3c5c7a6e9 100644
--- a/release/README.md
+++ b/release/README.md
@@ -2,14 +2,6 @@
In this folder you can find raylib library pre-compiled and ready-to-use for different platforms.
-It also includes additional raylib required libraries for different platforms that sometimes users need to compile by themselfs.Depending on target platform some libraries can be just downloaded from their repos using some package manager software provided by the OS, very tipical in Linux (`apt-get`) and OSX.
+For detailed information on raylib external dependencies, just check [Wiki information on external dependencies](https://github.com/raysan5/raylib/wiki/raylib-external-dependencies).
-**Provided libraries you will find in this folder are:**
-
-Library | Version | Date | Platform | Notes
---- | :---: | :---: | :---: | ---
-[raylib]() | 1.8.0 | Oct 2017 | *all* | simple and easy-to-use library for games dev.
-[GLFW3](http://www.glfw.org/) | 3.2.1 | Aug 2016 | win32-mingw32,
win32-msvc | Window and input management on desktop platforms
-[OpenAL Soft](http://kcat.strangesoft.net/openal.html) | 1.18.2 | Sep 2017 | win32-mingw32,
win32-msvc,
Android | Audio device management
-
-For detailed information on raylib external dependencies, just check [Wiki information on external dependencies](https://github.com/raysan5/raylib/wiki/External-dependencies).
+**NOTE: Next raylib version is removing all external dependencies.**
diff --git a/release/include/GLFW/glfw3.h b/release/include/GLFW/glfw3.h
deleted file mode 100644
index 5a0c45089..000000000
--- a/release/include/GLFW/glfw3.h
+++ /dev/null
@@ -1,4235 +0,0 @@
-/*************************************************************************
- * GLFW 3.2 - www.glfw.org
- * A library for OpenGL, window and input
- *------------------------------------------------------------------------
- * Copyright (c) 2002-2006 Marcus Geelnard
- * Copyright (c) 2006-2016 Camilla Berglund
- *
- * This software is provided 'as-is', without any express or implied
- * warranty. In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- * claim that you wrote the original software. If you use this software
- * in a product, an acknowledgment in the product documentation would
- * be appreciated but is not required.
- *
- * 2. Altered source versions must be plainly marked as such, and must not
- * be misrepresented as being the original software.
- *
- * 3. This notice may not be removed or altered from any source
- * distribution.
- *
- *************************************************************************/
-
-#ifndef _glfw3_h_
-#define _glfw3_h_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*************************************************************************
- * Doxygen documentation
- *************************************************************************/
-
-/*! @file glfw3.h
- * @brief The header of the GLFW 3 API.
- *
- * This is the header file of the GLFW 3 API. It defines all its types and
- * declares all its functions.
- *
- * For more information about how to use this file, see @ref build_include.
- */
-/*! @defgroup context Context reference
- *
- * This is the reference documentation for OpenGL and OpenGL ES context related
- * functions. For more task-oriented information, see the @ref context_guide.
- */
-/*! @defgroup vulkan Vulkan reference
- *
- * This is the reference documentation for Vulkan related functions and types.
- * For more task-oriented information, see the @ref vulkan_guide.
- */
-/*! @defgroup init Initialization, version and error reference
- *
- * This is the reference documentation for initialization and termination of
- * the library, version management and error handling. For more task-oriented
- * information, see the @ref intro_guide.
- */
-/*! @defgroup input Input reference
- *
- * This is the reference documentation for input related functions and types.
- * For more task-oriented information, see the @ref input_guide.
- */
-/*! @defgroup monitor Monitor reference
- *
- * This is the reference documentation for monitor related functions and types.
- * For more task-oriented information, see the @ref monitor_guide.
- */
-/*! @defgroup window Window reference
- *
- * This is the reference documentation for window related functions and types,
- * including creation, deletion and event polling. For more task-oriented
- * information, see the @ref window_guide.
- */
-
-
-/*************************************************************************
- * Compiler- and platform-specific preprocessor work
- *************************************************************************/
-
-/* If we are we on Windows, we want a single define for it.
- */
-#if !defined(_WIN32) && (defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__))
- #define _WIN32
-#endif /* _WIN32 */
-
-/* It is customary to use APIENTRY for OpenGL function pointer declarations on
- * all platforms. Additionally, the Windows OpenGL header needs APIENTRY.
- */
-#ifndef APIENTRY
- #ifdef _WIN32
- #define APIENTRY __stdcall
- #else
- #define APIENTRY
- #endif
-#endif /* APIENTRY */
-
-/* Some Windows OpenGL headers need this.
- */
-#if !defined(WINGDIAPI) && defined(_WIN32)
- #define WINGDIAPI __declspec(dllimport)
- #define GLFW_WINGDIAPI_DEFINED
-#endif /* WINGDIAPI */
-
-/* Some Windows GLU headers need this.
- */
-#if !defined(CALLBACK) && defined(_WIN32)
- #define CALLBACK __stdcall
- #define GLFW_CALLBACK_DEFINED
-#endif /* CALLBACK */
-
-/* Most Windows GLU headers need wchar_t.
- * The OS X OpenGL header blocks the definition of ptrdiff_t by glext.h.
- * Include it unconditionally to avoid surprising side-effects.
- */
-#include
-#include
-
-/* Include the chosen client API headers.
- */
-#if defined(__APPLE__)
- #if defined(GLFW_INCLUDE_GLCOREARB)
- #include
- #if defined(GLFW_INCLUDE_GLEXT)
- #include
- #endif
- #elif !defined(GLFW_INCLUDE_NONE)
- #if !defined(GLFW_INCLUDE_GLEXT)
- #define GL_GLEXT_LEGACY
- #endif
- #include
- #endif
- #if defined(GLFW_INCLUDE_GLU)
- #include
- #endif
-#else
- #if defined(GLFW_INCLUDE_GLCOREARB)
- #include
- #elif defined(GLFW_INCLUDE_ES1)
- #include
- #if defined(GLFW_INCLUDE_GLEXT)
- #include
- #endif
- #elif defined(GLFW_INCLUDE_ES2)
- #include
- #if defined(GLFW_INCLUDE_GLEXT)
- #include
- #endif
- #elif defined(GLFW_INCLUDE_ES3)
- #include
- #if defined(GLFW_INCLUDE_GLEXT)
- #include
- #endif
- #elif defined(GLFW_INCLUDE_ES31)
- #include
- #if defined(GLFW_INCLUDE_GLEXT)
- #include
- #endif
- #elif defined(GLFW_INCLUDE_VULKAN)
- #include
- #elif !defined(GLFW_INCLUDE_NONE)
- #include
- #if defined(GLFW_INCLUDE_GLEXT)
- #include
- #endif
- #endif
- #if defined(GLFW_INCLUDE_GLU)
- #include
- #endif
-#endif
-
-#if defined(GLFW_DLL) && defined(_GLFW_BUILD_DLL)
- /* GLFW_DLL must be defined by applications that are linking against the DLL
- * version of the GLFW library. _GLFW_BUILD_DLL is defined by the GLFW
- * configuration header when compiling the DLL version of the library.
- */
- #error "You must not have both GLFW_DLL and _GLFW_BUILD_DLL defined"
-#endif
-
-/* GLFWAPI is used to declare public API functions for export
- * from the DLL / shared library / dynamic library.
- */
-#if defined(_WIN32) && defined(_GLFW_BUILD_DLL)
- /* We are building GLFW as a Win32 DLL */
- #define GLFWAPI __declspec(dllexport)
-#elif defined(_WIN32) && defined(GLFW_DLL)
- /* We are calling GLFW as a Win32 DLL */
- #define GLFWAPI __declspec(dllimport)
-#elif defined(__GNUC__) && defined(_GLFW_BUILD_DLL)
- /* We are building GLFW as a shared / dynamic library */
- #define GLFWAPI __attribute__((visibility("default")))
-#else
- /* We are building or calling GLFW as a static library */
- #define GLFWAPI
-#endif
-
-
-/*************************************************************************
- * GLFW API tokens
- *************************************************************************/
-
-/*! @name GLFW version macros
- * @{ */
-/*! @brief The major version number of the GLFW library.
- *
- * This is incremented when the API is changed in non-compatible ways.
- * @ingroup init
- */
-#define GLFW_VERSION_MAJOR 3
-/*! @brief The minor version number of the GLFW library.
- *
- * This is incremented when features are added to the API but it remains
- * backward-compatible.
- * @ingroup init
- */
-#define GLFW_VERSION_MINOR 2
-/*! @brief The revision number of the GLFW library.
- *
- * This is incremented when a bug fix release is made that does not contain any
- * API changes.
- * @ingroup init
- */
-#define GLFW_VERSION_REVISION 0
-/*! @} */
-
-/*! @name Boolean values
- * @{ */
-/*! @brief One.
- *
- * One. Seriously. You don't _need_ to use this symbol in your code. It's
- * just semantic sugar for the number 1. You can use `1` or `true` or `_True`
- * or `GL_TRUE` or whatever you want.
- */
-#define GLFW_TRUE 1
-/*! @brief Zero.
- *
- * Zero. Seriously. You don't _need_ to use this symbol in your code. It's
- * just just semantic sugar for the number 0. You can use `0` or `false` or
- * `_False` or `GL_FALSE` or whatever you want.
- */
-#define GLFW_FALSE 0
-/*! @} */
-
-/*! @name Key and button actions
- * @{ */
-/*! @brief The key or mouse button was released.
- *
- * The key or mouse button was released.
- *
- * @ingroup input
- */
-#define GLFW_RELEASE 0
-/*! @brief The key or mouse button was pressed.
- *
- * The key or mouse button was pressed.
- *
- * @ingroup input
- */
-#define GLFW_PRESS 1
-/*! @brief The key was held down until it repeated.
- *
- * The key was held down until it repeated.
- *
- * @ingroup input
- */
-#define GLFW_REPEAT 2
-/*! @} */
-
-/*! @defgroup keys Keyboard keys
- *
- * See [key input](@ref input_key) for how these are used.
- *
- * These key codes are inspired by the _USB HID Usage Tables v1.12_ (p. 53-60),
- * but re-arranged to map to 7-bit ASCII for printable keys (function keys are
- * put in the 256+ range).
- *
- * The naming of the key codes follow these rules:
- * - The US keyboard layout is used
- * - Names of printable alpha-numeric characters are used (e.g. "A", "R",
- * "3", etc.)
- * - For non-alphanumeric characters, Unicode:ish names are used (e.g.
- * "COMMA", "LEFT_SQUARE_BRACKET", etc.). Note that some names do not
- * correspond to the Unicode standard (usually for brevity)
- * - Keys that lack a clear US mapping are named "WORLD_x"
- * - For non-printable keys, custom names are used (e.g. "F4",
- * "BACKSPACE", etc.)
- *
- * @ingroup input
- * @{
- */
-
-/* The unknown key */
-#define GLFW_KEY_UNKNOWN -1
-
-/* Printable keys */
-#define GLFW_KEY_SPACE 32
-#define GLFW_KEY_APOSTROPHE 39 /* ' */
-#define GLFW_KEY_COMMA 44 /* , */
-#define GLFW_KEY_MINUS 45 /* - */
-#define GLFW_KEY_PERIOD 46 /* . */
-#define GLFW_KEY_SLASH 47 /* / */
-#define GLFW_KEY_0 48
-#define GLFW_KEY_1 49
-#define GLFW_KEY_2 50
-#define GLFW_KEY_3 51
-#define GLFW_KEY_4 52
-#define GLFW_KEY_5 53
-#define GLFW_KEY_6 54
-#define GLFW_KEY_7 55
-#define GLFW_KEY_8 56
-#define GLFW_KEY_9 57
-#define GLFW_KEY_SEMICOLON 59 /* ; */
-#define GLFW_KEY_EQUAL 61 /* = */
-#define GLFW_KEY_A 65
-#define GLFW_KEY_B 66
-#define GLFW_KEY_C 67
-#define GLFW_KEY_D 68
-#define GLFW_KEY_E 69
-#define GLFW_KEY_F 70
-#define GLFW_KEY_G 71
-#define GLFW_KEY_H 72
-#define GLFW_KEY_I 73
-#define GLFW_KEY_J 74
-#define GLFW_KEY_K 75
-#define GLFW_KEY_L 76
-#define GLFW_KEY_M 77
-#define GLFW_KEY_N 78
-#define GLFW_KEY_O 79
-#define GLFW_KEY_P 80
-#define GLFW_KEY_Q 81
-#define GLFW_KEY_R 82
-#define GLFW_KEY_S 83
-#define GLFW_KEY_T 84
-#define GLFW_KEY_U 85
-#define GLFW_KEY_V 86
-#define GLFW_KEY_W 87
-#define GLFW_KEY_X 88
-#define GLFW_KEY_Y 89
-#define GLFW_KEY_Z 90
-#define GLFW_KEY_LEFT_BRACKET 91 /* [ */
-#define GLFW_KEY_BACKSLASH 92 /* \ */
-#define GLFW_KEY_RIGHT_BRACKET 93 /* ] */
-#define GLFW_KEY_GRAVE_ACCENT 96 /* ` */
-#define GLFW_KEY_WORLD_1 161 /* non-US #1 */
-#define GLFW_KEY_WORLD_2 162 /* non-US #2 */
-
-/* Function keys */
-#define GLFW_KEY_ESCAPE 256
-#define GLFW_KEY_ENTER 257
-#define GLFW_KEY_TAB 258
-#define GLFW_KEY_BACKSPACE 259
-#define GLFW_KEY_INSERT 260
-#define GLFW_KEY_DELETE 261
-#define GLFW_KEY_RIGHT 262
-#define GLFW_KEY_LEFT 263
-#define GLFW_KEY_DOWN 264
-#define GLFW_KEY_UP 265
-#define GLFW_KEY_PAGE_UP 266
-#define GLFW_KEY_PAGE_DOWN 267
-#define GLFW_KEY_HOME 268
-#define GLFW_KEY_END 269
-#define GLFW_KEY_CAPS_LOCK 280
-#define GLFW_KEY_SCROLL_LOCK 281
-#define GLFW_KEY_NUM_LOCK 282
-#define GLFW_KEY_PRINT_SCREEN 283
-#define GLFW_KEY_PAUSE 284
-#define GLFW_KEY_F1 290
-#define GLFW_KEY_F2 291
-#define GLFW_KEY_F3 292
-#define GLFW_KEY_F4 293
-#define GLFW_KEY_F5 294
-#define GLFW_KEY_F6 295
-#define GLFW_KEY_F7 296
-#define GLFW_KEY_F8 297
-#define GLFW_KEY_F9 298
-#define GLFW_KEY_F10 299
-#define GLFW_KEY_F11 300
-#define GLFW_KEY_F12 301
-#define GLFW_KEY_F13 302
-#define GLFW_KEY_F14 303
-#define GLFW_KEY_F15 304
-#define GLFW_KEY_F16 305
-#define GLFW_KEY_F17 306
-#define GLFW_KEY_F18 307
-#define GLFW_KEY_F19 308
-#define GLFW_KEY_F20 309
-#define GLFW_KEY_F21 310
-#define GLFW_KEY_F22 311
-#define GLFW_KEY_F23 312
-#define GLFW_KEY_F24 313
-#define GLFW_KEY_F25 314
-#define GLFW_KEY_KP_0 320
-#define GLFW_KEY_KP_1 321
-#define GLFW_KEY_KP_2 322
-#define GLFW_KEY_KP_3 323
-#define GLFW_KEY_KP_4 324
-#define GLFW_KEY_KP_5 325
-#define GLFW_KEY_KP_6 326
-#define GLFW_KEY_KP_7 327
-#define GLFW_KEY_KP_8 328
-#define GLFW_KEY_KP_9 329
-#define GLFW_KEY_KP_DECIMAL 330
-#define GLFW_KEY_KP_DIVIDE 331
-#define GLFW_KEY_KP_MULTIPLY 332
-#define GLFW_KEY_KP_SUBTRACT 333
-#define GLFW_KEY_KP_ADD 334
-#define GLFW_KEY_KP_ENTER 335
-#define GLFW_KEY_KP_EQUAL 336
-#define GLFW_KEY_LEFT_SHIFT 340
-#define GLFW_KEY_LEFT_CONTROL 341
-#define GLFW_KEY_LEFT_ALT 342
-#define GLFW_KEY_LEFT_SUPER 343
-#define GLFW_KEY_RIGHT_SHIFT 344
-#define GLFW_KEY_RIGHT_CONTROL 345
-#define GLFW_KEY_RIGHT_ALT 346
-#define GLFW_KEY_RIGHT_SUPER 347
-#define GLFW_KEY_MENU 348
-
-#define GLFW_KEY_LAST GLFW_KEY_MENU
-
-/*! @} */
-
-/*! @defgroup mods Modifier key flags
- *
- * See [key input](@ref input_key) for how these are used.
- *
- * @ingroup input
- * @{ */
-
-/*! @brief If this bit is set one or more Shift keys were held down.
- */
-#define GLFW_MOD_SHIFT 0x0001
-/*! @brief If this bit is set one or more Control keys were held down.
- */
-#define GLFW_MOD_CONTROL 0x0002
-/*! @brief If this bit is set one or more Alt keys were held down.
- */
-#define GLFW_MOD_ALT 0x0004
-/*! @brief If this bit is set one or more Super keys were held down.
- */
-#define GLFW_MOD_SUPER 0x0008
-
-/*! @} */
-
-/*! @defgroup buttons Mouse buttons
- *
- * See [mouse button input](@ref input_mouse_button) for how these are used.
- *
- * @ingroup input
- * @{ */
-#define GLFW_MOUSE_BUTTON_1 0
-#define GLFW_MOUSE_BUTTON_2 1
-#define GLFW_MOUSE_BUTTON_3 2
-#define GLFW_MOUSE_BUTTON_4 3
-#define GLFW_MOUSE_BUTTON_5 4
-#define GLFW_MOUSE_BUTTON_6 5
-#define GLFW_MOUSE_BUTTON_7 6
-#define GLFW_MOUSE_BUTTON_8 7
-#define GLFW_MOUSE_BUTTON_LAST GLFW_MOUSE_BUTTON_8
-#define GLFW_MOUSE_BUTTON_LEFT GLFW_MOUSE_BUTTON_1
-#define GLFW_MOUSE_BUTTON_RIGHT GLFW_MOUSE_BUTTON_2
-#define GLFW_MOUSE_BUTTON_MIDDLE GLFW_MOUSE_BUTTON_3
-/*! @} */
-
-/*! @defgroup joysticks Joysticks
- *
- * See [joystick input](@ref joystick) for how these are used.
- *
- * @ingroup input
- * @{ */
-#define GLFW_JOYSTICK_1 0
-#define GLFW_JOYSTICK_2 1
-#define GLFW_JOYSTICK_3 2
-#define GLFW_JOYSTICK_4 3
-#define GLFW_JOYSTICK_5 4
-#define GLFW_JOYSTICK_6 5
-#define GLFW_JOYSTICK_7 6
-#define GLFW_JOYSTICK_8 7
-#define GLFW_JOYSTICK_9 8
-#define GLFW_JOYSTICK_10 9
-#define GLFW_JOYSTICK_11 10
-#define GLFW_JOYSTICK_12 11
-#define GLFW_JOYSTICK_13 12
-#define GLFW_JOYSTICK_14 13
-#define GLFW_JOYSTICK_15 14
-#define GLFW_JOYSTICK_16 15
-#define GLFW_JOYSTICK_LAST GLFW_JOYSTICK_16
-/*! @} */
-
-/*! @defgroup errors Error codes
- *
- * See [error handling](@ref error_handling) for how these are used.
- *
- * @ingroup init
- * @{ */
-/*! @brief GLFW has not been initialized.
- *
- * This occurs if a GLFW function was called that must not be called unless the
- * library is [initialized](@ref intro_init).
- *
- * @analysis Application programmer error. Initialize GLFW before calling any
- * function that requires initialization.
- */
-#define GLFW_NOT_INITIALIZED 0x00010001
-/*! @brief No context is current for this thread.
- *
- * This occurs if a GLFW function was called that needs and operates on the
- * current OpenGL or OpenGL ES context but no context is current on the calling
- * thread. One such function is @ref glfwSwapInterval.
- *
- * @analysis Application programmer error. Ensure a context is current before
- * calling functions that require a current context.
- */
-#define GLFW_NO_CURRENT_CONTEXT 0x00010002
-/*! @brief One of the arguments to the function was an invalid enum value.
- *
- * One of the arguments to the function was an invalid enum value, for example
- * requesting [GLFW_RED_BITS](@ref window_hints_fb) with @ref
- * glfwGetWindowAttrib.
- *
- * @analysis Application programmer error. Fix the offending call.
- */
-#define GLFW_INVALID_ENUM 0x00010003
-/*! @brief One of the arguments to the function was an invalid value.
- *
- * One of the arguments to the function was an invalid value, for example
- * requesting a non-existent OpenGL or OpenGL ES version like 2.7.
- *
- * Requesting a valid but unavailable OpenGL or OpenGL ES version will instead
- * result in a @ref GLFW_VERSION_UNAVAILABLE error.
- *
- * @analysis Application programmer error. Fix the offending call.
- */
-#define GLFW_INVALID_VALUE 0x00010004
-/*! @brief A memory allocation failed.
- *
- * A memory allocation failed.
- *
- * @analysis A bug in GLFW or the underlying operating system. Report the bug
- * to our [issue tracker](https://github.com/glfw/glfw/issues).
- */
-#define GLFW_OUT_OF_MEMORY 0x00010005
-/*! @brief GLFW could not find support for the requested API on the system.
- *
- * GLFW could not find support for the requested API on the system.
- *
- * @analysis The installed graphics driver does not support the requested
- * API, or does not support it via the chosen context creation backend.
- * Below are a few examples.
- *
- * @par
- * Some pre-installed Windows graphics drivers do not support OpenGL. AMD only
- * supports OpenGL ES via EGL, while Nvidia and Intel only support it via
- * a WGL or GLX extension. OS X does not provide OpenGL ES at all. The Mesa
- * EGL, OpenGL and OpenGL ES libraries do not interface with the Nvidia binary
- * driver. Older graphics drivers do not support Vulkan.
- */
-#define GLFW_API_UNAVAILABLE 0x00010006
-/*! @brief The requested OpenGL or OpenGL ES version is not available.
- *
- * The requested OpenGL or OpenGL ES version (including any requested context
- * or framebuffer hints) is not available on this machine.
- *
- * @analysis The machine does not support your requirements. If your
- * application is sufficiently flexible, downgrade your requirements and try
- * again. Otherwise, inform the user that their machine does not match your
- * requirements.
- *
- * @par
- * Future invalid OpenGL and OpenGL ES versions, for example OpenGL 4.8 if 5.0
- * comes out before the 4.x series gets that far, also fail with this error and
- * not @ref GLFW_INVALID_VALUE, because GLFW cannot know what future versions
- * will exist.
- */
-#define GLFW_VERSION_UNAVAILABLE 0x00010007
-/*! @brief A platform-specific error occurred that does not match any of the
- * more specific categories.
- *
- * A platform-specific error occurred that does not match any of the more
- * specific categories.
- *
- * @analysis A bug or configuration error in GLFW, the underlying operating
- * system or its drivers, or a lack of required resources. Report the issue to
- * our [issue tracker](https://github.com/glfw/glfw/issues).
- */
-#define GLFW_PLATFORM_ERROR 0x00010008
-/*! @brief The requested format is not supported or available.
- *
- * If emitted during window creation, the requested pixel format is not
- * supported.
- *
- * If emitted when querying the clipboard, the contents of the clipboard could
- * not be converted to the requested format.
- *
- * @analysis If emitted during window creation, one or more
- * [hard constraints](@ref window_hints_hard) did not match any of the
- * available pixel formats. If your application is sufficiently flexible,
- * downgrade your requirements and try again. Otherwise, inform the user that
- * their machine does not match your requirements.
- *
- * @par
- * If emitted when querying the clipboard, ignore the error or report it to
- * the user, as appropriate.
- */
-#define GLFW_FORMAT_UNAVAILABLE 0x00010009
-/*! @brief The specified window does not have an OpenGL or OpenGL ES context.
- *
- * A window that does not have an OpenGL or OpenGL ES context was passed to
- * a function that requires it to have one.
- *
- * @analysis Application programmer error. Fix the offending call.
- */
-#define GLFW_NO_WINDOW_CONTEXT 0x0001000A
-/*! @} */
-
-#define GLFW_FOCUSED 0x00020001
-#define GLFW_ICONIFIED 0x00020002
-#define GLFW_RESIZABLE 0x00020003
-#define GLFW_VISIBLE 0x00020004
-#define GLFW_DECORATED 0x00020005
-#define GLFW_AUTO_ICONIFY 0x00020006
-#define GLFW_FLOATING 0x00020007
-#define GLFW_MAXIMIZED 0x00020008
-
-#define GLFW_RED_BITS 0x00021001
-#define GLFW_GREEN_BITS 0x00021002
-#define GLFW_BLUE_BITS 0x00021003
-#define GLFW_ALPHA_BITS 0x00021004
-#define GLFW_DEPTH_BITS 0x00021005
-#define GLFW_STENCIL_BITS 0x00021006
-#define GLFW_ACCUM_RED_BITS 0x00021007
-#define GLFW_ACCUM_GREEN_BITS 0x00021008
-#define GLFW_ACCUM_BLUE_BITS 0x00021009
-#define GLFW_ACCUM_ALPHA_BITS 0x0002100A
-#define GLFW_AUX_BUFFERS 0x0002100B
-#define GLFW_STEREO 0x0002100C
-#define GLFW_SAMPLES 0x0002100D
-#define GLFW_SRGB_CAPABLE 0x0002100E
-#define GLFW_REFRESH_RATE 0x0002100F
-#define GLFW_DOUBLEBUFFER 0x00021010
-
-#define GLFW_CLIENT_API 0x00022001
-#define GLFW_CONTEXT_VERSION_MAJOR 0x00022002
-#define GLFW_CONTEXT_VERSION_MINOR 0x00022003
-#define GLFW_CONTEXT_REVISION 0x00022004
-#define GLFW_CONTEXT_ROBUSTNESS 0x00022005
-#define GLFW_OPENGL_FORWARD_COMPAT 0x00022006
-#define GLFW_OPENGL_DEBUG_CONTEXT 0x00022007
-#define GLFW_OPENGL_PROFILE 0x00022008
-#define GLFW_CONTEXT_RELEASE_BEHAVIOR 0x00022009
-#define GLFW_CONTEXT_NO_ERROR 0x0002200A
-#define GLFW_CONTEXT_CREATION_API 0x0002200B
-
-#define GLFW_NO_API 0
-#define GLFW_OPENGL_API 0x00030001
-#define GLFW_OPENGL_ES_API 0x00030002
-
-#define GLFW_NO_ROBUSTNESS 0
-#define GLFW_NO_RESET_NOTIFICATION 0x00031001
-#define GLFW_LOSE_CONTEXT_ON_RESET 0x00031002
-
-#define GLFW_OPENGL_ANY_PROFILE 0
-#define GLFW_OPENGL_CORE_PROFILE 0x00032001
-#define GLFW_OPENGL_COMPAT_PROFILE 0x00032002
-
-#define GLFW_CURSOR 0x00033001
-#define GLFW_STICKY_KEYS 0x00033002
-#define GLFW_STICKY_MOUSE_BUTTONS 0x00033003
-
-#define GLFW_CURSOR_NORMAL 0x00034001
-#define GLFW_CURSOR_HIDDEN 0x00034002
-#define GLFW_CURSOR_DISABLED 0x00034003
-
-#define GLFW_ANY_RELEASE_BEHAVIOR 0
-#define GLFW_RELEASE_BEHAVIOR_FLUSH 0x00035001
-#define GLFW_RELEASE_BEHAVIOR_NONE 0x00035002
-
-#define GLFW_NATIVE_CONTEXT_API 0x00036001
-#define GLFW_EGL_CONTEXT_API 0x00036002
-
-/*! @defgroup shapes Standard cursor shapes
- *
- * See [standard cursor creation](@ref cursor_standard) for how these are used.
- *
- * @ingroup input
- * @{ */
-
-/*! @brief The regular arrow cursor shape.
- *
- * The regular arrow cursor.
- */
-#define GLFW_ARROW_CURSOR 0x00036001
-/*! @brief The text input I-beam cursor shape.
- *
- * The text input I-beam cursor shape.
- */
-#define GLFW_IBEAM_CURSOR 0x00036002
-/*! @brief The crosshair shape.
- *
- * The crosshair shape.
- */
-#define GLFW_CROSSHAIR_CURSOR 0x00036003
-/*! @brief The hand shape.
- *
- * The hand shape.
- */
-#define GLFW_HAND_CURSOR 0x00036004
-/*! @brief The horizontal resize arrow shape.
- *
- * The horizontal resize arrow shape.
- */
-#define GLFW_HRESIZE_CURSOR 0x00036005
-/*! @brief The vertical resize arrow shape.
- *
- * The vertical resize arrow shape.
- */
-#define GLFW_VRESIZE_CURSOR 0x00036006
-/*! @} */
-
-#define GLFW_CONNECTED 0x00040001
-#define GLFW_DISCONNECTED 0x00040002
-
-#define GLFW_DONT_CARE -1
-
-
-/*************************************************************************
- * GLFW API types
- *************************************************************************/
-
-/*! @brief Client API function pointer type.
- *
- * Generic function pointer used for returning client API function pointers
- * without forcing a cast from a regular pointer.
- *
- * @sa @ref context_glext
- * @sa glfwGetProcAddress
- *
- * @since Added in version 3.0.
-
- * @ingroup context
- */
-typedef void (*GLFWglproc)(void);
-
-/*! @brief Vulkan API function pointer type.
- *
- * Generic function pointer used for returning Vulkan API function pointers
- * without forcing a cast from a regular pointer.
- *
- * @sa @ref vulkan_proc
- * @sa glfwGetInstanceProcAddress
- *
- * @since Added in version 3.2.
- *
- * @ingroup vulkan
- */
-typedef void (*GLFWvkproc)(void);
-
-/*! @brief Opaque monitor object.
- *
- * Opaque monitor object.
- *
- * @see @ref monitor_object
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-typedef struct GLFWmonitor GLFWmonitor;
-
-/*! @brief Opaque window object.
- *
- * Opaque window object.
- *
- * @see @ref window_object
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-typedef struct GLFWwindow GLFWwindow;
-
-/*! @brief Opaque cursor object.
- *
- * Opaque cursor object.
- *
- * @see @ref cursor_object
- *
- * @since Added in version 3.1.
- *
- * @ingroup cursor
- */
-typedef struct GLFWcursor GLFWcursor;
-
-/*! @brief The function signature for error callbacks.
- *
- * This is the function signature for error callback functions.
- *
- * @param[in] error An [error code](@ref errors).
- * @param[in] description A UTF-8 encoded string describing the error.
- *
- * @sa @ref error_handling
- * @sa glfwSetErrorCallback
- *
- * @since Added in version 3.0.
- *
- * @ingroup init
- */
-typedef void (* GLFWerrorfun)(int,const char*);
-
-/*! @brief The function signature for window position callbacks.
- *
- * This is the function signature for window position callback functions.
- *
- * @param[in] window The window that was moved.
- * @param[in] xpos The new x-coordinate, in screen coordinates, of the
- * upper-left corner of the client area of the window.
- * @param[in] ypos The new y-coordinate, in screen coordinates, of the
- * upper-left corner of the client area of the window.
- *
- * @sa @ref window_pos
- * @sa glfwSetWindowPosCallback
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-typedef void (* GLFWwindowposfun)(GLFWwindow*,int,int);
-
-/*! @brief The function signature for window resize callbacks.
- *
- * This is the function signature for window size callback functions.
- *
- * @param[in] window The window that was resized.
- * @param[in] width The new width, in screen coordinates, of the window.
- * @param[in] height The new height, in screen coordinates, of the window.
- *
- * @sa @ref window_size
- * @sa glfwSetWindowSizeCallback
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup window
- */
-typedef void (* GLFWwindowsizefun)(GLFWwindow*,int,int);
-
-/*! @brief The function signature for window close callbacks.
- *
- * This is the function signature for window close callback functions.
- *
- * @param[in] window The window that the user attempted to close.
- *
- * @sa @ref window_close
- * @sa glfwSetWindowCloseCallback
- *
- * @since Added in version 2.5.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup window
- */
-typedef void (* GLFWwindowclosefun)(GLFWwindow*);
-
-/*! @brief The function signature for window content refresh callbacks.
- *
- * This is the function signature for window refresh callback functions.
- *
- * @param[in] window The window whose content needs to be refreshed.
- *
- * @sa @ref window_refresh
- * @sa glfwSetWindowRefreshCallback
- *
- * @since Added in version 2.5.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup window
- */
-typedef void (* GLFWwindowrefreshfun)(GLFWwindow*);
-
-/*! @brief The function signature for window focus/defocus callbacks.
- *
- * This is the function signature for window focus callback functions.
- *
- * @param[in] window The window that gained or lost input focus.
- * @param[in] focused `GLFW_TRUE` if the window was given input focus, or
- * `GLFW_FALSE` if it lost it.
- *
- * @sa @ref window_focus
- * @sa glfwSetWindowFocusCallback
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-typedef void (* GLFWwindowfocusfun)(GLFWwindow*,int);
-
-/*! @brief The function signature for window iconify/restore callbacks.
- *
- * This is the function signature for window iconify/restore callback
- * functions.
- *
- * @param[in] window The window that was iconified or restored.
- * @param[in] iconified `GLFW_TRUE` if the window was iconified, or
- * `GLFW_FALSE` if it was restored.
- *
- * @sa @ref window_iconify
- * @sa glfwSetWindowIconifyCallback
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-typedef void (* GLFWwindowiconifyfun)(GLFWwindow*,int);
-
-/*! @brief The function signature for framebuffer resize callbacks.
- *
- * This is the function signature for framebuffer resize callback
- * functions.
- *
- * @param[in] window The window whose framebuffer was resized.
- * @param[in] width The new width, in pixels, of the framebuffer.
- * @param[in] height The new height, in pixels, of the framebuffer.
- *
- * @sa @ref window_fbsize
- * @sa glfwSetFramebufferSizeCallback
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-typedef void (* GLFWframebuffersizefun)(GLFWwindow*,int,int);
-
-/*! @brief The function signature for mouse button callbacks.
- *
- * This is the function signature for mouse button callback functions.
- *
- * @param[in] window The window that received the event.
- * @param[in] button The [mouse button](@ref buttons) that was pressed or
- * released.
- * @param[in] action One of `GLFW_PRESS` or `GLFW_RELEASE`.
- * @param[in] mods Bit field describing which [modifier keys](@ref mods) were
- * held down.
- *
- * @sa @ref input_mouse_button
- * @sa glfwSetMouseButtonCallback
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle and modifier mask parameters.
- *
- * @ingroup input
- */
-typedef void (* GLFWmousebuttonfun)(GLFWwindow*,int,int,int);
-
-/*! @brief The function signature for cursor position callbacks.
- *
- * This is the function signature for cursor position callback functions.
- *
- * @param[in] window The window that received the event.
- * @param[in] xpos The new cursor x-coordinate, relative to the left edge of
- * the client area.
- * @param[in] ypos The new cursor y-coordinate, relative to the top edge of the
- * client area.
- *
- * @sa @ref cursor_pos
- * @sa glfwSetCursorPosCallback
- *
- * @since Added in version 3.0. Replaces `GLFWmouseposfun`.
- *
- * @ingroup input
- */
-typedef void (* GLFWcursorposfun)(GLFWwindow*,double,double);
-
-/*! @brief The function signature for cursor enter/leave callbacks.
- *
- * This is the function signature for cursor enter/leave callback functions.
- *
- * @param[in] window The window that received the event.
- * @param[in] entered `GLFW_TRUE` if the cursor entered the window's client
- * area, or `GLFW_FALSE` if it left it.
- *
- * @sa @ref cursor_enter
- * @sa glfwSetCursorEnterCallback
- *
- * @since Added in version 3.0.
- *
- * @ingroup input
- */
-typedef void (* GLFWcursorenterfun)(GLFWwindow*,int);
-
-/*! @brief The function signature for scroll callbacks.
- *
- * This is the function signature for scroll callback functions.
- *
- * @param[in] window The window that received the event.
- * @param[in] xoffset The scroll offset along the x-axis.
- * @param[in] yoffset The scroll offset along the y-axis.
- *
- * @sa @ref scrolling
- * @sa glfwSetScrollCallback
- *
- * @since Added in version 3.0. Replaces `GLFWmousewheelfun`.
- *
- * @ingroup input
- */
-typedef void (* GLFWscrollfun)(GLFWwindow*,double,double);
-
-/*! @brief The function signature for keyboard key callbacks.
- *
- * This is the function signature for keyboard key callback functions.
- *
- * @param[in] window The window that received the event.
- * @param[in] key The [keyboard key](@ref keys) that was pressed or released.
- * @param[in] scancode The system-specific scancode of the key.
- * @param[in] action `GLFW_PRESS`, `GLFW_RELEASE` or `GLFW_REPEAT`.
- * @param[in] mods Bit field describing which [modifier keys](@ref mods) were
- * held down.
- *
- * @sa @ref input_key
- * @sa glfwSetKeyCallback
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle, scancode and modifier mask parameters.
- *
- * @ingroup input
- */
-typedef void (* GLFWkeyfun)(GLFWwindow*,int,int,int,int);
-
-/*! @brief The function signature for Unicode character callbacks.
- *
- * This is the function signature for Unicode character callback functions.
- *
- * @param[in] window The window that received the event.
- * @param[in] codepoint The Unicode code point of the character.
- *
- * @sa @ref input_char
- * @sa glfwSetCharCallback
- *
- * @since Added in version 2.4.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup input
- */
-typedef void (* GLFWcharfun)(GLFWwindow*,unsigned int);
-
-/*! @brief The function signature for Unicode character with modifiers
- * callbacks.
- *
- * This is the function signature for Unicode character with modifiers callback
- * functions. It is called for each input character, regardless of what
- * modifier keys are held down.
- *
- * @param[in] window The window that received the event.
- * @param[in] codepoint The Unicode code point of the character.
- * @param[in] mods Bit field describing which [modifier keys](@ref mods) were
- * held down.
- *
- * @sa @ref input_char
- * @sa glfwSetCharModsCallback
- *
- * @since Added in version 3.1.
- *
- * @ingroup input
- */
-typedef void (* GLFWcharmodsfun)(GLFWwindow*,unsigned int,int);
-
-/*! @brief The function signature for file drop callbacks.
- *
- * This is the function signature for file drop callbacks.
- *
- * @param[in] window The window that received the event.
- * @param[in] count The number of dropped files.
- * @param[in] paths The UTF-8 encoded file and/or directory path names.
- *
- * @sa @ref path_drop
- * @sa glfwSetDropCallback
- *
- * @since Added in version 3.1.
- *
- * @ingroup input
- */
-typedef void (* GLFWdropfun)(GLFWwindow*,int,const char**);
-
-/*! @brief The function signature for monitor configuration callbacks.
- *
- * This is the function signature for monitor configuration callback functions.
- *
- * @param[in] monitor The monitor that was connected or disconnected.
- * @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`.
- *
- * @sa @ref monitor_event
- * @sa glfwSetMonitorCallback
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-typedef void (* GLFWmonitorfun)(GLFWmonitor*,int);
-
-/*! @brief The function signature for joystick configuration callbacks.
- *
- * This is the function signature for joystick configuration callback
- * functions.
- *
- * @param[in] joy The joystick that was connected or disconnected.
- * @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`.
- *
- * @sa @ref joystick_event
- * @sa glfwSetJoystickCallback
- *
- * @since Added in version 3.2.
- *
- * @ingroup input
- */
-typedef void (* GLFWjoystickfun)(int,int);
-
-/*! @brief Video mode type.
- *
- * This describes a single video mode.
- *
- * @sa @ref monitor_modes
- * @sa glfwGetVideoMode glfwGetVideoModes
- *
- * @since Added in version 1.0.
- * @glfw3 Added refresh rate member.
- *
- * @ingroup monitor
- */
-typedef struct GLFWvidmode
-{
- /*! The width, in screen coordinates, of the video mode.
- */
- int width;
- /*! The height, in screen coordinates, of the video mode.
- */
- int height;
- /*! The bit depth of the red channel of the video mode.
- */
- int redBits;
- /*! The bit depth of the green channel of the video mode.
- */
- int greenBits;
- /*! The bit depth of the blue channel of the video mode.
- */
- int blueBits;
- /*! The refresh rate, in Hz, of the video mode.
- */
- int refreshRate;
-} GLFWvidmode;
-
-/*! @brief Gamma ramp.
- *
- * This describes the gamma ramp for a monitor.
- *
- * @sa @ref monitor_gamma
- * @sa glfwGetGammaRamp glfwSetGammaRamp
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-typedef struct GLFWgammaramp
-{
- /*! An array of value describing the response of the red channel.
- */
- unsigned short* red;
- /*! An array of value describing the response of the green channel.
- */
- unsigned short* green;
- /*! An array of value describing the response of the blue channel.
- */
- unsigned short* blue;
- /*! The number of elements in each array.
- */
- unsigned int size;
-} GLFWgammaramp;
-
-/*! @brief Image data.
- *
- * @sa @ref cursor_custom
- *
- * @since Added in version 2.1.
- * @glfw3 Removed format and bytes-per-pixel members.
- */
-typedef struct GLFWimage
-{
- /*! The width, in pixels, of this image.
- */
- int width;
- /*! The height, in pixels, of this image.
- */
- int height;
- /*! The pixel data of this image, arranged left-to-right, top-to-bottom.
- */
- unsigned char* pixels;
-} GLFWimage;
-
-
-/*************************************************************************
- * GLFW API functions
- *************************************************************************/
-
-/*! @brief Initializes the GLFW library.
- *
- * This function initializes the GLFW library. Before most GLFW functions can
- * be used, GLFW must be initialized, and before an application terminates GLFW
- * should be terminated in order to free any resources allocated during or
- * after initialization.
- *
- * If this function fails, it calls @ref glfwTerminate before returning. If it
- * succeeds, you should call @ref glfwTerminate before the application exits.
- *
- * Additional calls to this function after successful initialization but before
- * termination will return `GLFW_TRUE` immediately.
- *
- * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_PLATFORM_ERROR.
- *
- * @remark @osx This function will change the current directory of the
- * application to the `Contents/Resources` subdirectory of the application's
- * bundle, if present. This can be disabled with a
- * [compile-time option](@ref compile_options_osx).
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref intro_init
- * @sa glfwTerminate
- *
- * @since Added in version 1.0.
- *
- * @ingroup init
- */
-GLFWAPI int glfwInit(void);
-
-/*! @brief Terminates the GLFW library.
- *
- * This function destroys all remaining windows and cursors, restores any
- * modified gamma ramps and frees any other allocated resources. Once this
- * function is called, you must again call @ref glfwInit successfully before
- * you will be able to use most GLFW functions.
- *
- * If GLFW has been successfully initialized, this function should be called
- * before the application exits. If initialization fails, there is no need to
- * call this function, as it is called by @ref glfwInit before it returns
- * failure.
- *
- * @errors Possible errors include @ref GLFW_PLATFORM_ERROR.
- *
- * @remark This function may be called before @ref glfwInit.
- *
- * @warning The contexts of any remaining windows must not be current on any
- * other thread when this function is called.
- *
- * @reentrancy This function must not be called from a callback.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref intro_init
- * @sa glfwInit
- *
- * @since Added in version 1.0.
- *
- * @ingroup init
- */
-GLFWAPI void glfwTerminate(void);
-
-/*! @brief Retrieves the version of the GLFW library.
- *
- * This function retrieves the major, minor and revision numbers of the GLFW
- * library. It is intended for when you are using GLFW as a shared library and
- * want to ensure that you are using the minimum required version.
- *
- * Any or all of the version arguments may be `NULL`.
- *
- * @param[out] major Where to store the major version number, or `NULL`.
- * @param[out] minor Where to store the minor version number, or `NULL`.
- * @param[out] rev Where to store the revision number, or `NULL`.
- *
- * @errors None.
- *
- * @remark This function may be called before @ref glfwInit.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref intro_version
- * @sa glfwGetVersionString
- *
- * @since Added in version 1.0.
- *
- * @ingroup init
- */
-GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev);
-
-/*! @brief Returns a string describing the compile-time configuration.
- *
- * This function returns the compile-time generated
- * [version string](@ref intro_version_string) of the GLFW library binary. It
- * describes the version, platform, compiler and any platform-specific
- * compile-time options. It should not be confused with the OpenGL or OpenGL
- * ES version string, queried with `glGetString`.
- *
- * __Do not use the version string__ to parse the GLFW library version. The
- * @ref glfwGetVersion function provides the version of the running library
- * binary in numerical format.
- *
- * @return The ASCII encoded GLFW version string.
- *
- * @errors None.
- *
- * @remark This function may be called before @ref glfwInit.
- *
- * @pointer_lifetime The returned string is static and compile-time generated.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref intro_version
- * @sa glfwGetVersion
- *
- * @since Added in version 3.0.
- *
- * @ingroup init
- */
-GLFWAPI const char* glfwGetVersionString(void);
-
-/*! @brief Sets the error callback.
- *
- * This function sets the error callback, which is called with an error code
- * and a human-readable description each time a GLFW error occurs.
- *
- * The error callback is called on the thread where the error occurred. If you
- * are using GLFW from multiple threads, your error callback needs to be
- * written accordingly.
- *
- * Because the description string may have been generated specifically for that
- * error, it is not guaranteed to be valid after the callback has returned. If
- * you wish to use it after the callback returns, you need to make a copy.
- *
- * Once set, the error callback remains set even after the library has been
- * terminated.
- *
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set.
- *
- * @errors None.
- *
- * @remark This function may be called before @ref glfwInit.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref error_handling
- *
- * @since Added in version 3.0.
- *
- * @ingroup init
- */
-GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun);
-
-/*! @brief Returns the currently connected monitors.
- *
- * This function returns an array of handles for all currently connected
- * monitors. The primary monitor is always first in the returned array. If no
- * monitors were found, this function returns `NULL`.
- *
- * @param[out] count Where to store the number of monitors in the returned
- * array. This is set to zero if an error occurred.
- * @return An array of monitor handles, or `NULL` if no monitors were found or
- * if an [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @pointer_lifetime The returned array is allocated and freed by GLFW. You
- * should not free it yourself. It is guaranteed to be valid only until the
- * monitor configuration changes or the library is terminated.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref monitor_monitors
- * @sa @ref monitor_event
- * @sa glfwGetPrimaryMonitor
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-GLFWAPI GLFWmonitor** glfwGetMonitors(int* count);
-
-/*! @brief Returns the primary monitor.
- *
- * This function returns the primary monitor. This is usually the monitor
- * where elements like the task bar or global menu bar are located.
- *
- * @return The primary monitor, or `NULL` if no monitors were found or if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @remark The primary monitor is always first in the array returned by @ref
- * glfwGetMonitors.
- *
- * @sa @ref monitor_monitors
- * @sa glfwGetMonitors
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void);
-
-/*! @brief Returns the position of the monitor's viewport on the virtual screen.
- *
- * This function returns the position, in screen coordinates, of the upper-left
- * corner of the specified monitor.
- *
- * Any or all of the position arguments may be `NULL`. If an error occurs, all
- * non-`NULL` position arguments will be set to zero.
- *
- * @param[in] monitor The monitor to query.
- * @param[out] xpos Where to store the monitor x-coordinate, or `NULL`.
- * @param[out] ypos Where to store the monitor y-coordinate, or `NULL`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref monitor_properties
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-GLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos);
-
-/*! @brief Returns the physical size of the monitor.
- *
- * This function returns the size, in millimetres, of the display area of the
- * specified monitor.
- *
- * Some systems do not provide accurate monitor size information, either
- * because the monitor
- * [EDID](https://en.wikipedia.org/wiki/Extended_display_identification_data)
- * data is incorrect or because the driver does not report it accurately.
- *
- * Any or all of the size arguments may be `NULL`. If an error occurs, all
- * non-`NULL` size arguments will be set to zero.
- *
- * @param[in] monitor The monitor to query.
- * @param[out] widthMM Where to store the width, in millimetres, of the
- * monitor's display area, or `NULL`.
- * @param[out] heightMM Where to store the height, in millimetres, of the
- * monitor's display area, or `NULL`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @remark @win32 calculates the returned physical size from the
- * current resolution and system DPI instead of querying the monitor EDID data.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref monitor_properties
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* monitor, int* widthMM, int* heightMM);
-
-/*! @brief Returns the name of the specified monitor.
- *
- * This function returns a human-readable name, encoded as UTF-8, of the
- * specified monitor. The name typically reflects the make and model of the
- * monitor and is not guaranteed to be unique among the connected monitors.
- *
- * @param[in] monitor The monitor to query.
- * @return The UTF-8 encoded name of the monitor, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @pointer_lifetime The returned string is allocated and freed by GLFW. You
- * should not free it yourself. It is valid until the specified monitor is
- * disconnected or the library is terminated.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref monitor_properties
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* monitor);
-
-/*! @brief Sets the monitor configuration callback.
- *
- * This function sets the monitor configuration callback, or removes the
- * currently set callback. This is called when a monitor is connected to or
- * disconnected from the system.
- *
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref monitor_event
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun);
-
-/*! @brief Returns the available video modes for the specified monitor.
- *
- * This function returns an array of all video modes supported by the specified
- * monitor. The returned array is sorted in ascending order, first by color
- * bit depth (the sum of all channel depths) and then by resolution area (the
- * product of width and height).
- *
- * @param[in] monitor The monitor to query.
- * @param[out] count Where to store the number of video modes in the returned
- * array. This is set to zero if an error occurred.
- * @return An array of video modes, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @pointer_lifetime The returned array is allocated and freed by GLFW. You
- * should not free it yourself. It is valid until the specified monitor is
- * disconnected, this function is called again for that monitor or the library
- * is terminated.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref monitor_modes
- * @sa glfwGetVideoMode
- *
- * @since Added in version 1.0.
- * @glfw3 Changed to return an array of modes for a specific monitor.
- *
- * @ingroup monitor
- */
-GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* monitor, int* count);
-
-/*! @brief Returns the current mode of the specified monitor.
- *
- * This function returns the current video mode of the specified monitor. If
- * you have created a full screen window for that monitor, the return value
- * will depend on whether that window is iconified.
- *
- * @param[in] monitor The monitor to query.
- * @return The current mode of the monitor, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @pointer_lifetime The returned array is allocated and freed by GLFW. You
- * should not free it yourself. It is valid until the specified monitor is
- * disconnected or the library is terminated.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref monitor_modes
- * @sa glfwGetVideoModes
- *
- * @since Added in version 3.0. Replaces `glfwGetDesktopMode`.
- *
- * @ingroup monitor
- */
-GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor);
-
-/*! @brief Generates a gamma ramp and sets it for the specified monitor.
- *
- * This function generates a 256-element gamma ramp from the specified exponent
- * and then calls @ref glfwSetGammaRamp with it. The value must be a finite
- * number greater than zero.
- *
- * @param[in] monitor The monitor whose gamma ramp to set.
- * @param[in] gamma The desired exponent.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref monitor_gamma
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma);
-
-/*! @brief Returns the current gamma ramp for the specified monitor.
- *
- * This function returns the current gamma ramp of the specified monitor.
- *
- * @param[in] monitor The monitor to query.
- * @return The current gamma ramp, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @pointer_lifetime The returned structure and its arrays are allocated and
- * freed by GLFW. You should not free them yourself. They are valid until the
- * specified monitor is disconnected, this function is called again for that
- * monitor or the library is terminated.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref monitor_gamma
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor);
-
-/*! @brief Sets the current gamma ramp for the specified monitor.
- *
- * This function sets the current gamma ramp for the specified monitor. The
- * original gamma ramp for that monitor is saved by GLFW the first time this
- * function is called and is restored by @ref glfwTerminate.
- *
- * @param[in] monitor The monitor whose gamma ramp to set.
- * @param[in] ramp The gamma ramp to use.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @remark Gamma ramp sizes other than 256 are not supported by all platforms
- * or graphics hardware.
- *
- * @remark @win32 The gamma ramp size must be 256.
- *
- * @pointer_lifetime The specified gamma ramp is copied before this function
- * returns.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref monitor_gamma
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-GLFWAPI void glfwSetGammaRamp(GLFWmonitor* monitor, const GLFWgammaramp* ramp);
-
-/*! @brief Resets all window hints to their default values.
- *
- * This function resets all window hints to their
- * [default values](@ref window_hints_values).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_hints
- * @sa glfwWindowHint
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI void glfwDefaultWindowHints(void);
-
-/*! @brief Sets the specified window hint to the desired value.
- *
- * This function sets hints for the next call to @ref glfwCreateWindow. The
- * hints, once set, retain their values until changed by a call to @ref
- * glfwWindowHint or @ref glfwDefaultWindowHints, or until the library is
- * terminated.
- *
- * This function does not check whether the specified hint values are valid.
- * If you set hints to invalid values this will instead be reported by the next
- * call to @ref glfwCreateWindow.
- *
- * @param[in] hint The [window hint](@ref window_hints) to set.
- * @param[in] value The new value of the window hint.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_INVALID_ENUM.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_hints
- * @sa glfwDefaultWindowHints
- *
- * @since Added in version 3.0. Replaces `glfwOpenWindowHint`.
- *
- * @ingroup window
- */
-GLFWAPI void glfwWindowHint(int hint, int value);
-
-/*! @brief Creates a window and its associated context.
- *
- * This function creates a window and its associated OpenGL or OpenGL ES
- * context. Most of the options controlling how the window and its context
- * should be created are specified with [window hints](@ref window_hints).
- *
- * Successful creation does not change which context is current. Before you
- * can use the newly created context, you need to
- * [make it current](@ref context_current). For information about the `share`
- * parameter, see @ref context_sharing.
- *
- * The created window, framebuffer and context may differ from what you
- * requested, as not all parameters and hints are
- * [hard constraints](@ref window_hints_hard). This includes the size of the
- * window, especially for full screen windows. To query the actual attributes
- * of the created window, framebuffer and context, see @ref
- * glfwGetWindowAttrib, @ref glfwGetWindowSize and @ref glfwGetFramebufferSize.
- *
- * To create a full screen window, you need to specify the monitor the window
- * will cover. If no monitor is specified, the window will be windowed mode.
- * Unless you have a way for the user to choose a specific monitor, it is
- * recommended that you pick the primary monitor. For more information on how
- * to query connected monitors, see @ref monitor_monitors.
- *
- * For full screen windows, the specified size becomes the resolution of the
- * window's _desired video mode_. As long as a full screen window is not
- * iconified, the supported video mode most closely matching the desired video
- * mode is set for the specified monitor. For more information about full
- * screen windows, including the creation of so called _windowed full screen_
- * or _borderless full screen_ windows, see @ref window_windowed_full_screen.
- *
- * By default, newly created windows use the placement recommended by the
- * window system. To create the window at a specific position, make it
- * initially invisible using the [GLFW_VISIBLE](@ref window_hints_wnd) window
- * hint, set its [position](@ref window_pos) and then [show](@ref window_hide)
- * it.
- *
- * As long as at least one full screen window is not iconified, the screensaver
- * is prohibited from starting.
- *
- * Window systems put limits on window sizes. Very large or very small window
- * dimensions may be overridden by the window system on creation. Check the
- * actual [size](@ref window_size) after creation.
- *
- * The [swap interval](@ref buffer_swap) is not set during window creation and
- * the initial value may vary depending on driver settings and defaults.
- *
- * @param[in] width The desired width, in screen coordinates, of the window.
- * This must be greater than zero.
- * @param[in] height The desired height, in screen coordinates, of the window.
- * This must be greater than zero.
- * @param[in] title The initial, UTF-8 encoded window title.
- * @param[in] monitor The monitor to use for full screen mode, or `NULL` for
- * windowed mode.
- * @param[in] share The window whose context to share resources with, or `NULL`
- * to not share resources.
- * @return The handle of the created window, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE, @ref GLFW_API_UNAVAILABLE, @ref
- * GLFW_VERSION_UNAVAILABLE, @ref GLFW_FORMAT_UNAVAILABLE and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @remark @win32 Window creation will fail if the Microsoft GDI software
- * OpenGL implementation is the only one available.
- *
- * @remark @win32 If the executable has an icon resource named `GLFW_ICON,` it
- * will be set as the initial icon for the window. If no such icon is present,
- * the `IDI_WINLOGO` icon will be used instead. To set a different icon, see
- * @ref glfwSetWindowIcon.
- *
- * @remark @win32 The context to share resources with must not be current on
- * any other thread.
- *
- * @remark @osx The GLFW window has no icon, as it is not a document
- * window, but the dock icon will be the same as the application bundle's icon.
- * For more information on bundles, see the
- * [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/)
- * in the Mac Developer Library.
- *
- * @remark @osx The first time a window is created the menu bar is populated
- * with common commands like Hide, Quit and About. The About entry opens
- * a minimal about dialog with information from the application's bundle. The
- * menu bar can be disabled with a
- * [compile-time option](@ref compile_options_osx).
- *
- * @remark @osx On OS X 10.10 and later the window frame will not be rendered
- * at full resolution on Retina displays unless the `NSHighResolutionCapable`
- * key is enabled in the application bundle's `Info.plist`. For more
- * information, see
- * [High Resolution Guidelines for OS X](https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html)
- * in the Mac Developer Library. The GLFW test and example programs use
- * a custom `Info.plist` template for this, which can be found as
- * `CMake/MacOSXBundleInfo.plist.in` in the source tree.
- *
- * @remark @x11 Some window managers will not respect the placement of
- * initially hidden windows.
- *
- * @remark @x11 Due to the asynchronous nature of X11, it may take a moment for
- * a window to reach its requested state. This means you may not be able to
- * query the final size, position or other attributes directly after window
- * creation.
- *
- * @reentrancy This function must not be called from a callback.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_creation
- * @sa glfwDestroyWindow
- *
- * @since Added in version 3.0. Replaces `glfwOpenWindow`.
- *
- * @ingroup window
- */
-GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, GLFWmonitor* monitor, GLFWwindow* share);
-
-/*! @brief Destroys the specified window and its context.
- *
- * This function destroys the specified window and its context. On calling
- * this function, no further callbacks will be called for that window.
- *
- * If the context of the specified window is current on the main thread, it is
- * detached before being destroyed.
- *
- * @param[in] window The window to destroy.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @note The context of the specified window must not be current on any other
- * thread when this function is called.
- *
- * @reentrancy This function must not be called from a callback.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_creation
- * @sa glfwCreateWindow
- *
- * @since Added in version 3.0. Replaces `glfwCloseWindow`.
- *
- * @ingroup window
- */
-GLFWAPI void glfwDestroyWindow(GLFWwindow* window);
-
-/*! @brief Checks the close flag of the specified window.
- *
- * This function returns the value of the close flag of the specified window.
- *
- * @param[in] window The window to query.
- * @return The value of the close flag.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @sa @ref window_close
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI int glfwWindowShouldClose(GLFWwindow* window);
-
-/*! @brief Sets the close flag of the specified window.
- *
- * This function sets the value of the close flag of the specified window.
- * This can be used to override the user's attempt to close the window, or
- * to signal that it should be closed.
- *
- * @param[in] window The window whose flag to change.
- * @param[in] value The new value.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @sa @ref window_close
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* window, int value);
-
-/*! @brief Sets the title of the specified window.
- *
- * This function sets the window title, encoded as UTF-8, of the specified
- * window.
- *
- * @param[in] window The window whose title to change.
- * @param[in] title The UTF-8 encoded window title.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @remark @osx The window title will not be updated until the next time you
- * process events.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_title
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup window
- */
-GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title);
-
-/*! @brief Sets the icon for the specified window.
- *
- * This function sets the icon of the specified window. If passed an array of
- * candidate images, those of or closest to the sizes desired by the system are
- * selected. If no images are specified, the window reverts to its default
- * icon.
- *
- * The desired image sizes varies depending on platform and system settings.
- * The selected images will be rescaled as needed. Good sizes include 16x16,
- * 32x32 and 48x48.
- *
- * @param[in] window The window whose icon to set.
- * @param[in] count The number of images in the specified array, or zero to
- * revert to the default window icon.
- * @param[in] images The images to create the icon from. This is ignored if
- * count is zero.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @pointer_lifetime The specified image data is copied before this function
- * returns.
- *
- * @remark @osx The GLFW window has no icon, as it is not a document
- * window, so this function does nothing. The dock icon will be the same as
- * the application bundle's icon. For more information on bundles, see the
- * [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/)
- * in the Mac Developer Library.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_icon
- *
- * @since Added in version 3.2.
- *
- * @ingroup window
- */
-GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* images);
-
-/*! @brief Retrieves the position of the client area of the specified window.
- *
- * This function retrieves the position, in screen coordinates, of the
- * upper-left corner of the client area of the specified window.
- *
- * Any or all of the position arguments may be `NULL`. If an error occurs, all
- * non-`NULL` position arguments will be set to zero.
- *
- * @param[in] window The window to query.
- * @param[out] xpos Where to store the x-coordinate of the upper-left corner of
- * the client area, or `NULL`.
- * @param[out] ypos Where to store the y-coordinate of the upper-left corner of
- * the client area, or `NULL`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_pos
- * @sa glfwSetWindowPos
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos);
-
-/*! @brief Sets the position of the client area of the specified window.
- *
- * This function sets the position, in screen coordinates, of the upper-left
- * corner of the client area of the specified windowed mode window. If the
- * window is a full screen window, this function does nothing.
- *
- * __Do not use this function__ to move an already visible window unless you
- * have very good reasons for doing so, as it will confuse and annoy the user.
- *
- * The window manager may put limits on what positions are allowed. GLFW
- * cannot and should not override these limits.
- *
- * @param[in] window The window to query.
- * @param[in] xpos The x-coordinate of the upper-left corner of the client area.
- * @param[in] ypos The y-coordinate of the upper-left corner of the client area.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_pos
- * @sa glfwGetWindowPos
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup window
- */
-GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos);
-
-/*! @brief Retrieves the size of the client area of the specified window.
- *
- * This function retrieves the size, in screen coordinates, of the client area
- * of the specified window. If you wish to retrieve the size of the
- * framebuffer of the window in pixels, see @ref glfwGetFramebufferSize.
- *
- * Any or all of the size arguments may be `NULL`. If an error occurs, all
- * non-`NULL` size arguments will be set to zero.
- *
- * @param[in] window The window whose size to retrieve.
- * @param[out] width Where to store the width, in screen coordinates, of the
- * client area, or `NULL`.
- * @param[out] height Where to store the height, in screen coordinates, of the
- * client area, or `NULL`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_size
- * @sa glfwSetWindowSize
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup window
- */
-GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height);
-
-/*! @brief Sets the size limits of the specified window.
- *
- * This function sets the size limits of the client area of the specified
- * window. If the window is full screen, the size limits only take effect
- * once it is made windowed. If the window is not resizable, this function
- * does nothing.
- *
- * The size limits are applied immediately to a windowed mode window and may
- * cause it to be resized.
- *
- * The maximum dimensions must be greater than or equal to the minimum
- * dimensions and all must be greater than or equal to zero.
- *
- * @param[in] window The window to set limits for.
- * @param[in] minwidth The minimum width, in screen coordinates, of the client
- * area, or `GLFW_DONT_CARE`.
- * @param[in] minheight The minimum height, in screen coordinates, of the
- * client area, or `GLFW_DONT_CARE`.
- * @param[in] maxwidth The maximum width, in screen coordinates, of the client
- * area, or `GLFW_DONT_CARE`.
- * @param[in] maxheight The maximum height, in screen coordinates, of the
- * client area, or `GLFW_DONT_CARE`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.
- *
- * @remark If you set size limits and an aspect ratio that conflict, the
- * results are undefined.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_sizelimits
- * @sa glfwSetWindowAspectRatio
- *
- * @since Added in version 3.2.
- *
- * @ingroup window
- */
-GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight);
-
-/*! @brief Sets the aspect ratio of the specified window.
- *
- * This function sets the required aspect ratio of the client area of the
- * specified window. If the window is full screen, the aspect ratio only takes
- * effect once it is made windowed. If the window is not resizable, this
- * function does nothing.
- *
- * The aspect ratio is specified as a numerator and a denominator and both
- * values must be greater than zero. For example, the common 16:9 aspect ratio
- * is specified as 16 and 9, respectively.
- *
- * If the numerator and denominator is set to `GLFW_DONT_CARE` then the aspect
- * ratio limit is disabled.
- *
- * The aspect ratio is applied immediately to a windowed mode window and may
- * cause it to be resized.
- *
- * @param[in] window The window to set limits for.
- * @param[in] numer The numerator of the desired aspect ratio, or
- * `GLFW_DONT_CARE`.
- * @param[in] denom The denominator of the desired aspect ratio, or
- * `GLFW_DONT_CARE`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.
- *
- * @remark If you set size limits and an aspect ratio that conflict, the
- * results are undefined.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_sizelimits
- * @sa glfwSetWindowSizeLimits
- *
- * @since Added in version 3.2.
- *
- * @ingroup window
- */
-GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom);
-
-/*! @brief Sets the size of the client area of the specified window.
- *
- * This function sets the size, in screen coordinates, of the client area of
- * the specified window.
- *
- * For full screen windows, this function updates the resolution of its desired
- * video mode and switches to the video mode closest to it, without affecting
- * the window's context. As the context is unaffected, the bit depths of the
- * framebuffer remain unchanged.
- *
- * If you wish to update the refresh rate of the desired video mode in addition
- * to its resolution, see @ref glfwSetWindowMonitor.
- *
- * The window manager may put limits on what sizes are allowed. GLFW cannot
- * and should not override these limits.
- *
- * @param[in] window The window to resize.
- * @param[in] width The desired width, in screen coordinates, of the window
- * client area.
- * @param[in] height The desired height, in screen coordinates, of the window
- * client area.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_size
- * @sa glfwGetWindowSize
- * @sa glfwSetWindowMonitor
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup window
- */
-GLFWAPI void glfwSetWindowSize(GLFWwindow* window, int width, int height);
-
-/*! @brief Retrieves the size of the framebuffer of the specified window.
- *
- * This function retrieves the size, in pixels, of the framebuffer of the
- * specified window. If you wish to retrieve the size of the window in screen
- * coordinates, see @ref glfwGetWindowSize.
- *
- * Any or all of the size arguments may be `NULL`. If an error occurs, all
- * non-`NULL` size arguments will be set to zero.
- *
- * @param[in] window The window whose framebuffer to query.
- * @param[out] width Where to store the width, in pixels, of the framebuffer,
- * or `NULL`.
- * @param[out] height Where to store the height, in pixels, of the framebuffer,
- * or `NULL`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_fbsize
- * @sa glfwSetFramebufferSizeCallback
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI void glfwGetFramebufferSize(GLFWwindow* window, int* width, int* height);
-
-/*! @brief Retrieves the size of the frame of the window.
- *
- * This function retrieves the size, in screen coordinates, of each edge of the
- * frame of the specified window. This size includes the title bar, if the
- * window has one. The size of the frame may vary depending on the
- * [window-related hints](@ref window_hints_wnd) used to create it.
- *
- * Because this function retrieves the size of each window frame edge and not
- * the offset along a particular coordinate axis, the retrieved values will
- * always be zero or positive.
- *
- * Any or all of the size arguments may be `NULL`. If an error occurs, all
- * non-`NULL` size arguments will be set to zero.
- *
- * @param[in] window The window whose frame size to query.
- * @param[out] left Where to store the size, in screen coordinates, of the left
- * edge of the window frame, or `NULL`.
- * @param[out] top Where to store the size, in screen coordinates, of the top
- * edge of the window frame, or `NULL`.
- * @param[out] right Where to store the size, in screen coordinates, of the
- * right edge of the window frame, or `NULL`.
- * @param[out] bottom Where to store the size, in screen coordinates, of the
- * bottom edge of the window frame, or `NULL`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_size
- *
- * @since Added in version 3.1.
- *
- * @ingroup window
- */
-GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* window, int* left, int* top, int* right, int* bottom);
-
-/*! @brief Iconifies the specified window.
- *
- * This function iconifies (minimizes) the specified window if it was
- * previously restored. If the window is already iconified, this function does
- * nothing.
- *
- * If the specified window is a full screen window, the original monitor
- * resolution is restored until the window is restored.
- *
- * @param[in] window The window to iconify.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_iconify
- * @sa glfwRestoreWindow
- * @sa glfwMaximizeWindow
- *
- * @since Added in version 2.1.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup window
- */
-GLFWAPI void glfwIconifyWindow(GLFWwindow* window);
-
-/*! @brief Restores the specified window.
- *
- * This function restores the specified window if it was previously iconified
- * (minimized) or maximized. If the window is already restored, this function
- * does nothing.
- *
- * If the specified window is a full screen window, the resolution chosen for
- * the window is restored on the selected monitor.
- *
- * @param[in] window The window to restore.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_iconify
- * @sa glfwIconifyWindow
- * @sa glfwMaximizeWindow
- *
- * @since Added in version 2.1.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup window
- */
-GLFWAPI void glfwRestoreWindow(GLFWwindow* window);
-
-/*! @brief Maximizes the specified window.
- *
- * This function maximizes the specified window if it was previously not
- * maximized. If the window is already maximized, this function does nothing.
- *
- * If the specified window is a full screen window, this function does nothing.
- *
- * @param[in] window The window to maximize.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @par Thread Safety
- * This function may only be called from the main thread.
- *
- * @sa @ref window_iconify
- * @sa glfwIconifyWindow
- * @sa glfwRestoreWindow
- *
- * @since Added in GLFW 3.2.
- *
- * @ingroup window
- */
-GLFWAPI void glfwMaximizeWindow(GLFWwindow* window);
-
-/*! @brief Makes the specified window visible.
- *
- * This function makes the specified window visible if it was previously
- * hidden. If the window is already visible or is in full screen mode, this
- * function does nothing.
- *
- * @param[in] window The window to make visible.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_hide
- * @sa glfwHideWindow
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI void glfwShowWindow(GLFWwindow* window);
-
-/*! @brief Hides the specified window.
- *
- * This function hides the specified window if it was previously visible. If
- * the window is already hidden or is in full screen mode, this function does
- * nothing.
- *
- * @param[in] window The window to hide.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_hide
- * @sa glfwShowWindow
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI void glfwHideWindow(GLFWwindow* window);
-
-/*! @brief Brings the specified window to front and sets input focus.
- *
- * This function brings the specified window to front and sets input focus.
- * The window should already be visible and not iconified.
- *
- * By default, both windowed and full screen mode windows are focused when
- * initially created. Set the [GLFW_FOCUSED](@ref window_hints_wnd) to disable
- * this behavior.
- *
- * __Do not use this function__ to steal focus from other applications unless
- * you are certain that is what the user wants. Focus stealing can be
- * extremely disruptive.
- *
- * @param[in] window The window to give input focus.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_focus
- *
- * @since Added in version 3.2.
- *
- * @ingroup window
- */
-GLFWAPI void glfwFocusWindow(GLFWwindow* window);
-
-/*! @brief Returns the monitor that the window uses for full screen mode.
- *
- * This function returns the handle of the monitor that the specified window is
- * in full screen on.
- *
- * @param[in] window The window to query.
- * @return The monitor, or `NULL` if the window is in windowed mode or an error
- * occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_monitor
- * @sa glfwSetWindowMonitor
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window);
-
-/*! @brief Sets the mode, monitor, video mode and placement of a window.
- *
- * This function sets the monitor that the window uses for full screen mode or,
- * if the monitor is `NULL`, makes it windowed mode.
- *
- * When setting a monitor, this function updates the width, height and refresh
- * rate of the desired video mode and switches to the video mode closest to it.
- * The window position is ignored when setting a monitor.
- *
- * When the monitor is `NULL`, the position, width and height are used to
- * place the window client area. The refresh rate is ignored when no monitor
- * is specified.
- *
- * If you only wish to update the resolution of a full screen window or the
- * size of a windowed mode window, see @ref glfwSetWindowSize.
- *
- * When a window transitions from full screen to windowed mode, this function
- * restores any previous window settings such as whether it is decorated,
- * floating, resizable, has size or aspect ratio limits, etc..
- *
- * @param[in] window The window whose monitor, size or video mode to set.
- * @param[in] monitor The desired monitor, or `NULL` to set windowed mode.
- * @param[in] xpos The desired x-coordinate of the upper-left corner of the
- * client area.
- * @param[in] ypos The desired y-coordinate of the upper-left corner of the
- * client area.
- * @param[in] width The desired with, in screen coordinates, of the client area
- * or video mode.
- * @param[in] height The desired height, in screen coordinates, of the client
- * area or video mode.
- * @param[in] refreshRate The desired refresh rate, in Hz, of the video mode,
- * or `GLFW_DONT_CARE`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_monitor
- * @sa @ref window_full_screen
- * @sa glfwGetWindowMonitor
- * @sa glfwSetWindowSize
- *
- * @since Added in version 3.2.
- *
- * @ingroup window
- */
-GLFWAPI void glfwSetWindowMonitor(GLFWwindow* window, GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);
-
-/*! @brief Returns an attribute of the specified window.
- *
- * This function returns the value of an attribute of the specified window or
- * its OpenGL or OpenGL ES context.
- *
- * @param[in] window The window to query.
- * @param[in] attrib The [window attribute](@ref window_attribs) whose value to
- * return.
- * @return The value of the attribute, or zero if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
- *
- * @remark Framebuffer related hints are not window attributes. See @ref
- * window_attribs_fb for more information.
- *
- * @remark Zero is a valid value for many window and context related
- * attributes so you cannot use a return value of zero as an indication of
- * errors. However, this function should not fail as long as it is passed
- * valid arguments and the library has been [initialized](@ref intro_init).
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_attribs
- *
- * @since Added in version 3.0. Replaces `glfwGetWindowParam` and
- * `glfwGetGLVersion`.
- *
- * @ingroup window
- */
-GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib);
-
-/*! @brief Sets the user pointer of the specified window.
- *
- * This function sets the user-defined pointer of the specified window. The
- * current value is retained until the window is destroyed. The initial value
- * is `NULL`.
- *
- * @param[in] window The window whose pointer to set.
- * @param[in] pointer The new value.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @sa @ref window_userptr
- * @sa glfwGetWindowUserPointer
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* window, void* pointer);
-
-/*! @brief Returns the user pointer of the specified window.
- *
- * This function returns the current value of the user-defined pointer of the
- * specified window. The initial value is `NULL`.
- *
- * @param[in] window The window whose pointer to return.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @sa @ref window_userptr
- * @sa glfwSetWindowUserPointer
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window);
-
-/*! @brief Sets the position callback for the specified window.
- *
- * This function sets the position callback of the specified window, which is
- * called when the window is moved. The callback is provided with the screen
- * position of the upper-left corner of the client area of the window.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_pos
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* window, GLFWwindowposfun cbfun);
-
-/*! @brief Sets the size callback for the specified window.
- *
- * This function sets the size callback of the specified window, which is
- * called when the window is resized. The callback is provided with the size,
- * in screen coordinates, of the client area of the window.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_size
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle parameter and return value.
- *
- * @ingroup window
- */
-GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwindowsizefun cbfun);
-
-/*! @brief Sets the close callback for the specified window.
- *
- * This function sets the close callback of the specified window, which is
- * called when the user attempts to close the window, for example by clicking
- * the close widget in the title bar.
- *
- * The close flag is set before this callback is called, but you can modify it
- * at any time with @ref glfwSetWindowShouldClose.
- *
- * The close callback is not triggered by @ref glfwDestroyWindow.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @remark @osx Selecting Quit from the application menu will trigger the close
- * callback for all windows.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_close
- *
- * @since Added in version 2.5.
- * @glfw3 Added window handle parameter and return value.
- *
- * @ingroup window
- */
-GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwindowclosefun cbfun);
-
-/*! @brief Sets the refresh callback for the specified window.
- *
- * This function sets the refresh callback of the specified window, which is
- * called when the client area of the window needs to be redrawn, for example
- * if the window has been exposed after having been covered by another window.
- *
- * On compositing window systems such as Aero, Compiz or Aqua, where the window
- * contents are saved off-screen, this callback may be called only very
- * infrequently or never at all.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_refresh
- *
- * @since Added in version 2.5.
- * @glfw3 Added window handle parameter and return value.
- *
- * @ingroup window
- */
-GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* window, GLFWwindowrefreshfun cbfun);
-
-/*! @brief Sets the focus callback for the specified window.
- *
- * This function sets the focus callback of the specified window, which is
- * called when the window gains or loses input focus.
- *
- * After the focus callback is called for a window that lost input focus,
- * synthetic key and mouse button release events will be generated for all such
- * that had been pressed. For more information, see @ref glfwSetKeyCallback
- * and @ref glfwSetMouseButtonCallback.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_focus
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwindowfocusfun cbfun);
-
-/*! @brief Sets the iconify callback for the specified window.
- *
- * This function sets the iconification callback of the specified window, which
- * is called when the window is iconified or restored.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_iconify
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* window, GLFWwindowiconifyfun cbfun);
-
-/*! @brief Sets the framebuffer resize callback for the specified window.
- *
- * This function sets the framebuffer resize callback of the specified window,
- * which is called when the framebuffer of the specified window is resized.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_fbsize
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* window, GLFWframebuffersizefun cbfun);
-
-/*! @brief Processes all pending events.
- *
- * This function processes only those events that are already in the event
- * queue and then returns immediately. Processing events will cause the window
- * and input callbacks associated with those events to be called.
- *
- * On some platforms, a window move, resize or menu operation will cause event
- * processing to block. This is due to how event processing is designed on
- * those platforms. You can use the
- * [window refresh callback](@ref window_refresh) to redraw the contents of
- * your window when necessary during such operations.
- *
- * On some platforms, certain events are sent directly to the application
- * without going through the event queue, causing callbacks to be called
- * outside of a call to one of the event processing functions.
- *
- * Event processing is not required for joystick input to work.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @reentrancy This function must not be called from a callback.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref events
- * @sa glfwWaitEvents
- * @sa glfwWaitEventsTimeout
- *
- * @since Added in version 1.0.
- *
- * @ingroup window
- */
-GLFWAPI void glfwPollEvents(void);
-
-/*! @brief Waits until events are queued and processes them.
- *
- * This function puts the calling thread to sleep until at least one event is
- * available in the event queue. Once one or more events are available,
- * it behaves exactly like @ref glfwPollEvents, i.e. the events in the queue
- * are processed and the function then returns immediately. Processing events
- * will cause the window and input callbacks associated with those events to be
- * called.
- *
- * Since not all events are associated with callbacks, this function may return
- * without a callback having been called even if you are monitoring all
- * callbacks.
- *
- * On some platforms, a window move, resize or menu operation will cause event
- * processing to block. This is due to how event processing is designed on
- * those platforms. You can use the
- * [window refresh callback](@ref window_refresh) to redraw the contents of
- * your window when necessary during such operations.
- *
- * On some platforms, certain callbacks may be called outside of a call to one
- * of the event processing functions.
- *
- * If no windows exist, this function returns immediately. For synchronization
- * of threads in applications that do not create windows, use your threading
- * library of choice.
- *
- * Event processing is not required for joystick input to work.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @reentrancy This function must not be called from a callback.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref events
- * @sa glfwPollEvents
- * @sa glfwWaitEventsTimeout
- *
- * @since Added in version 2.5.
- *
- * @ingroup window
- */
-GLFWAPI void glfwWaitEvents(void);
-
-/*! @brief Waits with timeout until events are queued and processes them.
- *
- * This function puts the calling thread to sleep until at least one event is
- * available in the event queue, or until the specified timeout is reached. If
- * one or more events are available, it behaves exactly like @ref
- * glfwPollEvents, i.e. the events in the queue are processed and the function
- * then returns immediately. Processing events will cause the window and input
- * callbacks associated with those events to be called.
- *
- * The timeout value must be a positive finite number.
- *
- * Since not all events are associated with callbacks, this function may return
- * without a callback having been called even if you are monitoring all
- * callbacks.
- *
- * On some platforms, a window move, resize or menu operation will cause event
- * processing to block. This is due to how event processing is designed on
- * those platforms. You can use the
- * [window refresh callback](@ref window_refresh) to redraw the contents of
- * your window when necessary during such operations.
- *
- * On some platforms, certain callbacks may be called outside of a call to one
- * of the event processing functions.
- *
- * If no windows exist, this function returns immediately. For synchronization
- * of threads in applications that do not create windows, use your threading
- * library of choice.
- *
- * Event processing is not required for joystick input to work.
- *
- * @param[in] timeout The maximum amount of time, in seconds, to wait.
- *
- * @reentrancy This function must not be called from a callback.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref events
- * @sa glfwPollEvents
- * @sa glfwWaitEvents
- *
- * @since Added in version 3.2.
- *
- * @ingroup window
- */
-GLFWAPI void glfwWaitEventsTimeout(double timeout);
-
-/*! @brief Posts an empty event to the event queue.
- *
- * This function posts an empty event from the current thread to the event
- * queue, causing @ref glfwWaitEvents to return.
- *
- * If no windows exist, this function returns immediately. For synchronization
- * of threads in applications that do not create windows, use your threading
- * library of choice.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref events
- * @sa glfwWaitEvents
- *
- * @since Added in version 3.1.
- *
- * @ingroup window
- */
-GLFWAPI void glfwPostEmptyEvent(void);
-
-/*! @brief Returns the value of an input option for the specified window.
- *
- * This function returns the value of an input option for the specified window.
- * The mode must be one of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or
- * `GLFW_STICKY_MOUSE_BUTTONS`.
- *
- * @param[in] window The window to query.
- * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or
- * `GLFW_STICKY_MOUSE_BUTTONS`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_INVALID_ENUM.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa glfwSetInputMode
- *
- * @since Added in version 3.0.
- *
- * @ingroup input
- */
-GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);
-
-/*! @brief Sets an input option for the specified window.
- *
- * This function sets an input mode option for the specified window. The mode
- * must be one of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or
- * `GLFW_STICKY_MOUSE_BUTTONS`.
- *
- * If the mode is `GLFW_CURSOR`, the value must be one of the following cursor
- * modes:
- * - `GLFW_CURSOR_NORMAL` makes the cursor visible and behaving normally.
- * - `GLFW_CURSOR_HIDDEN` makes the cursor invisible when it is over the client
- * area of the window but does not restrict the cursor from leaving.
- * - `GLFW_CURSOR_DISABLED` hides and grabs the cursor, providing virtual
- * and unlimited cursor movement. This is useful for implementing for
- * example 3D camera controls.
- *
- * If the mode is `GLFW_STICKY_KEYS`, the value must be either `GLFW_TRUE` to
- * enable sticky keys, or `GLFW_FALSE` to disable it. If sticky keys are
- * enabled, a key press will ensure that @ref glfwGetKey returns `GLFW_PRESS`
- * the next time it is called even if the key had been released before the
- * call. This is useful when you are only interested in whether keys have been
- * pressed but not when or in which order.
- *
- * If the mode is `GLFW_STICKY_MOUSE_BUTTONS`, the value must be either
- * `GLFW_TRUE` to enable sticky mouse buttons, or `GLFW_FALSE` to disable it.
- * If sticky mouse buttons are enabled, a mouse button press will ensure that
- * @ref glfwGetMouseButton returns `GLFW_PRESS` the next time it is called even
- * if the mouse button had been released before the call. This is useful when
- * you are only interested in whether mouse buttons have been pressed but not
- * when or in which order.
- *
- * @param[in] window The window whose input mode to set.
- * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or
- * `GLFW_STICKY_MOUSE_BUTTONS`.
- * @param[in] value The new value of the specified input mode.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa glfwGetInputMode
- *
- * @since Added in version 3.0. Replaces `glfwEnable` and `glfwDisable`.
- *
- * @ingroup input
- */
-GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value);
-
-/*! @brief Returns the localized name of the specified printable key.
- *
- * This function returns the localized name of the specified printable key.
- * This is intended for displaying key bindings to the user.
- *
- * If the key is `GLFW_KEY_UNKNOWN`, the scancode is used instead, otherwise
- * the scancode is ignored. If a non-printable key or (if the key is
- * `GLFW_KEY_UNKNOWN`) a scancode that maps to a non-printable key is
- * specified, this function returns `NULL`.
- *
- * This behavior allows you to pass in the arguments passed to the
- * [key callback](@ref input_key) without modification.
- *
- * The printable keys are:
- * - `GLFW_KEY_APOSTROPHE`
- * - `GLFW_KEY_COMMA`
- * - `GLFW_KEY_MINUS`
- * - `GLFW_KEY_PERIOD`
- * - `GLFW_KEY_SLASH`
- * - `GLFW_KEY_SEMICOLON`
- * - `GLFW_KEY_EQUAL`
- * - `GLFW_KEY_LEFT_BRACKET`
- * - `GLFW_KEY_RIGHT_BRACKET`
- * - `GLFW_KEY_BACKSLASH`
- * - `GLFW_KEY_WORLD_1`
- * - `GLFW_KEY_WORLD_2`
- * - `GLFW_KEY_0` to `GLFW_KEY_9`
- * - `GLFW_KEY_A` to `GLFW_KEY_Z`
- * - `GLFW_KEY_KP_0` to `GLFW_KEY_KP_9`
- * - `GLFW_KEY_KP_DECIMAL`
- * - `GLFW_KEY_KP_DIVIDE`
- * - `GLFW_KEY_KP_MULTIPLY`
- * - `GLFW_KEY_KP_SUBTRACT`
- * - `GLFW_KEY_KP_ADD`
- * - `GLFW_KEY_KP_EQUAL`
- *
- * @param[in] key The key to query, or `GLFW_KEY_UNKNOWN`.
- * @param[in] scancode The scancode of the key to query.
- * @return The localized name of the key, or `NULL`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @pointer_lifetime The returned string is allocated and freed by GLFW. You
- * should not free it yourself. It is valid until the next call to @ref
- * glfwGetKeyName, or until the library is terminated.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref input_key_name
- *
- * @since Added in version 3.2.
- *
- * @ingroup input
- */
-GLFWAPI const char* glfwGetKeyName(int key, int scancode);
-
-/*! @brief Returns the last reported state of a keyboard key for the specified
- * window.
- *
- * This function returns the last state reported for the specified key to the
- * specified window. The returned state is one of `GLFW_PRESS` or
- * `GLFW_RELEASE`. The higher-level action `GLFW_REPEAT` is only reported to
- * the key callback.
- *
- * If the `GLFW_STICKY_KEYS` input mode is enabled, this function returns
- * `GLFW_PRESS` the first time you call it for a key that was pressed, even if
- * that key has already been released.
- *
- * The key functions deal with physical keys, with [key tokens](@ref keys)
- * named after their use on the standard US keyboard layout. If you want to
- * input text, use the Unicode character callback instead.
- *
- * The [modifier key bit masks](@ref mods) are not key tokens and cannot be
- * used with this function.
- *
- * __Do not use this function__ to implement [text input](@ref input_char).
- *
- * @param[in] window The desired window.
- * @param[in] key The desired [keyboard key](@ref keys). `GLFW_KEY_UNKNOWN` is
- * not a valid key for this function.
- * @return One of `GLFW_PRESS` or `GLFW_RELEASE`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_INVALID_ENUM.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref input_key
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup input
- */
-GLFWAPI int glfwGetKey(GLFWwindow* window, int key);
-
-/*! @brief Returns the last reported state of a mouse button for the specified
- * window.
- *
- * This function returns the last state reported for the specified mouse button
- * to the specified window. The returned state is one of `GLFW_PRESS` or
- * `GLFW_RELEASE`.
- *
- * If the `GLFW_STICKY_MOUSE_BUTTONS` input mode is enabled, this function
- * `GLFW_PRESS` the first time you call it for a mouse button that was pressed,
- * even if that mouse button has already been released.
- *
- * @param[in] window The desired window.
- * @param[in] button The desired [mouse button](@ref buttons).
- * @return One of `GLFW_PRESS` or `GLFW_RELEASE`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_INVALID_ENUM.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref input_mouse_button
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup input
- */
-GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button);
-
-/*! @brief Retrieves the position of the cursor relative to the client area of
- * the window.
- *
- * This function returns the position of the cursor, in screen coordinates,
- * relative to the upper-left corner of the client area of the specified
- * window.
- *
- * If the cursor is disabled (with `GLFW_CURSOR_DISABLED`) then the cursor
- * position is unbounded and limited only by the minimum and maximum values of
- * a `double`.
- *
- * The coordinate can be converted to their integer equivalents with the
- * `floor` function. Casting directly to an integer type works for positive
- * coordinates, but fails for negative ones.
- *
- * Any or all of the position arguments may be `NULL`. If an error occurs, all
- * non-`NULL` position arguments will be set to zero.
- *
- * @param[in] window The desired window.
- * @param[out] xpos Where to store the cursor x-coordinate, relative to the
- * left edge of the client area, or `NULL`.
- * @param[out] ypos Where to store the cursor y-coordinate, relative to the to
- * top edge of the client area, or `NULL`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref cursor_pos
- * @sa glfwSetCursorPos
- *
- * @since Added in version 3.0. Replaces `glfwGetMousePos`.
- *
- * @ingroup input
- */
-GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos);
-
-/*! @brief Sets the position of the cursor, relative to the client area of the
- * window.
- *
- * This function sets the position, in screen coordinates, of the cursor
- * relative to the upper-left corner of the client area of the specified
- * window. The window must have input focus. If the window does not have
- * input focus when this function is called, it fails silently.
- *
- * __Do not use this function__ to implement things like camera controls. GLFW
- * already provides the `GLFW_CURSOR_DISABLED` cursor mode that hides the
- * cursor, transparently re-centers it and provides unconstrained cursor
- * motion. See @ref glfwSetInputMode for more information.
- *
- * If the cursor mode is `GLFW_CURSOR_DISABLED` then the cursor position is
- * unconstrained and limited only by the minimum and maximum values of
- * a `double`.
- *
- * @param[in] window The desired window.
- * @param[in] xpos The desired x-coordinate, relative to the left edge of the
- * client area.
- * @param[in] ypos The desired y-coordinate, relative to the top edge of the
- * client area.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref cursor_pos
- * @sa glfwGetCursorPos
- *
- * @since Added in version 3.0. Replaces `glfwSetMousePos`.
- *
- * @ingroup input
- */
-GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos);
-
-/*! @brief Creates a custom cursor.
- *
- * Creates a new custom cursor image that can be set for a window with @ref
- * glfwSetCursor. The cursor can be destroyed with @ref glfwDestroyCursor.
- * Any remaining cursors are destroyed by @ref glfwTerminate.
- *
- * The pixels are 32-bit, little-endian, non-premultiplied RGBA, i.e. eight
- * bits per channel. They are arranged canonically as packed sequential rows,
- * starting from the top-left corner.
- *
- * The cursor hotspot is specified in pixels, relative to the upper-left corner
- * of the cursor image. Like all other coordinate systems in GLFW, the X-axis
- * points to the right and the Y-axis points down.
- *
- * @param[in] image The desired cursor image.
- * @param[in] xhot The desired x-coordinate, in pixels, of the cursor hotspot.
- * @param[in] yhot The desired y-coordinate, in pixels, of the cursor hotspot.
- * @return The handle of the created cursor, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @pointer_lifetime The specified image data is copied before this function
- * returns.
- *
- * @reentrancy This function must not be called from a callback.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref cursor_object
- * @sa glfwDestroyCursor
- * @sa glfwCreateStandardCursor
- *
- * @since Added in version 3.1.
- *
- * @ingroup input
- */
-GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot);
-
-/*! @brief Creates a cursor with a standard shape.
- *
- * Returns a cursor with a [standard shape](@ref shapes), that can be set for
- * a window with @ref glfwSetCursor.
- *
- * @param[in] shape One of the [standard shapes](@ref shapes).
- * @return A new cursor ready to use or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
- *
- * @reentrancy This function must not be called from a callback.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref cursor_object
- * @sa glfwCreateCursor
- *
- * @since Added in version 3.1.
- *
- * @ingroup input
- */
-GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape);
-
-/*! @brief Destroys a cursor.
- *
- * This function destroys a cursor previously created with @ref
- * glfwCreateCursor. Any remaining cursors will be destroyed by @ref
- * glfwTerminate.
- *
- * @param[in] cursor The cursor object to destroy.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @reentrancy This function must not be called from a callback.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref cursor_object
- * @sa glfwCreateCursor
- *
- * @since Added in version 3.1.
- *
- * @ingroup input
- */
-GLFWAPI void glfwDestroyCursor(GLFWcursor* cursor);
-
-/*! @brief Sets the cursor for the window.
- *
- * This function sets the cursor image to be used when the cursor is over the
- * client area of the specified window. The set cursor will only be visible
- * when the [cursor mode](@ref cursor_mode) of the window is
- * `GLFW_CURSOR_NORMAL`.
- *
- * On some platforms, the set cursor may not be visible unless the window also
- * has input focus.
- *
- * @param[in] window The window to set the cursor for.
- * @param[in] cursor The cursor to set, or `NULL` to switch back to the default
- * arrow cursor.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref cursor_object
- *
- * @since Added in version 3.1.
- *
- * @ingroup input
- */
-GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor);
-
-/*! @brief Sets the key callback.
- *
- * This function sets the key callback of the specified window, which is called
- * when a key is pressed, repeated or released.
- *
- * The key functions deal with physical keys, with layout independent
- * [key tokens](@ref keys) named after their values in the standard US keyboard
- * layout. If you want to input text, use the
- * [character callback](@ref glfwSetCharCallback) instead.
- *
- * When a window loses input focus, it will generate synthetic key release
- * events for all pressed keys. You can tell these events from user-generated
- * events by the fact that the synthetic ones are generated after the focus
- * loss event has been processed, i.e. after the
- * [window focus callback](@ref glfwSetWindowFocusCallback) has been called.
- *
- * The scancode of a key is specific to that platform or sometimes even to that
- * machine. Scancodes are intended to allow users to bind keys that don't have
- * a GLFW key token. Such keys have `key` set to `GLFW_KEY_UNKNOWN`, their
- * state is not saved and so it cannot be queried with @ref glfwGetKey.
- *
- * Sometimes GLFW needs to generate synthetic key events, in which case the
- * scancode may be zero.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new key callback, or `NULL` to remove the currently
- * set callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref input_key
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle parameter and return value.
- *
- * @ingroup input
- */
-GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun cbfun);
-
-/*! @brief Sets the Unicode character callback.
- *
- * This function sets the character callback of the specified window, which is
- * called when a Unicode character is input.
- *
- * The character callback is intended for Unicode text input. As it deals with
- * characters, it is keyboard layout dependent, whereas the
- * [key callback](@ref glfwSetKeyCallback) is not. Characters do not map 1:1
- * to physical keys, as a key may produce zero, one or more characters. If you
- * want to know whether a specific physical key was pressed or released, see
- * the key callback instead.
- *
- * The character callback behaves as system text input normally does and will
- * not be called if modifier keys are held down that would prevent normal text
- * input on that platform, for example a Super (Command) key on OS X or Alt key
- * on Windows. There is a
- * [character with modifiers callback](@ref glfwSetCharModsCallback) that
- * receives these events.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref input_char
- *
- * @since Added in version 2.4.
- * @glfw3 Added window handle parameter and return value.
- *
- * @ingroup input
- */
-GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* window, GLFWcharfun cbfun);
-
-/*! @brief Sets the Unicode character with modifiers callback.
- *
- * This function sets the character with modifiers callback of the specified
- * window, which is called when a Unicode character is input regardless of what
- * modifier keys are used.
- *
- * The character with modifiers callback is intended for implementing custom
- * Unicode character input. For regular Unicode text input, see the
- * [character callback](@ref glfwSetCharCallback). Like the character
- * callback, the character with modifiers callback deals with characters and is
- * keyboard layout dependent. Characters do not map 1:1 to physical keys, as
- * a key may produce zero, one or more characters. If you want to know whether
- * a specific physical key was pressed or released, see the
- * [key callback](@ref glfwSetKeyCallback) instead.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or an
- * error occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref input_char
- *
- * @since Added in version 3.1.
- *
- * @ingroup input
- */
-GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmodsfun cbfun);
-
-/*! @brief Sets the mouse button callback.
- *
- * This function sets the mouse button callback of the specified window, which
- * is called when a mouse button is pressed or released.
- *
- * When a window loses input focus, it will generate synthetic mouse button
- * release events for all pressed mouse buttons. You can tell these events
- * from user-generated events by the fact that the synthetic ones are generated
- * after the focus loss event has been processed, i.e. after the
- * [window focus callback](@ref glfwSetWindowFocusCallback) has been called.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref input_mouse_button
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle parameter and return value.
- *
- * @ingroup input
- */
-GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* window, GLFWmousebuttonfun cbfun);
-
-/*! @brief Sets the cursor position callback.
- *
- * This function sets the cursor position callback of the specified window,
- * which is called when the cursor is moved. The callback is provided with the
- * position, in screen coordinates, relative to the upper-left corner of the
- * client area of the window.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref cursor_pos
- *
- * @since Added in version 3.0. Replaces `glfwSetMousePosCallback`.
- *
- * @ingroup input
- */
-GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* window, GLFWcursorposfun cbfun);
-
-/*! @brief Sets the cursor enter/exit callback.
- *
- * This function sets the cursor boundary crossing callback of the specified
- * window, which is called when the cursor enters or leaves the client area of
- * the window.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref cursor_enter
- *
- * @since Added in version 3.0.
- *
- * @ingroup input
- */
-GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* window, GLFWcursorenterfun cbfun);
-
-/*! @brief Sets the scroll callback.
- *
- * This function sets the scroll callback of the specified window, which is
- * called when a scrolling device is used, such as a mouse wheel or scrolling
- * area of a touchpad.
- *
- * The scroll callback receives all scrolling input, like that from a mouse
- * wheel or a touchpad scrolling area.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new scroll callback, or `NULL` to remove the currently
- * set callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref scrolling
- *
- * @since Added in version 3.0. Replaces `glfwSetMouseWheelCallback`.
- *
- * @ingroup input
- */
-GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun cbfun);
-
-/*! @brief Sets the file drop callback.
- *
- * This function sets the file drop callback of the specified window, which is
- * called when one or more dragged files are dropped on the window.
- *
- * Because the path array and its strings may have been generated specifically
- * for that event, they are not guaranteed to be valid after the callback has
- * returned. If you wish to use them after the callback returns, you need to
- * make a deep copy.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new file drop callback, or `NULL` to remove the
- * currently set callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref path_drop
- *
- * @since Added in version 3.1.
- *
- * @ingroup input
- */
-GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* window, GLFWdropfun cbfun);
-
-/*! @brief Returns whether the specified joystick is present.
- *
- * This function returns whether the specified joystick is present.
- *
- * @param[in] joy The [joystick](@ref joysticks) to query.
- * @return `GLFW_TRUE` if the joystick is present, or `GLFW_FALSE` otherwise.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref joystick
- *
- * @since Added in version 3.0. Replaces `glfwGetJoystickParam`.
- *
- * @ingroup input
- */
-GLFWAPI int glfwJoystickPresent(int joy);
-
-/*! @brief Returns the values of all axes of the specified joystick.
- *
- * This function returns the values of all axes of the specified joystick.
- * Each element in the array is a value between -1.0 and 1.0.
- *
- * Querying a joystick slot with no device present is not an error, but will
- * cause this function to return `NULL`. Call @ref glfwJoystickPresent to
- * check device presence.
- *
- * @param[in] joy The [joystick](@ref joysticks) to query.
- * @param[out] count Where to store the number of axis values in the returned
- * array. This is set to zero if an error occurred.
- * @return An array of axis values, or `NULL` if the joystick is not present.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
- *
- * @pointer_lifetime The returned array is allocated and freed by GLFW. You
- * should not free it yourself. It is valid until the specified joystick is
- * disconnected, this function is called again for that joystick or the library
- * is terminated.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref joystick_axis
- *
- * @since Added in version 3.0. Replaces `glfwGetJoystickPos`.
- *
- * @ingroup input
- */
-GLFWAPI const float* glfwGetJoystickAxes(int joy, int* count);
-
-/*! @brief Returns the state of all buttons of the specified joystick.
- *
- * This function returns the state of all buttons of the specified joystick.
- * Each element in the array is either `GLFW_PRESS` or `GLFW_RELEASE`.
- *
- * Querying a joystick slot with no device present is not an error, but will
- * cause this function to return `NULL`. Call @ref glfwJoystickPresent to
- * check device presence.
- *
- * @param[in] joy The [joystick](@ref joysticks) to query.
- * @param[out] count Where to store the number of button states in the returned
- * array. This is set to zero if an error occurred.
- * @return An array of button states, or `NULL` if the joystick is not present.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
- *
- * @pointer_lifetime The returned array is allocated and freed by GLFW. You
- * should not free it yourself. It is valid until the specified joystick is
- * disconnected, this function is called again for that joystick or the library
- * is terminated.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref joystick_button
- *
- * @since Added in version 2.2.
- * @glfw3 Changed to return a dynamic array.
- *
- * @ingroup input
- */
-GLFWAPI const unsigned char* glfwGetJoystickButtons(int joy, int* count);
-
-/*! @brief Returns the name of the specified joystick.
- *
- * This function returns the name, encoded as UTF-8, of the specified joystick.
- * The returned string is allocated and freed by GLFW. You should not free it
- * yourself.
- *
- * Querying a joystick slot with no device present is not an error, but will
- * cause this function to return `NULL`. Call @ref glfwJoystickPresent to
- * check device presence.
- *
- * @param[in] joy The [joystick](@ref joysticks) to query.
- * @return The UTF-8 encoded name of the joystick, or `NULL` if the joystick
- * is not present.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
- *
- * @pointer_lifetime The returned string is allocated and freed by GLFW. You
- * should not free it yourself. It is valid until the specified joystick is
- * disconnected, this function is called again for that joystick or the library
- * is terminated.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref joystick_name
- *
- * @since Added in version 3.0.
- *
- * @ingroup input
- */
-GLFWAPI const char* glfwGetJoystickName(int joy);
-
-/*! @brief Sets the joystick configuration callback.
- *
- * This function sets the joystick configuration callback, or removes the
- * currently set callback. This is called when a joystick is connected to or
- * disconnected from the system.
- *
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref joystick_event
- *
- * @since Added in version 3.2.
- *
- * @ingroup input
- */
-GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun);
-
-/*! @brief Sets the clipboard to the specified string.
- *
- * This function sets the system clipboard to the specified, UTF-8 encoded
- * string.
- *
- * @param[in] window The window that will own the clipboard contents.
- * @param[in] string A UTF-8 encoded string.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @pointer_lifetime The specified string is copied before this function
- * returns.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref clipboard
- * @sa glfwGetClipboardString
- *
- * @since Added in version 3.0.
- *
- * @ingroup input
- */
-GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string);
-
-/*! @brief Returns the contents of the clipboard as a string.
- *
- * This function returns the contents of the system clipboard, if it contains
- * or is convertible to a UTF-8 encoded string. If the clipboard is empty or
- * if its contents cannot be converted, `NULL` is returned and a @ref
- * GLFW_FORMAT_UNAVAILABLE error is generated.
- *
- * @param[in] window The window that will request the clipboard contents.
- * @return The contents of the clipboard as a UTF-8 encoded string, or `NULL`
- * if an [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @pointer_lifetime The returned string is allocated and freed by GLFW. You
- * should not free it yourself. It is valid until the next call to @ref
- * glfwGetClipboardString or @ref glfwSetClipboardString, or until the library
- * is terminated.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref clipboard
- * @sa glfwSetClipboardString
- *
- * @since Added in version 3.0.
- *
- * @ingroup input
- */
-GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window);
-
-/*! @brief Returns the value of the GLFW timer.
- *
- * This function returns the value of the GLFW timer. Unless the timer has
- * been set using @ref glfwSetTime, the timer measures time elapsed since GLFW
- * was initialized.
- *
- * The resolution of the timer is system dependent, but is usually on the order
- * of a few micro- or nanoseconds. It uses the highest-resolution monotonic
- * time source on each supported platform.
- *
- * @return The current value, in seconds, or zero if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function may be called from any thread. Reading and
- * writing of the internal timer offset is not atomic, so it needs to be
- * externally synchronized with calls to @ref glfwSetTime.
- *
- * @sa @ref time
- *
- * @since Added in version 1.0.
- *
- * @ingroup input
- */
-GLFWAPI double glfwGetTime(void);
-
-/*! @brief Sets the GLFW timer.
- *
- * This function sets the value of the GLFW timer. It then continues to count
- * up from that value. The value must be a positive finite number less than
- * or equal to 18446744073.0, which is approximately 584.5 years.
- *
- * @param[in] time The new value, in seconds.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_INVALID_VALUE.
- *
- * @remark The upper limit of the timer is calculated as
- * floor((264 - 1) / 109) and is due to implementations
- * storing nanoseconds in 64 bits. The limit may be increased in the future.
- *
- * @thread_safety This function may be called from any thread. Reading and
- * writing of the internal timer offset is not atomic, so it needs to be
- * externally synchronized with calls to @ref glfwGetTime.
- *
- * @sa @ref time
- *
- * @since Added in version 2.2.
- *
- * @ingroup input
- */
-GLFWAPI void glfwSetTime(double time);
-
-/*! @brief Returns the current value of the raw timer.
- *
- * This function returns the current value of the raw timer, measured in
- * 1 / frequency seconds. To get the frequency, call @ref
- * glfwGetTimerFrequency.
- *
- * @return The value of the timer, or zero if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref time
- * @sa glfwGetTimerFrequency
- *
- * @since Added in version 3.2.
- *
- * @ingroup input
- */
-GLFWAPI uint64_t glfwGetTimerValue(void);
-
-/*! @brief Returns the frequency, in Hz, of the raw timer.
- *
- * This function returns the frequency, in Hz, of the raw timer.
- *
- * @return The frequency of the timer, in Hz, or zero if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref time
- * @sa glfwGetTimerValue
- *
- * @since Added in version 3.2.
- *
- * @ingroup input
- */
-GLFWAPI uint64_t glfwGetTimerFrequency(void);
-
-/*! @brief Makes the context of the specified window current for the calling
- * thread.
- *
- * This function makes the OpenGL or OpenGL ES context of the specified window
- * current on the calling thread. A context can only be made current on
- * a single thread at a time and each thread can have only a single current
- * context at a time.
- *
- * By default, making a context non-current implicitly forces a pipeline flush.
- * On machines that support `GL_KHR_context_flush_control`, you can control
- * whether a context performs this flush by setting the
- * [GLFW_CONTEXT_RELEASE_BEHAVIOR](@ref window_hints_ctx) window hint.
- *
- * The specified window must have an OpenGL or OpenGL ES context. Specifying
- * a window without a context will generate a @ref GLFW_NO_WINDOW_CONTEXT
- * error.
- *
- * @param[in] window The window whose context to make current, or `NULL` to
- * detach the current context.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref context_current
- * @sa glfwGetCurrentContext
- *
- * @since Added in version 3.0.
- *
- * @ingroup context
- */
-GLFWAPI void glfwMakeContextCurrent(GLFWwindow* window);
-
-/*! @brief Returns the window whose context is current on the calling thread.
- *
- * This function returns the window whose OpenGL or OpenGL ES context is
- * current on the calling thread.
- *
- * @return The window whose context is current, or `NULL` if no window's
- * context is current.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref context_current
- * @sa glfwMakeContextCurrent
- *
- * @since Added in version 3.0.
- *
- * @ingroup context
- */
-GLFWAPI GLFWwindow* glfwGetCurrentContext(void);
-
-/*! @brief Swaps the front and back buffers of the specified window.
- *
- * This function swaps the front and back buffers of the specified window when
- * rendering with OpenGL or OpenGL ES. If the swap interval is greater than
- * zero, the GPU driver waits the specified number of screen updates before
- * swapping the buffers.
- *
- * The specified window must have an OpenGL or OpenGL ES context. Specifying
- * a window without a context will generate a @ref GLFW_NO_WINDOW_CONTEXT
- * error.
- *
- * This function does not apply to Vulkan. If you are rendering with Vulkan,
- * see `vkQueuePresentKHR` instead.
- *
- * @param[in] window The window whose buffers to swap.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR.
- *
- * @remark __EGL:__ The context of the specified window must be current on the
- * calling thread.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref buffer_swap
- * @sa glfwSwapInterval
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup window
- */
-GLFWAPI void glfwSwapBuffers(GLFWwindow* window);
-
-/*! @brief Sets the swap interval for the current context.
- *
- * This function sets the swap interval for the current OpenGL or OpenGL ES
- * context, i.e. the number of screen updates to wait from the time @ref
- * glfwSwapBuffers was called before swapping the buffers and returning. This
- * is sometimes called _vertical synchronization_, _vertical retrace
- * synchronization_ or just _vsync_.
- *
- * Contexts that support either of the `WGL_EXT_swap_control_tear` and
- * `GLX_EXT_swap_control_tear` extensions also accept negative swap intervals,
- * which allow the driver to swap even if a frame arrives a little bit late.
- * You can check for the presence of these extensions using @ref
- * glfwExtensionSupported. For more information about swap tearing, see the
- * extension specifications.
- *
- * A context must be current on the calling thread. Calling this function
- * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error.
- *
- * This function does not apply to Vulkan. If you are rendering with Vulkan,
- * see the present mode of your swapchain instead.
- *
- * @param[in] interval The minimum number of screen updates to wait for
- * until the buffers are swapped by @ref glfwSwapBuffers.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_NO_CURRENT_CONTEXT and @ref GLFW_PLATFORM_ERROR.
- *
- * @remark This function is not called during context creation, leaving the
- * swap interval set to whatever is the default on that platform. This is done
- * because some swap interval extensions used by GLFW do not allow the swap
- * interval to be reset to zero once it has been set to a non-zero value.
- *
- * @remark Some GPU drivers do not honor the requested swap interval, either
- * because of a user setting that overrides the application's request or due to
- * bugs in the driver.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref buffer_swap
- * @sa glfwSwapBuffers
- *
- * @since Added in version 1.0.
- *
- * @ingroup context
- */
-GLFWAPI void glfwSwapInterval(int interval);
-
-/*! @brief Returns whether the specified extension is available.
- *
- * This function returns whether the specified
- * [API extension](@ref context_glext) is supported by the current OpenGL or
- * OpenGL ES context. It searches both for client API extension and context
- * creation API extensions.
- *
- * A context must be current on the calling thread. Calling this function
- * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error.
- *
- * As this functions retrieves and searches one or more extension strings each
- * call, it is recommended that you cache its results if it is going to be used
- * frequently. The extension strings will not change during the lifetime of
- * a context, so there is no danger in doing this.
- *
- * This function does not apply to Vulkan. If you are using Vulkan, see @ref
- * glfwGetRequiredInstanceExtensions, `vkEnumerateInstanceExtensionProperties`
- * and `vkEnumerateDeviceExtensionProperties` instead.
- *
- * @param[in] extension The ASCII encoded name of the extension.
- * @return `GLFW_TRUE` if the extension is available, or `GLFW_FALSE`
- * otherwise.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_NO_CURRENT_CONTEXT, @ref GLFW_INVALID_VALUE and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref context_glext
- * @sa glfwGetProcAddress
- *
- * @since Added in version 1.0.
- *
- * @ingroup context
- */
-GLFWAPI int glfwExtensionSupported(const char* extension);
-
-/*! @brief Returns the address of the specified function for the current
- * context.
- *
- * This function returns the address of the specified OpenGL or OpenGL ES
- * [core or extension function](@ref context_glext), if it is supported
- * by the current context.
- *
- * A context must be current on the calling thread. Calling this function
- * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error.
- *
- * This function does not apply to Vulkan. If you are rendering with Vulkan,
- * see @ref glfwGetInstanceProcAddress, `vkGetInstanceProcAddr` and
- * `vkGetDeviceProcAddr` instead.
- *
- * @param[in] procname The ASCII encoded name of the function.
- * @return The address of the function, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_NO_CURRENT_CONTEXT and @ref GLFW_PLATFORM_ERROR.
- *
- * @remark The address of a given function is not guaranteed to be the same
- * between contexts.
- *
- * @remark This function may return a non-`NULL` address despite the
- * associated version or extension not being available. Always check the
- * context version or extension string first.
- *
- * @pointer_lifetime The returned function pointer is valid until the context
- * is destroyed or the library is terminated.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref context_glext
- * @sa glfwExtensionSupported
- *
- * @since Added in version 1.0.
- *
- * @ingroup context
- */
-GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname);
-
-/*! @brief Returns whether the Vulkan loader has been found.
- *
- * This function returns whether the Vulkan loader has been found. This check
- * is performed by @ref glfwInit.
- *
- * The availability of a Vulkan loader does not by itself guarantee that window
- * surface creation or even device creation is possible. Call @ref
- * glfwGetRequiredInstanceExtensions to check whether the extensions necessary
- * for Vulkan surface creation are available and @ref
- * glfwGetPhysicalDevicePresentationSupport to check whether a queue family of
- * a physical device supports image presentation.
- *
- * @return `GLFW_TRUE` if Vulkan is available, or `GLFW_FALSE` otherwise.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref vulkan_support
- *
- * @since Added in version 3.2.
- *
- * @ingroup vulkan
- */
-GLFWAPI int glfwVulkanSupported(void);
-
-/*! @brief Returns the Vulkan instance extensions required by GLFW.
- *
- * This function returns an array of names of Vulkan instance extensions required
- * by GLFW for creating Vulkan surfaces for GLFW windows. If successful, the
- * list will always contains `VK_KHR_surface`, so if you don't require any
- * additional extensions you can pass this list directly to the
- * `VkInstanceCreateInfo` struct.
- *
- * If Vulkan is not available on the machine, this function returns `NULL` and
- * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported
- * to check whether Vulkan is available.
- *
- * If Vulkan is available but no set of extensions allowing window surface
- * creation was found, this function returns `NULL`. You may still use Vulkan
- * for off-screen rendering and compute work.
- *
- * @param[out] count Where to store the number of extensions in the returned
- * array. This is set to zero if an error occurred.
- * @return An array of ASCII encoded extension names, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_API_UNAVAILABLE.
- *
- * @remarks Additional extensions may be required by future versions of GLFW.
- * You should check if any extensions you wish to enable are already in the
- * returned array, as it is an error to specify an extension more than once in
- * the `VkInstanceCreateInfo` struct.
- *
- * @pointer_lifetime The returned array is allocated and freed by GLFW. You
- * should not free it yourself. It is guaranteed to be valid only until the
- * library is terminated.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref vulkan_ext
- * @sa glfwCreateWindowSurface
- *
- * @since Added in version 3.2.
- *
- * @ingroup vulkan
- */
-GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count);
-
-#if defined(VK_VERSION_1_0)
-
-/*! @brief Returns the address of the specified Vulkan instance function.
- *
- * This function returns the address of the specified Vulkan core or extension
- * function for the specified instance. If instance is set to `NULL` it can
- * return any function exported from the Vulkan loader, including at least the
- * following functions:
- *
- * - `vkEnumerateInstanceExtensionProperties`
- * - `vkEnumerateInstanceLayerProperties`
- * - `vkCreateInstance`
- * - `vkGetInstanceProcAddr`
- *
- * If Vulkan is not available on the machine, this function returns `NULL` and
- * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported
- * to check whether Vulkan is available.
- *
- * This function is equivalent to calling `vkGetInstanceProcAddr` with
- * a platform-specific query of the Vulkan loader as a fallback.
- *
- * @param[in] instance The Vulkan instance to query, or `NULL` to retrieve
- * functions related to instance creation.
- * @param[in] procname The ASCII encoded name of the function.
- * @return The address of the function, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_API_UNAVAILABLE.
- *
- * @pointer_lifetime The returned function pointer is valid until the library
- * is terminated.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref vulkan_proc
- *
- * @since Added in version 3.2.
- *
- * @ingroup vulkan
- */
-GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* procname);
-
-/*! @brief Returns whether the specified queue family can present images.
- *
- * This function returns whether the specified queue family of the specified
- * physical device supports presentation to the platform GLFW was built for.
- *
- * If Vulkan or the required window surface creation instance extensions are
- * not available on the machine, or if the specified instance was not created
- * with the required extensions, this function returns `GLFW_FALSE` and
- * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported
- * to check whether Vulkan is available and @ref
- * glfwGetRequiredInstanceExtensions to check what instance extensions are
- * required.
- *
- * @param[in] instance The instance that the physical device belongs to.
- * @param[in] device The physical device that the queue family belongs to.
- * @param[in] queuefamily The index of the queue family to query.
- * @return `GLFW_TRUE` if the queue family supports presentation, or
- * `GLFW_FALSE` otherwise.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function may be called from any thread. For
- * synchronization details of Vulkan objects, see the Vulkan specification.
- *
- * @sa @ref vulkan_present
- *
- * @since Added in version 3.2.
- *
- * @ingroup vulkan
- */
-GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
-
-/*! @brief Creates a Vulkan surface for the specified window.
- *
- * This function creates a Vulkan surface for the specified window.
- *
- * If the Vulkan loader was not found at initialization, this function returns
- * `VK_ERROR_INITIALIZATION_FAILED` and generates a @ref GLFW_API_UNAVAILABLE
- * error. Call @ref glfwVulkanSupported to check whether the Vulkan loader was
- * found.
- *
- * If the required window surface creation instance extensions are not
- * available or if the specified instance was not created with these extensions
- * enabled, this function returns `VK_ERROR_EXTENSION_NOT_PRESENT` and
- * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref
- * glfwGetRequiredInstanceExtensions to check what instance extensions are
- * required.
- *
- * The window surface must be destroyed before the specified Vulkan instance.
- * It is the responsibility of the caller to destroy the window surface. GLFW
- * does not destroy it for you. Call `vkDestroySurfaceKHR` to destroy the
- * surface.
- *
- * @param[in] instance The Vulkan instance to create the surface in.
- * @param[in] window The window to create the surface for.
- * @param[in] allocator The allocator to use, or `NULL` to use the default
- * allocator.
- * @param[out] surface Where to store the handle of the surface. This is set
- * to `VK_NULL_HANDLE` if an error occurred.
- * @return `VK_SUCCESS` if successful, or a Vulkan error code if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.
- *
- * @remarks If an error occurs before the creation call is made, GLFW returns
- * the Vulkan error code most appropriate for the error. Appropriate use of
- * @ref glfwVulkanSupported and @ref glfwGetRequiredInstanceExtensions should
- * eliminate almost all occurrences of these errors.
- *
- * @thread_safety This function may be called from any thread. For
- * synchronization details of Vulkan objects, see the Vulkan specification.
- *
- * @sa @ref vulkan_surface
- * @sa glfwGetRequiredInstanceExtensions
- *
- * @since Added in version 3.2.
- *
- * @ingroup vulkan
- */
-GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);
-
-#endif /*VK_VERSION_1_0*/
-
-
-/*************************************************************************
- * Global definition cleanup
- *************************************************************************/
-
-/* ------------------- BEGIN SYSTEM/COMPILER SPECIFIC -------------------- */
-
-#ifdef GLFW_WINGDIAPI_DEFINED
- #undef WINGDIAPI
- #undef GLFW_WINGDIAPI_DEFINED
-#endif
-
-#ifdef GLFW_CALLBACK_DEFINED
- #undef CALLBACK
- #undef GLFW_CALLBACK_DEFINED
-#endif
-
-/* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _glfw3_h_ */
-
diff --git a/release/include/GLFW/glfw3native.h b/release/include/GLFW/glfw3native.h
deleted file mode 100644
index 30e1a570f..000000000
--- a/release/include/GLFW/glfw3native.h
+++ /dev/null
@@ -1,456 +0,0 @@
-/*************************************************************************
- * GLFW 3.2 - www.glfw.org
- * A library for OpenGL, window and input
- *------------------------------------------------------------------------
- * Copyright (c) 2002-2006 Marcus Geelnard
- * Copyright (c) 2006-2016 Camilla Berglund
- *
- * This software is provided 'as-is', without any express or implied
- * warranty. In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- * claim that you wrote the original software. If you use this software
- * in a product, an acknowledgment in the product documentation would
- * be appreciated but is not required.
- *
- * 2. Altered source versions must be plainly marked as such, and must not
- * be misrepresented as being the original software.
- *
- * 3. This notice may not be removed or altered from any source
- * distribution.
- *
- *************************************************************************/
-
-#ifndef _glfw3_native_h_
-#define _glfw3_native_h_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*************************************************************************
- * Doxygen documentation
- *************************************************************************/
-
-/*! @file glfw3native.h
- * @brief The header of the native access functions.
- *
- * This is the header file of the native access functions. See @ref native for
- * more information.
- */
-/*! @defgroup native Native access
- *
- * **By using the native access functions you assert that you know what you're
- * doing and how to fix problems caused by using them. If you don't, you
- * shouldn't be using them.**
- *
- * Before the inclusion of @ref glfw3native.h, you may define exactly one
- * window system API macro and zero or more context creation API macros.
- *
- * The chosen backends must match those the library was compiled for. Failure
- * to do this will cause a link-time error.
- *
- * The available window API macros are:
- * * `GLFW_EXPOSE_NATIVE_WIN32`
- * * `GLFW_EXPOSE_NATIVE_COCOA`
- * * `GLFW_EXPOSE_NATIVE_X11`
- * * `GLFW_EXPOSE_NATIVE_WAYLAND`
- * * `GLFW_EXPOSE_NATIVE_MIR`
- *
- * The available context API macros are:
- * * `GLFW_EXPOSE_NATIVE_WGL`
- * * `GLFW_EXPOSE_NATIVE_NSGL`
- * * `GLFW_EXPOSE_NATIVE_GLX`
- * * `GLFW_EXPOSE_NATIVE_EGL`
- *
- * These macros select which of the native access functions that are declared
- * and which platform-specific headers to include. It is then up your (by
- * definition platform-specific) code to handle which of these should be
- * defined.
- */
-
-
-/*************************************************************************
- * System headers and types
- *************************************************************************/
-
-#if defined(GLFW_EXPOSE_NATIVE_WIN32)
- // This is a workaround for the fact that glfw3.h needs to export APIENTRY (for
- // example to allow applications to correctly declare a GL_ARB_debug_output
- // callback) but windows.h assumes no one will define APIENTRY before it does
- #undef APIENTRY
- #include
-#elif defined(GLFW_EXPOSE_NATIVE_COCOA)
- #include
- #if defined(__OBJC__)
- #import
- #else
- typedef void* id;
- #endif
-#elif defined(GLFW_EXPOSE_NATIVE_X11)
- #include
- #include
-#elif defined(GLFW_EXPOSE_NATIVE_WAYLAND)
- #include
-#elif defined(GLFW_EXPOSE_NATIVE_MIR)
- #include
-#endif
-
-#if defined(GLFW_EXPOSE_NATIVE_WGL)
- /* WGL is declared by windows.h */
-#endif
-#if defined(GLFW_EXPOSE_NATIVE_NSGL)
- /* NSGL is declared by Cocoa.h */
-#endif
-#if defined(GLFW_EXPOSE_NATIVE_GLX)
- #include
-#endif
-#if defined(GLFW_EXPOSE_NATIVE_EGL)
- #include
-#endif
-
-
-/*************************************************************************
- * Functions
- *************************************************************************/
-
-#if defined(GLFW_EXPOSE_NATIVE_WIN32)
-/*! @brief Returns the adapter device name of the specified monitor.
- *
- * @return The UTF-8 encoded adapter device name (for example `\\.\DISPLAY1`)
- * of the specified monitor, or `NULL` if an [error](@ref error_handling)
- * occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.1.
- *
- * @ingroup native
- */
-GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor);
-
-/*! @brief Returns the display device name of the specified monitor.
- *
- * @return The UTF-8 encoded display device name (for example
- * `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.1.
- *
- * @ingroup native
- */
-GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor);
-
-/*! @brief Returns the `HWND` of the specified window.
- *
- * @return The `HWND` of the specified window, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.0.
- *
- * @ingroup native
- */
-GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);
-#endif
-
-#if defined(GLFW_EXPOSE_NATIVE_WGL)
-/*! @brief Returns the `HGLRC` of the specified window.
- *
- * @return The `HGLRC` of the specified window, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.0.
- *
- * @ingroup native
- */
-GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window);
-#endif
-
-#if defined(GLFW_EXPOSE_NATIVE_COCOA)
-/*! @brief Returns the `CGDirectDisplayID` of the specified monitor.
- *
- * @return The `CGDirectDisplayID` of the specified monitor, or
- * `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.1.
- *
- * @ingroup native
- */
-GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor);
-
-/*! @brief Returns the `NSWindow` of the specified window.
- *
- * @return The `NSWindow` of the specified window, or `nil` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.0.
- *
- * @ingroup native
- */
-GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window);
-#endif
-
-#if defined(GLFW_EXPOSE_NATIVE_NSGL)
-/*! @brief Returns the `NSOpenGLContext` of the specified window.
- *
- * @return The `NSOpenGLContext` of the specified window, or `nil` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.0.
- *
- * @ingroup native
- */
-GLFWAPI id glfwGetNSGLContext(GLFWwindow* window);
-#endif
-
-#if defined(GLFW_EXPOSE_NATIVE_X11)
-/*! @brief Returns the `Display` used by GLFW.
- *
- * @return The `Display` used by GLFW, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.0.
- *
- * @ingroup native
- */
-GLFWAPI Display* glfwGetX11Display(void);
-
-/*! @brief Returns the `RRCrtc` of the specified monitor.
- *
- * @return The `RRCrtc` of the specified monitor, or `None` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.1.
- *
- * @ingroup native
- */
-GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor);
-
-/*! @brief Returns the `RROutput` of the specified monitor.
- *
- * @return The `RROutput` of the specified monitor, or `None` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.1.
- *
- * @ingroup native
- */
-GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor);
-
-/*! @brief Returns the `Window` of the specified window.
- *
- * @return The `Window` of the specified window, or `None` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.0.
- *
- * @ingroup native
- */
-GLFWAPI Window glfwGetX11Window(GLFWwindow* window);
-#endif
-
-#if defined(GLFW_EXPOSE_NATIVE_GLX)
-/*! @brief Returns the `GLXContext` of the specified window.
- *
- * @return The `GLXContext` of the specified window, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.0.
- *
- * @ingroup native
- */
-GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);
-
-/*! @brief Returns the `GLXWindow` of the specified window.
- *
- * @return The `GLXWindow` of the specified window, or `None` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.2.
- *
- * @ingroup native
- */
-GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window);
-#endif
-
-#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
-/*! @brief Returns the `struct wl_display*` used by GLFW.
- *
- * @return The `struct wl_display*` used by GLFW, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.2.
- *
- * @ingroup native
- */
-GLFWAPI struct wl_display* glfwGetWaylandDisplay(void);
-
-/*! @brief Returns the `struct wl_output*` of the specified monitor.
- *
- * @return The `struct wl_output*` of the specified monitor, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.2.
- *
- * @ingroup native
- */
-GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor);
-
-/*! @brief Returns the main `struct wl_surface*` of the specified window.
- *
- * @return The main `struct wl_surface*` of the specified window, or `NULL` if
- * an [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.2.
- *
- * @ingroup native
- */
-GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);
-#endif
-
-#if defined(GLFW_EXPOSE_NATIVE_MIR)
-/*! @brief Returns the `MirConnection*` used by GLFW.
- *
- * @return The `MirConnection*` used by GLFW, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.2.
- *
- * @ingroup native
- */
-GLFWAPI MirConnection* glfwGetMirDisplay(void);
-
-/*! @brief Returns the Mir output ID of the specified monitor.
- *
- * @return The Mir output ID of the specified monitor, or zero if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.2.
- *
- * @ingroup native
- */
-GLFWAPI int glfwGetMirMonitor(GLFWmonitor* monitor);
-
-/*! @brief Returns the `MirSurface*` of the specified window.
- *
- * @return The `MirSurface*` of the specified window, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.2.
- *
- * @ingroup native
- */
-GLFWAPI MirSurface* glfwGetMirWindow(GLFWwindow* window);
-#endif
-
-#if defined(GLFW_EXPOSE_NATIVE_EGL)
-/*! @brief Returns the `EGLDisplay` used by GLFW.
- *
- * @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.0.
- *
- * @ingroup native
- */
-GLFWAPI EGLDisplay glfwGetEGLDisplay(void);
-
-/*! @brief Returns the `EGLContext` of the specified window.
- *
- * @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.0.
- *
- * @ingroup native
- */
-GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window);
-
-/*! @brief Returns the `EGLSurface` of the specified window.
- *
- * @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.0.
- *
- * @ingroup native
- */
-GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window);
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _glfw3_native_h_ */
-
diff --git a/release/include/raylib.h b/release/include/raylib.h
index 392e0a24c..acca46bdc 100644
--- a/release/include/raylib.h
+++ b/release/include/raylib.h
@@ -1,23 +1,23 @@
/**********************************************************************************************
*
-* raylib v1.8.0
+* raylib v1.9.6-dev
*
* A simple and easy-to-use library to learn videogames programming (www.raylib.com)
*
* FEATURES:
* - Written in plain C code (C99) in PascalCase/camelCase notation
-* - Multiple platforms support: Windows, Linux, Mac, Android, Raspberry Pi and HTML5
-* - Hardware accelerated with OpenGL (1.1, 2.1, 3.3 or ES 2.0)
+* - Hardware accelerated with OpenGL (1.1, 2.1, 3.3 or ES2 - choose at compile)
* - Unique OpenGL abstraction layer (usable as standalone module): [rlgl]
-* - Powerful fonts module with SpriteFonts support (XNA bitmap fonts, AngelCode fonts, TTF)
-* - Outstanding texture formats support, including compressed formats (DXT, ETC, PVRT, ASTC)
-* - Basic 3d support for Geometrics, Models, Billboards, Heightmaps and Cubicmaps
+* - Powerful fonts module with SpriteFonts support (XNA fonts, AngelCode fonts, TTF)
+* - Outstanding texture formats support, including compressed formats (DXT, ETC, ASTC)
+* - Full 3d support for 3d Shapes, Models, Billboards, Heightmaps and more!
* - Flexible Materials system, supporting classic maps and PBR maps
* - Shaders support, including Model shaders and Postprocessing shaders
-* - Powerful math module for Vector2, Vector3, Matrix and Quaternion operations: [raymath]
-* - Audio loading and playing with streaming support and mixing channels: [audio]
-* - VR stereo rendering support with configurable HMD device parameters
-* - Minimal external dependencies (GLFW3, OpenGL, OpenAL)
+* - Powerful math module for Vector, Matrix and Quaternion operations: [raymath]
+* - Audio loading and playing with streaming support (WAV, OGG, FLAC, XM, MOD)
+* - Multiple platforms support: Windows, Linux, FreeBSD, MacOS, UWP, Android, Raspberry Pi, HTML5.
+* - VR stereo rendering with configurable HMD device parameters
+* - NO external dependencies, all required libraries included with raylib
* - Complete bindings to LUA (raylib-lua) and Go (raylib-go)
*
* NOTES:
@@ -25,17 +25,17 @@
* If using OpenGL 3.3 or ES2, one default shader is loaded automatically (internally defined) [rlgl]
* If using OpenGL 3.3 or ES2, several vertex buffers (VAO/VBO) are created to manage lines-triangles-quads
*
-* DEPENDENCIES:
-* GLFW3 (www.glfw.org) for window/context management and input [core]
-* GLAD for OpenGL extensions loading (3.3 Core profile, only PLATFORM_DESKTOP) [rlgl]
-* OpenAL Soft for audio device/context management [audio]
+* DEPENDENCIES (included):
+* rglfw (github.com/glfw/glfw) for window/context management and input (only PLATFORM_DESKTOP) [core]
+* glad (github.com/Dav1dde/glad) for OpenGL extensions loading (3.3 Core profile, only PLATFORM_DESKTOP) [rlgl]
+* mini_al (github.com/dr-soft/mini_al) for audio device/context management [audio]
*
-* OPTIONAL DEPENDENCIES:
-* stb_image (Sean Barret) for images loading (JPEG, PNG, BMP, TGA) [textures]
+* OPTIONAL DEPENDENCIES (included):
+* stb_image (Sean Barret) for images loading (BMP, TGA, PNG, JPEG, HDR...) [textures]
* stb_image_resize (Sean Barret) for image resizing algorythms [textures]
* stb_image_write (Sean Barret) for image writting (PNG) [utils]
* stb_truetype (Sean Barret) for ttf fonts loading [text]
-* stb_vorbis (Sean Barret) for ogg audio loading [audio]
+* stb_vorbis (Sean Barret) for OGG audio loading [audio]
* stb_perlin (Sean Barret) for Perlin noise image generation [textures]
* par_shapes (Philip Rideout) for parametric 3d shapes generation [models]
* jar_xm (Joshua Reisenauer) for XM audio module loading [audio]
@@ -50,7 +50,7 @@
* raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software:
*
-* Copyright (c) 2013-2017 Ramon Santamaria (@raysan5)
+* Copyright (c) 2013-2018 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
@@ -72,20 +72,6 @@
#ifndef RAYLIB_H
#define RAYLIB_H
-// Choose your platform here or just define it at compile time: -DPLATFORM_DESKTOP
-//#define PLATFORM_DESKTOP // Windows, Linux or OSX
-//#define PLATFORM_ANDROID // Android device
-//#define PLATFORM_RPI // Raspberry Pi
-//#define PLATFORM_WEB // HTML5 (emscripten, asm.js)
-
-// Security check in case no PLATFORM_* defined
-#if !defined(PLATFORM_DESKTOP) && \
- !defined(PLATFORM_ANDROID) && \
- !defined(PLATFORM_RPI) && \
- !defined(PLATFORM_WEB)
- #define PLATFORM_DESKTOP
-#endif
-
#if defined(_WIN32) && defined(BUILD_LIBTYPE_SHARED)
#define RLAPI __declspec(dllexport) // We are building raylib as a Win32 shared library (.dll)
#elif defined(_WIN32) && defined(USE_LIBTYPE_SHARED)
@@ -117,11 +103,23 @@
#define KEY_SPACE 32
#define KEY_ESCAPE 256
#define KEY_ENTER 257
+#define KEY_TAB 258
#define KEY_BACKSPACE 259
+#define KEY_INSERT 260
+#define KEY_DELETE 261
#define KEY_RIGHT 262
#define KEY_LEFT 263
#define KEY_DOWN 264
#define KEY_UP 265
+#define KEY_PAGE_UP 266
+#define KEY_PAGE_DOWN 267
+#define KEY_HOME 268
+#define KEY_END 269
+#define KEY_CAPS_LOCK 280
+#define KEY_SCROLL_LOCK 281
+#define KEY_NUM_LOCK 282
+#define KEY_PRINT_SCREEN 283
+#define KEY_PAUSE 284
#define KEY_F1 290
#define KEY_F2 291
#define KEY_F3 292
@@ -179,13 +177,11 @@
#define KEY_Y 89
#define KEY_Z 90
-#if defined(PLATFORM_ANDROID)
- // Android Physical Buttons
- #define KEY_BACK 4
- #define KEY_MENU 82
- #define KEY_VOLUME_UP 24
- #define KEY_VOLUME_DOWN 25
-#endif
+// Android Physical Buttons
+#define KEY_BACK 4
+#define KEY_MENU 82
+#define KEY_VOLUME_UP 24
+#define KEY_VOLUME_DOWN 25
// Mouse Buttons
#define MOUSE_LEFT_BUTTON 0
@@ -326,6 +322,14 @@ typedef struct Vector3 {
float z;
} Vector3;
+// Vector4 type
+typedef struct Vector4 {
+ float x;
+ float y;
+ float z;
+ float w;
+} Vector4;
+
// Matrix type (OpenGL style 4x4 - right handed, column major)
typedef struct Matrix {
float m0, m4, m8, m12;
@@ -357,7 +361,7 @@ typedef struct Image {
int width; // Image base width
int height; // Image base height
int mipmaps; // Mipmap levels, 1 by default
- int format; // Data format (TextureFormat type)
+ int format; // Data format (PixelFormat type)
} Image;
// Texture2D type
@@ -367,7 +371,7 @@ typedef struct Texture2D {
int width; // Texture base width
int height; // Texture base height
int mipmaps; // Mipmap levels, 1 by default
- int format; // Data format (TextureFormat type)
+ int format; // Data format (PixelFormat type)
} Texture2D;
// RenderTexture2D type, for texture rendering
@@ -394,12 +398,19 @@ typedef struct SpriteFont {
CharInfo *chars; // Characters info data
} SpriteFont;
+// Camera projection modes
+typedef enum {
+ CAMERA_PERSPECTIVE = 0,
+ CAMERA_ORTHOGRAPHIC
+} CameraType;
+
// Camera type, defines a camera position/orientation in 3d space
typedef struct Camera {
Vector3 position; // Camera position
Vector3 target; // Camera target it looks-at
Vector3 up; // Camera up vector (rotation over its axis)
- float fovy; // Camera field-of-view apperture in Y (degrees)
+ float fovy; // Camera field-of-view apperture in Y (degrees) in perspective, used as near plane width in orthographic
+ CameraType type; // Camera type, controlling projection type, either CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC.
} Camera;
// Camera2D type, defines a 2d camera
@@ -426,7 +437,7 @@ typedef struct Mesh {
float *texcoords; // Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1)
float *texcoords2; // Vertex second texture coordinates (useful for lightmaps) (shader-location = 5)
float *normals; // Vertex normals (XYZ - 3 components per vertex) (shader-location = 2)
- float *tangents; // Vertex tangents (XYZ - 3 components per vertex) (shader-location = 4)
+ float *tangents; // Vertex tangents (XYZW - 4 components per vertex) (shader-location = 4)
unsigned char *colors; // Vertex colors (RGBA - 4 components per vertex) (shader-location = 3)
unsigned short *indices;// Vertex indices (in case vertex data comes indexed)
@@ -486,9 +497,11 @@ typedef struct Wave {
// Sound source type
typedef struct Sound {
- unsigned int source; // OpenAL audio source id
- unsigned int buffer; // OpenAL audio buffer id
- int format; // OpenAL audio format specifier
+ void *audioBuffer; // Pointer to internal data used by the audio system
+
+ unsigned int source; // Audio source id
+ unsigned int buffer; // Audio buffer id
+ int format; // Audio format specifier
} Sound;
// Music type (file streaming from memory)
@@ -502,27 +515,13 @@ typedef struct AudioStream {
unsigned int sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported)
unsigned int channels; // Number of channels (1-mono, 2-stereo)
- int format; // OpenAL audio format specifier
- unsigned int source; // OpenAL audio source id
- unsigned int buffers[2]; // OpenAL audio buffers (double buffering)
+ void *audioBuffer; // Pointer to internal data used by the audio system.
+
+ int format; // Audio format specifier
+ unsigned int source; // Audio source id
+ unsigned int buffers[2]; // Audio buffers (double buffering)
} AudioStream;
-// rRES data returned when reading a resource,
-// it contains all required data for user (24 byte)
-typedef struct RRESData {
- unsigned int type; // Resource type (4 byte)
-
- unsigned int param1; // Resouce parameter 1 (4 byte)
- unsigned int param2; // Resouce parameter 2 (4 byte)
- unsigned int param3; // Resouce parameter 3 (4 byte)
- unsigned int param4; // Resouce parameter 4 (4 byte)
-
- void *data; // Resource data pointer (4 byte)
-} RRESData;
-
-// RRES type (pointer to RRESData array)
-typedef struct RRESData *RRES;
-
// Head-Mounted-Display device parameters
typedef struct VrDeviceInfo {
int hResolution; // HMD horizontal resolution in pixels
@@ -542,11 +541,11 @@ typedef struct VrDeviceInfo {
//----------------------------------------------------------------------------------
// Trace log type
typedef enum {
- LOG_INFO = 0,
- LOG_WARNING,
- LOG_ERROR,
- LOG_DEBUG,
- LOG_OTHER
+ LOG_INFO = 1,
+ LOG_WARNING = 2,
+ LOG_ERROR = 4,
+ LOG_DEBUG = 8,
+ LOG_OTHER = 16
} LogType;
// Shader location point type
@@ -569,7 +568,7 @@ typedef enum {
LOC_MAP_METALNESS, // LOC_MAP_SPECULAR
LOC_MAP_NORMAL,
LOC_MAP_ROUGHNESS,
- LOC_MAP_OCCUSION,
+ LOC_MAP_OCCLUSION,
LOC_MAP_EMISSION,
LOC_MAP_HEIGHT,
LOC_MAP_CUBEMAP,
@@ -599,17 +598,19 @@ typedef enum {
#define MAP_DIFFUSE MAP_ALBEDO
#define MAP_SPECULAR MAP_METALNESS
-// Texture formats
+// Pixel formats
// NOTE: Support depends on OpenGL version and platform
typedef enum {
UNCOMPRESSED_GRAYSCALE = 1, // 8 bit per pixel (no alpha)
- UNCOMPRESSED_GRAY_ALPHA, // 16 bpp (2 channels)
+ UNCOMPRESSED_GRAY_ALPHA, // 8*2 bpp (2 channels)
UNCOMPRESSED_R5G6B5, // 16 bpp
UNCOMPRESSED_R8G8B8, // 24 bpp
UNCOMPRESSED_R5G5B5A1, // 16 bpp (1 bit alpha)
UNCOMPRESSED_R4G4B4A4, // 16 bpp (4 bit alpha)
UNCOMPRESSED_R8G8B8A8, // 32 bpp
- UNCOMPRESSED_R32G32B32, // 32 bit per channel (float) - HDR
+ UNCOMPRESSED_R32, // 32 bpp (1 channel - float)
+ UNCOMPRESSED_R32G32B32, // 32*3 bpp (3 channels - float)
+ UNCOMPRESSED_R32G32B32A32, // 32*4 bpp (4 channels - float)
COMPRESSED_DXT1_RGB, // 4 bpp (no alpha)
COMPRESSED_DXT1_RGBA, // 4 bpp (1 bit alpha)
COMPRESSED_DXT3_RGBA, // 8 bpp
@@ -621,7 +622,7 @@ typedef enum {
COMPRESSED_PVRT_RGBA, // 4 bpp
COMPRESSED_ASTC_4x4_RGBA, // 8 bpp
COMPRESSED_ASTC_8x8_RGBA // 2 bpp
-} TextureFormat;
+} PixelFormat;
// Texture parameters: filter mode
// NOTE 1: Filtering considers mipmaps if available in the texture
@@ -684,18 +685,6 @@ typedef enum {
HMD_SONY_PSVR
} VrDeviceType;
-// RRESData type
-typedef enum {
- RRES_TYPE_RAW = 0,
- RRES_TYPE_IMAGE,
- RRES_TYPE_WAVE,
- RRES_TYPE_VERTEX,
- RRES_TYPE_TEXT,
- RRES_TYPE_FONT_IMAGE,
- RRES_TYPE_FONT_CHARDATA, // CharInfo data array
- RRES_TYPE_DIRECTORY
-} RRESDataType;
-
#ifdef __cplusplus
extern "C" { // Prevents name mangling of functions
#endif
@@ -710,12 +699,9 @@ extern "C" { // Prevents name mangling of functions
//------------------------------------------------------------------------------------
// Window-related functions
-#if defined(PLATFORM_ANDROID)
-RLAPI void InitWindow(int width, int height, void *state); // Initialize Android activity
-#elif defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
RLAPI void InitWindow(int width, int height, const char *title); // Initialize window and OpenGL context
-#endif
RLAPI void CloseWindow(void); // Close window and unload OpenGL context
+RLAPI bool IsWindowReady(void); // Check if window has been initialized successfully
RLAPI bool WindowShouldClose(void); // Check if KEY_ESCAPE pressed or Close icon pressed
RLAPI bool IsWindowMinimized(void); // Check if window has been minimized (or lost focus)
RLAPI void ToggleFullscreen(void); // Toggle fullscreen mode (only PLATFORM_DESKTOP)
@@ -724,17 +710,16 @@ RLAPI void SetWindowTitle(const char *title); // Set title f
RLAPI void SetWindowPosition(int x, int y); // Set window position on screen (only PLATFORM_DESKTOP)
RLAPI void SetWindowMonitor(int monitor); // Set monitor for the current window (fullscreen mode)
RLAPI void SetWindowMinSize(int width, int height); // Set window minimum dimensions (for FLAG_WINDOW_RESIZABLE)
+RLAPI void SetWindowSize(int width, int height); // Set window dimensions
RLAPI int GetScreenWidth(void); // Get current screen width
RLAPI int GetScreenHeight(void); // Get current screen height
-#if !defined(PLATFORM_ANDROID)
// Cursor-related functions
RLAPI void ShowCursor(void); // Shows cursor
RLAPI void HideCursor(void); // Hides cursor
RLAPI bool IsCursorHidden(void); // Check if cursor is not visible
RLAPI void EnableCursor(void); // Enables cursor (unlock cursor)
RLAPI void DisableCursor(void); // Disables cursor (lock cursor)
-#endif
// Drawing-related functions
RLAPI void ClearBackground(Color color); // Set background color (framebuffer clear color)
@@ -748,7 +733,7 @@ RLAPI void BeginTextureMode(RenderTexture2D target); // Initializes
RLAPI void EndTextureMode(void); // Ends drawing to render texture
// Screen-space-related functions
-RLAPI Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Returns a ray trace from mouse position
+RLAPI Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Returns a ray trace from mouse position
RLAPI Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Returns the screen space position for a 3d world space position
RLAPI Matrix GetCameraMatrix(Camera camera); // Returns camera transform matrix (view matrix)
@@ -756,32 +741,29 @@ RLAPI Matrix GetCameraMatrix(Camera camera); // Returns cam
RLAPI void SetTargetFPS(int fps); // Set target FPS (maximum)
RLAPI int GetFPS(void); // Returns current FPS
RLAPI float GetFrameTime(void); // Returns time in seconds for last frame drawn
+RLAPI double GetTime(void); // Returns elapsed time in seconds since InitWindow()
// Color-related functions
-RLAPI int GetHexValue(Color color); // Returns hexadecimal value for a Color
+RLAPI float *ColorToFloat(Color color); // Returns normalized float array for a Color
+RLAPI int ColorToInt(Color color); // Returns hexadecimal value for a Color
+RLAPI Vector3 ColorToHSV(Color color); // Returns HSV values for a Color
RLAPI Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value
RLAPI Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0f to 1.0f
-RLAPI float *ColorToFloat(Color color); // Converts Color to float array and normalizes
-
-// Math useful functions (available from raymath.h)
-RLAPI float *VectorToFloat(Vector3 vec); // Returns Vector3 as float array
-RLAPI float *MatrixToFloat(Matrix mat); // Returns Matrix as float array
-RLAPI Vector3 Vector3Zero(void); // Vector with components value 0.0f
-RLAPI Vector3 Vector3One(void); // Vector with components value 1.0f
-RLAPI Matrix MatrixIdentity(void); // Returns identity matrix
// Misc. functions
RLAPI void ShowLogo(void); // Activate raylib logo at startup (can be done with flags)
-RLAPI void SetConfigFlags(char flags); // Setup window configuration flags (view FLAGS)
+RLAPI void SetConfigFlags(unsigned char flags); // Setup window configuration flags (view FLAGS)
+RLAPI void SetTraceLog(unsigned char types); // Enable trace log message types (bit flags based)
RLAPI void TraceLog(int logType, const char *text, ...); // Show trace log messages (LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_DEBUG)
RLAPI void TakeScreenshot(const char *fileName); // Takes a screenshot of current screen (saved a .png)
RLAPI int GetRandomValue(int min, int max); // Returns a random value between min and max (both included)
// Files management functions
RLAPI bool IsFileExtension(const char *fileName, const char *ext);// Check file extension
-RLAPI const char *GetExtension(const char *fileName); // Get file extension
-RLAPI const char *GetDirectoryPath(const char *fileName); // Get directory for a given fileName (with path)
-RLAPI const char *GetWorkingDirectory(void); // Get current working directory
+RLAPI const char *GetExtension(const char *fileName); // Get pointer to extension for a filename string
+RLAPI const char *GetFileName(const char *filePath); // Get pointer to filename for a path string
+RLAPI const char *GetDirectoryPath(const char *fileName); // Get full path for a given fileName (uses static string)
+RLAPI const char *GetWorkingDirectory(void); // Get current working directory (uses static string)
RLAPI bool ChangeDirectory(const char *dir); // Change working directory, returns true if success
RLAPI bool IsFileDropped(void); // Check if a file has been dropped into window
RLAPI char **GetDroppedFiles(int *count); // Get dropped files names
@@ -824,6 +806,7 @@ RLAPI int GetMouseX(void); // Returns mouse p
RLAPI int GetMouseY(void); // Returns mouse position Y
RLAPI Vector2 GetMousePosition(void); // Returns mouse position XY
RLAPI void SetMousePosition(Vector2 position); // Set mouse position XY
+RLAPI void SetMouseScale(float scale); // Set mouse scaling
RLAPI int GetMouseWheelMove(void); // Returns mouse wheel movement Y
// Input-related functions: touch
@@ -873,14 +856,14 @@ RLAPI void DrawCircleGradient(int centerX, int centerY, float radius, Color colo
RLAPI void DrawCircleV(Vector2 center, float radius, Color color); // Draw a color-filled circle (Vector version)
RLAPI void DrawCircleLines(int centerX, int centerY, float radius, Color color); // Draw circle outline
RLAPI void DrawRectangle(int posX, int posY, int width, int height, Color color); // Draw a color-filled rectangle
+RLAPI void DrawRectangleV(Vector2 position, Vector2 size, Color color); // Draw a color-filled rectangle (Vector version)
RLAPI void DrawRectangleRec(Rectangle rec, Color color); // Draw a color-filled rectangle
RLAPI void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color); // Draw a color-filled rectangle with pro parameters
RLAPI void DrawRectangleGradientV(int posX, int posY, int width, int height, Color color1, Color color2);// Draw a vertical-gradient-filled rectangle
RLAPI void DrawRectangleGradientH(int posX, int posY, int width, int height, Color color1, Color color2);// Draw a horizontal-gradient-filled rectangle
RLAPI void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4); // Draw a gradient-filled rectangle with custom vertex colors
-RLAPI void DrawRectangleV(Vector2 position, Vector2 size, Color color); // Draw a color-filled rectangle (Vector version)
RLAPI void DrawRectangleLines(int posX, int posY, int width, int height, Color color); // Draw rectangle outline
-RLAPI void DrawRectangleT(int posX, int posY, int width, int height, Color color); // Draw rectangle using text character
+RLAPI void DrawRectangleLinesEx(Rectangle rec, int lineThick, Color color); // Draw rectangle outline with extended parameters
RLAPI void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle
RLAPI void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline
RLAPI void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a regular polygon (Vector version)
@@ -912,19 +895,24 @@ RLAPI void UnloadImage(Image image);
RLAPI void UnloadTexture(Texture2D texture); // Unload texture from GPU memory (VRAM)
RLAPI void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory (VRAM)
RLAPI Color *GetImageData(Image image); // Get pixel data from image as a Color struct array
+RLAPI int GetPixelDataSize(int width, int height, int format); // Get pixel data size in bytes (image or texture)
RLAPI Image GetTextureData(Texture2D texture); // Get pixel data from GPU texture and return an Image
RLAPI void UpdateTexture(Texture2D texture, const void *pixels); // Update GPU texture with new data
RLAPI void SaveImageAs(const char *fileName, Image image); // Save image to a PNG file
// Image manipulation functions
+RLAPI Image ImageCopy(Image image); // Create an image duplicate (useful for transformations)
RLAPI void ImageToPOT(Image *image, Color fillColor); // Convert image to POT (power-of-two)
RLAPI void ImageFormat(Image *image, int newFormat); // Convert image data to desired format
RLAPI void ImageAlphaMask(Image *image, Image alphaMask); // Apply alpha mask to image
-RLAPI void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp); // Dither image data to 16bpp or lower (Floyd-Steinberg dithering)
-RLAPI Image ImageCopy(Image image); // Create an image duplicate (useful for transformations)
+RLAPI void ImageAlphaClear(Image *image, Color color, float threshold); // Clear alpha channel to desired color
+RLAPI void ImageAlphaCrop(Image *image, float threshold); // Crop image depending on alpha value
+RLAPI void ImageAlphaPremultiply(Image *image); // Premultiply alpha channel
RLAPI void ImageCrop(Image *image, Rectangle crop); // Crop an image to a defined rectangle
RLAPI void ImageResize(Image *image, int newWidth, int newHeight); // Resize and image (bilinear filtering)
RLAPI void ImageResizeNN(Image *image,int newWidth,int newHeight); // Resize and image (Nearest-Neighbor scaling algorithm)
+RLAPI void ImageMipmaps(Image *image); // Generate all mipmap levels for a provided image
+RLAPI void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp); // Dither image data to 16bpp or lower (Floyd-Steinberg dithering)
RLAPI Image ImageText(const char *text, int fontSize, Color color); // Create an image from text (default font)
RLAPI Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing, Color tint); // Create an image from text (custom sprite font)
RLAPI void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec); // Draw a source image within a destination image
@@ -940,12 +928,13 @@ RLAPI void ImageColorContrast(Image *image, float contrast);
RLAPI void ImageColorBrightness(Image *image, int brightness); // Modify image color: brightness (-255 to 255)
// Image generation functions
+RLAPI Image GenImageColor(int width, int height, Color color); // Generate image: plain color
RLAPI Image GenImageGradientV(int width, int height, Color top, Color bottom); // Generate image: vertical gradient
RLAPI Image GenImageGradientH(int width, int height, Color left, Color right); // Generate image: horizontal gradient
RLAPI Image GenImageGradientRadial(int width, int height, float density, Color inner, Color outer); // Generate image: radial gradient
RLAPI Image GenImageChecked(int width, int height, int checksX, int checksY, Color col1, Color col2); // Generate image: checked
RLAPI Image GenImageWhiteNoise(int width, int height, float factor); // Generate image: white noise
-RLAPI Image GenImagePerlinNoise(int width, int height, float scale); // Generate image: perlin noise
+RLAPI Image GenImagePerlinNoise(int width, int height, int offsetX, int offsetY, float scale); // Generate image: perlin noise
RLAPI Image GenImageCellular(int width, int height, int tileSize); // Generate image: cellular algorithm. Bigger tileSize means bigger cells
// Texture2D configuration functions
@@ -969,19 +958,20 @@ RLAPI void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle dest
RLAPI SpriteFont GetDefaultFont(void); // Get the default SpriteFont
RLAPI SpriteFont LoadSpriteFont(const char *fileName); // Load SpriteFont from file into GPU memory (VRAM)
RLAPI SpriteFont LoadSpriteFontEx(const char *fileName, int fontSize, int charsCount, int *fontChars); // Load SpriteFont from file with extended parameters
-RLAPI void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory (VRAM)
+RLAPI void UnloadSpriteFont(SpriteFont font); // Unload SpriteFont from GPU memory (VRAM)
// Text drawing functions
RLAPI void DrawFPS(int posX, int posY); // Shows current FPS
RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font)
-RLAPI void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, // Draw text using SpriteFont and additional parameters
+RLAPI void DrawTextEx(SpriteFont font, const char* text, Vector2 position, // Draw text using SpriteFont and additional parameters
float fontSize, int spacing, Color tint);
// Text misc. functions
RLAPI int MeasureText(const char *text, int fontSize); // Measure string width for default font
-RLAPI Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, int spacing); // Measure string size for SpriteFont
+RLAPI Vector2 MeasureTextEx(SpriteFont font, const char *text, float fontSize, int spacing); // Measure string size for SpriteFont
RLAPI const char *FormatText(const char *text, ...); // Formatting of text with variables to 'embed'
RLAPI const char *SubText(const char *text, int position, int length); // Get a piece of a text string
+RLAPI int GetGlyphIndex(SpriteFont font, int character); // Returns index position for a unicode character on sprite font
//------------------------------------------------------------------------------------
// Basic 3d Shapes Drawing Functions (Module: models)
@@ -1018,6 +1008,11 @@ RLAPI void UnloadModel(Model model);
RLAPI Mesh LoadMesh(const char *fileName); // Load mesh from file
RLAPI void UnloadMesh(Mesh *mesh); // Unload mesh from memory (RAM and/or VRAM)
+// Mesh manipulation functions
+RLAPI BoundingBox MeshBoundingBox(Mesh mesh); // Compute mesh bounding box limits
+RLAPI void MeshTangents(Mesh *mesh); // Compute mesh tangents
+RLAPI void MeshBinormals(Mesh *mesh); // Compute mesh binormals
+
// Mesh generation functions
RLAPI Mesh GenMeshPlane(float width, float length, int resX, int resZ); // Generate plane mesh (with subdivisions)
RLAPI Mesh GenMeshCube(float width, float height, float length); // Generate cuboid mesh
@@ -1047,7 +1042,6 @@ RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRe
Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec
// Collision detection functions
-RLAPI BoundingBox CalculateBoundingBox(Mesh mesh); // Calculate mesh bounding box limits
RLAPI bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB); // Detect collision between two spheres
RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Detect collision between two bounding boxes
RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 centerSphere, float radiusSphere); // Detect collision between box and sphere
@@ -1066,7 +1060,8 @@ RLAPI RayHitInfo GetCollisionRayGround(Ray ray, float groundHeight);
// Shader loading/unloading functions
RLAPI char *LoadText(const char *fileName); // Load chars array from text file
-RLAPI Shader LoadShader(char *vsFileName, char *fsFileName); // Load shader from files and bind default locations
+RLAPI Shader LoadShader(const char *vsFileName, const char *fsFileName); // Load shader from files and bind default locations
+RLAPI Shader LoadShaderCode(char *vsCode, char *fsCode); // Load shader from code strings and bind default locations
RLAPI void UnloadShader(Shader shader); // Unload shader from GPU memory (VRAM)
RLAPI Shader GetShaderDefault(void); // Get default shader
@@ -1074,11 +1069,12 @@ RLAPI Texture2D GetTextureDefault(void); // Get
// Shader configuration functions
RLAPI int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location
-RLAPI void SetShaderValue(Shader shader, int uniformLoc, float *value, int size); // Set shader uniform value (float)
-RLAPI void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size); // Set shader uniform value (int)
+RLAPI void SetShaderValue(Shader shader, int uniformLoc, const float *value, int size); // Set shader uniform value (float)
+RLAPI void SetShaderValuei(Shader shader, int uniformLoc, const int *value, int size); // Set shader uniform value (int)
RLAPI void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat); // Set shader uniform value (matrix 4x4)
RLAPI void SetMatrixProjection(Matrix proj); // Set a custom projection matrix (replaces internal projection matrix)
RLAPI void SetMatrixModelview(Matrix view); // Set a custom modelview matrix (replaces internal modelview matrix)
+RLAPI Matrix GetMatrixModelview(); // Get internal modelview matrix
// Texture maps generation (PBR)
// NOTE: Required shaders should be provided
@@ -1094,14 +1090,15 @@ RLAPI void BeginBlendMode(int mode); // Beg
RLAPI void EndBlendMode(void); // End blending mode (reset to default: alpha blending)
// VR control functions
-VrDeviceInfo GetVrDeviceInfo(int vrDeviceType); // Get VR device information for some standard devices
-void InitVrSimulator(VrDeviceInfo info); // Init VR simulator for selected device parameters
-RLAPI void CloseVrSimulator(void); // Close VR simulator for current device
-RLAPI bool IsVrSimulatorReady(void); // Detect if VR simulator is ready
-RLAPI void UpdateVrTracking(Camera *camera); // Update VR tracking (position and orientation) and camera
-RLAPI void ToggleVrMode(void); // Enable/Disable VR experience
-RLAPI void BeginVrDrawing(void); // Begin VR simulator stereo rendering
-RLAPI void EndVrDrawing(void); // End VR simulator stereo rendering
+RLAPI VrDeviceInfo GetVrDeviceInfo(int vrDeviceType); // Get VR device information for some standard devices
+RLAPI void InitVrSimulator(VrDeviceInfo info); // Init VR simulator for selected device parameters
+RLAPI void CloseVrSimulator(void); // Close VR simulator for current device
+RLAPI bool IsVrSimulatorReady(void); // Detect if VR simulator is ready
+RLAPI void SetVrDistortionShader(Shader shader); // Set VR distortion shader for stereoscopic rendering
+RLAPI void UpdateVrTracking(Camera *camera); // Update VR tracking (position and orientation) and camera
+RLAPI void ToggleVrMode(void); // Enable/Disable VR experience
+RLAPI void BeginVrDrawing(void); // Begin VR simulator stereo rendering
+RLAPI void EndVrDrawing(void); // End VR simulator stereo rendering
//------------------------------------------------------------------------------------
// Audio Loading and Playing Functions (Module: audio)
@@ -1146,7 +1143,7 @@ RLAPI void ResumeMusicStream(Music music); // Resume
RLAPI bool IsMusicPlaying(Music music); // Check if music is playing
RLAPI void SetMusicVolume(Music music, float volume); // Set volume for music (1.0 is max level)
RLAPI void SetMusicPitch(Music music, float pitch); // Set pitch for a music (1.0 is base level)
-RLAPI void SetMusicLoopCount(Music music, float count); // Set music loop count (loop repeats)
+RLAPI void SetMusicLoopCount(Music music, int count); // Set music loop count (loop repeats)
RLAPI float GetMusicTimeLength(Music music); // Get music time length (in seconds)
RLAPI float GetMusicTimePlayed(Music music); // Get current music time played (in seconds)
@@ -1159,7 +1156,10 @@ RLAPI bool IsAudioBufferProcessed(AudioStream stream); // Check i
RLAPI void PlayAudioStream(AudioStream stream); // Play audio stream
RLAPI void PauseAudioStream(AudioStream stream); // Pause audio stream
RLAPI void ResumeAudioStream(AudioStream stream); // Resume audio stream
+RLAPI bool IsAudioStreamPlaying(AudioStream stream); // Check if audio stream is playing
RLAPI void StopAudioStream(AudioStream stream); // Stop audio stream
+RLAPI void SetAudioStreamVolume(AudioStream stream, float volume); // Set volume for audio stream (1.0 is max level)
+RLAPI void SetAudioStreamPitch(AudioStream stream, float pitch); // Set pitch for audio stream (1.0 is base level)
#ifdef __cplusplus
}
diff --git a/release/libs/android/armeabi-v7a/libopenal.a b/release/libs/android/armeabi-v7a/libopenal.a
deleted file mode 100644
index ffc90321a..000000000
Binary files a/release/libs/android/armeabi-v7a/libopenal.a and /dev/null differ
diff --git a/release/libs/android/armeabi-v7a/libopenal.so b/release/libs/android/armeabi-v7a/libopenal.so
deleted file mode 100644
index d0f913a64..000000000
Binary files a/release/libs/android/armeabi-v7a/libopenal.so and /dev/null differ
diff --git a/release/libs/android/armeabi-v7a/libraylib.a b/release/libs/android/armeabi-v7a/libraylib.a
index 4802cda0b..1e6a00886 100644
Binary files a/release/libs/android/armeabi-v7a/libraylib.a and b/release/libs/android/armeabi-v7a/libraylib.a differ
diff --git a/release/libs/html5/libraylib.bc b/release/libs/html5/libraylib.bc
index a92e7d17c..afcf46709 100644
Binary files a/release/libs/html5/libraylib.bc and b/release/libs/html5/libraylib.bc differ
diff --git a/release/libs/linux/ADDLIBS b/release/libs/linux/ADDLIBS
deleted file mode 100644
index e69de29bb..000000000
diff --git a/release/libs/linux/libglfw3.a b/release/libs/linux/libglfw3.a
deleted file mode 100644
index 84cc1d202..000000000
Binary files a/release/libs/linux/libglfw3.a and /dev/null differ
diff --git a/release/libs/linux/libraylib.a b/release/libs/linux/libraylib.a
new file mode 100644
index 000000000..5a14e1d35
Binary files /dev/null and b/release/libs/linux/libraylib.a differ
diff --git a/release/libs/osx/ADDLIBS b/release/libs/osx/ADDLIBS
deleted file mode 100644
index e69de29bb..000000000
diff --git a/release/libs/osx/libglfw.3.0.dylib b/release/libs/osx/libglfw.3.0.dylib
deleted file mode 100644
index 15674573c..000000000
Binary files a/release/libs/osx/libglfw.3.0.dylib and /dev/null differ
diff --git a/release/libs/osx/libglfw.3.dylib b/release/libs/osx/libglfw.3.dylib
deleted file mode 100644
index cd20112e3..000000000
--- a/release/libs/osx/libglfw.3.dylib
+++ /dev/null
@@ -1 +0,0 @@
-libglfw.3.0.dylib
\ No newline at end of file
diff --git a/release/libs/osx/libglfw.dylib b/release/libs/osx/libglfw.dylib
deleted file mode 100644
index d4bd51e18..000000000
--- a/release/libs/osx/libglfw.dylib
+++ /dev/null
@@ -1 +0,0 @@
-libglfw.3.dylib
\ No newline at end of file
diff --git a/release/libs/osx/libraylib.a b/release/libs/osx/libraylib.a
new file mode 100644
index 000000000..8520bf7bf
Binary files /dev/null and b/release/libs/osx/libraylib.a differ
diff --git a/release/libs/osx/libraylib.dylib b/release/libs/osx/libraylib.dylib
new file mode 100644
index 000000000..4a0fc9af9
Binary files /dev/null and b/release/libs/osx/libraylib.dylib differ
diff --git a/release/libs/win32/mingw32/OpenAL32.dll b/release/libs/win32/mingw32/OpenAL32.dll
deleted file mode 100644
index 13b3fcae6..000000000
Binary files a/release/libs/win32/mingw32/OpenAL32.dll and /dev/null differ
diff --git a/release/libs/win32/mingw32/glfw3.dll b/release/libs/win32/mingw32/glfw3.dll
deleted file mode 100644
index 9f5d40f6e..000000000
Binary files a/release/libs/win32/mingw32/glfw3.dll and /dev/null differ
diff --git a/release/libs/win32/mingw32/glfw3.lib b/release/libs/win32/mingw32/glfw3.lib
deleted file mode 100644
index 741756ab6..000000000
Binary files a/release/libs/win32/mingw32/glfw3.lib and /dev/null differ
diff --git a/release/libs/win32/mingw32/libOpenAL32.a b/release/libs/win32/mingw32/libOpenAL32.a
deleted file mode 100644
index 2cc6917e4..000000000
Binary files a/release/libs/win32/mingw32/libOpenAL32.a and /dev/null differ
diff --git a/release/libs/win32/mingw32/libOpenAL32dll.a b/release/libs/win32/mingw32/libOpenAL32dll.a
deleted file mode 100644
index cafac41ee..000000000
Binary files a/release/libs/win32/mingw32/libOpenAL32dll.a and /dev/null differ
diff --git a/release/libs/win32/mingw32/libglfw3.a b/release/libs/win32/mingw32/libglfw3.a
deleted file mode 100644
index d50ffa724..000000000
Binary files a/release/libs/win32/mingw32/libglfw3.a and /dev/null differ
diff --git a/release/libs/win32/mingw32/libglfw3dll.a b/release/libs/win32/mingw32/libglfw3dll.a
deleted file mode 100644
index a42a400b1..000000000
Binary files a/release/libs/win32/mingw32/libglfw3dll.a and /dev/null differ
diff --git a/release/libs/win32/mingw32/libraylib.a b/release/libs/win32/mingw32/libraylib.a
index da618b7b3..361aa73c2 100644
Binary files a/release/libs/win32/mingw32/libraylib.a and b/release/libs/win32/mingw32/libraylib.a differ
diff --git a/release/libs/win32/mingw32/libraylibdll.a b/release/libs/win32/mingw32/libraylibdll.a
index 7d910eeb0..b4f1cb6b9 100644
Binary files a/release/libs/win32/mingw32/libraylibdll.a and b/release/libs/win32/mingw32/libraylibdll.a differ
diff --git a/release/libs/win32/mingw32/raylib.dll b/release/libs/win32/mingw32/raylib.dll
index c53876547..54d086ac8 100644
Binary files a/release/libs/win32/mingw32/raylib.dll and b/release/libs/win32/mingw32/raylib.dll differ
diff --git a/release/libs/win32/mingw32/raylib.h b/release/libs/win32/mingw32/raylib.h
deleted file mode 100644
index 392e0a24c..000000000
--- a/release/libs/win32/mingw32/raylib.h
+++ /dev/null
@@ -1,1168 +0,0 @@
-/**********************************************************************************************
-*
-* raylib v1.8.0
-*
-* A simple and easy-to-use library to learn videogames programming (www.raylib.com)
-*
-* FEATURES:
-* - Written in plain C code (C99) in PascalCase/camelCase notation
-* - Multiple platforms support: Windows, Linux, Mac, Android, Raspberry Pi and HTML5
-* - Hardware accelerated with OpenGL (1.1, 2.1, 3.3 or ES 2.0)
-* - Unique OpenGL abstraction layer (usable as standalone module): [rlgl]
-* - Powerful fonts module with SpriteFonts support (XNA bitmap fonts, AngelCode fonts, TTF)
-* - Outstanding texture formats support, including compressed formats (DXT, ETC, PVRT, ASTC)
-* - Basic 3d support for Geometrics, Models, Billboards, Heightmaps and Cubicmaps
-* - Flexible Materials system, supporting classic maps and PBR maps
-* - Shaders support, including Model shaders and Postprocessing shaders
-* - Powerful math module for Vector2, Vector3, Matrix and Quaternion operations: [raymath]
-* - Audio loading and playing with streaming support and mixing channels: [audio]
-* - VR stereo rendering support with configurable HMD device parameters
-* - Minimal external dependencies (GLFW3, OpenGL, OpenAL)
-* - Complete bindings to LUA (raylib-lua) and Go (raylib-go)
-*
-* NOTES:
-* One custom font is loaded by default when InitWindow() [core]
-* If using OpenGL 3.3 or ES2, one default shader is loaded automatically (internally defined) [rlgl]
-* If using OpenGL 3.3 or ES2, several vertex buffers (VAO/VBO) are created to manage lines-triangles-quads
-*
-* DEPENDENCIES:
-* GLFW3 (www.glfw.org) for window/context management and input [core]
-* GLAD for OpenGL extensions loading (3.3 Core profile, only PLATFORM_DESKTOP) [rlgl]
-* OpenAL Soft for audio device/context management [audio]
-*
-* OPTIONAL DEPENDENCIES:
-* stb_image (Sean Barret) for images loading (JPEG, PNG, BMP, TGA) [textures]
-* stb_image_resize (Sean Barret) for image resizing algorythms [textures]
-* stb_image_write (Sean Barret) for image writting (PNG) [utils]
-* stb_truetype (Sean Barret) for ttf fonts loading [text]
-* stb_vorbis (Sean Barret) for ogg audio loading [audio]
-* stb_perlin (Sean Barret) for Perlin noise image generation [textures]
-* par_shapes (Philip Rideout) for parametric 3d shapes generation [models]
-* jar_xm (Joshua Reisenauer) for XM audio module loading [audio]
-* jar_mod (Joshua Reisenauer) for MOD audio module loading [audio]
-* dr_flac (David Reid) for FLAC audio file loading [audio]
-* rgif (Charlie Tangora, Ramon Santamaria) for GIF recording [core]
-* tinfl for data decompression (DEFLATE algorithm) [rres]
-*
-*
-* LICENSE: zlib/libpng
-*
-* raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified,
-* BSD-like license that allows static linking with closed source software:
-*
-* Copyright (c) 2013-2017 Ramon Santamaria (@raysan5)
-*
-* This software is provided "as-is", without any express or implied warranty. In no event
-* will the authors be held liable for any damages arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose, including commercial
-* applications, and to alter it and redistribute it freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not claim that you
-* wrote the original software. If you use this software in a product, an acknowledgment
-* in the product documentation would be appreciated but is not required.
-*
-* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
-* as being the original software.
-*
-* 3. This notice may not be removed or altered from any source distribution.
-*
-**********************************************************************************************/
-
-#ifndef RAYLIB_H
-#define RAYLIB_H
-
-// Choose your platform here or just define it at compile time: -DPLATFORM_DESKTOP
-//#define PLATFORM_DESKTOP // Windows, Linux or OSX
-//#define PLATFORM_ANDROID // Android device
-//#define PLATFORM_RPI // Raspberry Pi
-//#define PLATFORM_WEB // HTML5 (emscripten, asm.js)
-
-// Security check in case no PLATFORM_* defined
-#if !defined(PLATFORM_DESKTOP) && \
- !defined(PLATFORM_ANDROID) && \
- !defined(PLATFORM_RPI) && \
- !defined(PLATFORM_WEB)
- #define PLATFORM_DESKTOP
-#endif
-
-#if defined(_WIN32) && defined(BUILD_LIBTYPE_SHARED)
- #define RLAPI __declspec(dllexport) // We are building raylib as a Win32 shared library (.dll)
-#elif defined(_WIN32) && defined(USE_LIBTYPE_SHARED)
- #define RLAPI __declspec(dllimport) // We are using raylib as a Win32 shared library (.dll)
-#else
- #define RLAPI // We are building or using raylib as a static library (or Linux shared library)
-#endif
-
-//----------------------------------------------------------------------------------
-// Some basic Defines
-//----------------------------------------------------------------------------------
-#ifndef PI
- #define PI 3.14159265358979323846f
-#endif
-
-#define DEG2RAD (PI/180.0f)
-#define RAD2DEG (180.0f/PI)
-
-// raylib Config Flags
-#define FLAG_SHOW_LOGO 1 // Set to show raylib logo at startup
-#define FLAG_FULLSCREEN_MODE 2 // Set to run program in fullscreen
-#define FLAG_WINDOW_RESIZABLE 4 // Set to allow resizable window
-#define FLAG_WINDOW_DECORATED 8 // Set to show window decoration (frame and buttons)
-#define FLAG_WINDOW_TRANSPARENT 16 // Set to allow transparent window
-#define FLAG_MSAA_4X_HINT 32 // Set to try enabling MSAA 4X
-#define FLAG_VSYNC_HINT 64 // Set to try enabling V-Sync on GPU
-
-// Keyboard Function Keys
-#define KEY_SPACE 32
-#define KEY_ESCAPE 256
-#define KEY_ENTER 257
-#define KEY_BACKSPACE 259
-#define KEY_RIGHT 262
-#define KEY_LEFT 263
-#define KEY_DOWN 264
-#define KEY_UP 265
-#define KEY_F1 290
-#define KEY_F2 291
-#define KEY_F3 292
-#define KEY_F4 293
-#define KEY_F5 294
-#define KEY_F6 295
-#define KEY_F7 296
-#define KEY_F8 297
-#define KEY_F9 298
-#define KEY_F10 299
-#define KEY_F11 300
-#define KEY_F12 301
-#define KEY_LEFT_SHIFT 340
-#define KEY_LEFT_CONTROL 341
-#define KEY_LEFT_ALT 342
-#define KEY_RIGHT_SHIFT 344
-#define KEY_RIGHT_CONTROL 345
-#define KEY_RIGHT_ALT 346
-
-// Keyboard Alpha Numeric Keys
-#define KEY_ZERO 48
-#define KEY_ONE 49
-#define KEY_TWO 50
-#define KEY_THREE 51
-#define KEY_FOUR 52
-#define KEY_FIVE 53
-#define KEY_SIX 54
-#define KEY_SEVEN 55
-#define KEY_EIGHT 56
-#define KEY_NINE 57
-#define KEY_A 65
-#define KEY_B 66
-#define KEY_C 67
-#define KEY_D 68
-#define KEY_E 69
-#define KEY_F 70
-#define KEY_G 71
-#define KEY_H 72
-#define KEY_I 73
-#define KEY_J 74
-#define KEY_K 75
-#define KEY_L 76
-#define KEY_M 77
-#define KEY_N 78
-#define KEY_O 79
-#define KEY_P 80
-#define KEY_Q 81
-#define KEY_R 82
-#define KEY_S 83
-#define KEY_T 84
-#define KEY_U 85
-#define KEY_V 86
-#define KEY_W 87
-#define KEY_X 88
-#define KEY_Y 89
-#define KEY_Z 90
-
-#if defined(PLATFORM_ANDROID)
- // Android Physical Buttons
- #define KEY_BACK 4
- #define KEY_MENU 82
- #define KEY_VOLUME_UP 24
- #define KEY_VOLUME_DOWN 25
-#endif
-
-// Mouse Buttons
-#define MOUSE_LEFT_BUTTON 0
-#define MOUSE_RIGHT_BUTTON 1
-#define MOUSE_MIDDLE_BUTTON 2
-
-// Touch points registered
-#define MAX_TOUCH_POINTS 2
-
-// Gamepad Number
-#define GAMEPAD_PLAYER1 0
-#define GAMEPAD_PLAYER2 1
-#define GAMEPAD_PLAYER3 2
-#define GAMEPAD_PLAYER4 3
-
-// Gamepad Buttons/Axis
-
-// PS3 USB Controller Buttons
-#define GAMEPAD_PS3_BUTTON_TRIANGLE 0
-#define GAMEPAD_PS3_BUTTON_CIRCLE 1
-#define GAMEPAD_PS3_BUTTON_CROSS 2
-#define GAMEPAD_PS3_BUTTON_SQUARE 3
-#define GAMEPAD_PS3_BUTTON_L1 6
-#define GAMEPAD_PS3_BUTTON_R1 7
-#define GAMEPAD_PS3_BUTTON_L2 4
-#define GAMEPAD_PS3_BUTTON_R2 5
-#define GAMEPAD_PS3_BUTTON_START 8
-#define GAMEPAD_PS3_BUTTON_SELECT 9
-#define GAMEPAD_PS3_BUTTON_UP 24
-#define GAMEPAD_PS3_BUTTON_RIGHT 25
-#define GAMEPAD_PS3_BUTTON_DOWN 26
-#define GAMEPAD_PS3_BUTTON_LEFT 27
-#define GAMEPAD_PS3_BUTTON_PS 12
-
-// PS3 USB Controller Axis
-#define GAMEPAD_PS3_AXIS_LEFT_X 0
-#define GAMEPAD_PS3_AXIS_LEFT_Y 1
-#define GAMEPAD_PS3_AXIS_RIGHT_X 2
-#define GAMEPAD_PS3_AXIS_RIGHT_Y 5
-#define GAMEPAD_PS3_AXIS_L2 3 // [1..-1] (pressure-level)
-#define GAMEPAD_PS3_AXIS_R2 4 // [1..-1] (pressure-level)
-
-// Xbox360 USB Controller Buttons
-#define GAMEPAD_XBOX_BUTTON_A 0
-#define GAMEPAD_XBOX_BUTTON_B 1
-#define GAMEPAD_XBOX_BUTTON_X 2
-#define GAMEPAD_XBOX_BUTTON_Y 3
-#define GAMEPAD_XBOX_BUTTON_LB 4
-#define GAMEPAD_XBOX_BUTTON_RB 5
-#define GAMEPAD_XBOX_BUTTON_SELECT 6
-#define GAMEPAD_XBOX_BUTTON_START 7
-#define GAMEPAD_XBOX_BUTTON_UP 10
-#define GAMEPAD_XBOX_BUTTON_RIGHT 11
-#define GAMEPAD_XBOX_BUTTON_DOWN 12
-#define GAMEPAD_XBOX_BUTTON_LEFT 13
-#define GAMEPAD_XBOX_BUTTON_HOME 8
-
-// Xbox360 USB Controller Axis
-// NOTE: For Raspberry Pi, axis must be reconfigured
-#if defined(PLATFORM_RPI)
- #define GAMEPAD_XBOX_AXIS_LEFT_X 0 // [-1..1] (left->right)
- #define GAMEPAD_XBOX_AXIS_LEFT_Y 1 // [-1..1] (up->down)
- #define GAMEPAD_XBOX_AXIS_RIGHT_X 3 // [-1..1] (left->right)
- #define GAMEPAD_XBOX_AXIS_RIGHT_Y 4 // [-1..1] (up->down)
- #define GAMEPAD_XBOX_AXIS_LT 2 // [-1..1] (pressure-level)
- #define GAMEPAD_XBOX_AXIS_RT 5 // [-1..1] (pressure-level)
-#else
- #define GAMEPAD_XBOX_AXIS_LEFT_X 0 // [-1..1] (left->right)
- #define GAMEPAD_XBOX_AXIS_LEFT_Y 1 // [1..-1] (up->down)
- #define GAMEPAD_XBOX_AXIS_RIGHT_X 2 // [-1..1] (left->right)
- #define GAMEPAD_XBOX_AXIS_RIGHT_Y 3 // [1..-1] (up->down)
- #define GAMEPAD_XBOX_AXIS_LT 4 // [-1..1] (pressure-level)
- #define GAMEPAD_XBOX_AXIS_RT 5 // [-1..1] (pressure-level)
-#endif
-
-// NOTE: MSC C++ compiler does not support compound literals (C99 feature)
-// Plain structures in C++ (without constructors) can be initialized from { } initializers.
-#ifdef __cplusplus
- #define CLITERAL
-#else
- #define CLITERAL (Color)
-#endif
-
-// Some Basic Colors
-// NOTE: Custom raylib color palette for amazing visuals on WHITE background
-#define LIGHTGRAY CLITERAL{ 200, 200, 200, 255 } // Light Gray
-#define GRAY CLITERAL{ 130, 130, 130, 255 } // Gray
-#define DARKGRAY CLITERAL{ 80, 80, 80, 255 } // Dark Gray
-#define YELLOW CLITERAL{ 253, 249, 0, 255 } // Yellow
-#define GOLD CLITERAL{ 255, 203, 0, 255 } // Gold
-#define ORANGE CLITERAL{ 255, 161, 0, 255 } // Orange
-#define PINK CLITERAL{ 255, 109, 194, 255 } // Pink
-#define RED CLITERAL{ 230, 41, 55, 255 } // Red
-#define MAROON CLITERAL{ 190, 33, 55, 255 } // Maroon
-#define GREEN CLITERAL{ 0, 228, 48, 255 } // Green
-#define LIME CLITERAL{ 0, 158, 47, 255 } // Lime
-#define DARKGREEN CLITERAL{ 0, 117, 44, 255 } // Dark Green
-#define SKYBLUE CLITERAL{ 102, 191, 255, 255 } // Sky Blue
-#define BLUE CLITERAL{ 0, 121, 241, 255 } // Blue
-#define DARKBLUE CLITERAL{ 0, 82, 172, 255 } // Dark Blue
-#define PURPLE CLITERAL{ 200, 122, 255, 255 } // Purple
-#define VIOLET CLITERAL{ 135, 60, 190, 255 } // Violet
-#define DARKPURPLE CLITERAL{ 112, 31, 126, 255 } // Dark Purple
-#define BEIGE CLITERAL{ 211, 176, 131, 255 } // Beige
-#define BROWN CLITERAL{ 127, 106, 79, 255 } // Brown
-#define DARKBROWN CLITERAL{ 76, 63, 47, 255 } // Dark Brown
-
-#define WHITE CLITERAL{ 255, 255, 255, 255 } // White
-#define BLACK CLITERAL{ 0, 0, 0, 255 } // Black
-#define BLANK CLITERAL{ 0, 0, 0, 0 } // Blank (Transparent)
-#define MAGENTA CLITERAL{ 255, 0, 255, 255 } // Magenta
-#define RAYWHITE CLITERAL{ 245, 245, 245, 255 } // My own White (raylib logo)
-
-// Shader and material limits
-#define MAX_SHADER_LOCATIONS 32 // Maximum number of predefined locations stored in shader struct
-#define MAX_MATERIAL_MAPS 12 // Maximum number of texture maps stored in shader struct
-
-//----------------------------------------------------------------------------------
-// Structures Definition
-//----------------------------------------------------------------------------------
-#ifndef __cplusplus
-// Boolean type
- #ifndef bool
- typedef enum { false, true } bool;
- #endif
-#endif
-
-// Vector2 type
-typedef struct Vector2 {
- float x;
- float y;
-} Vector2;
-
-// Vector3 type
-typedef struct Vector3 {
- float x;
- float y;
- float z;
-} Vector3;
-
-// Matrix type (OpenGL style 4x4 - right handed, column major)
-typedef struct Matrix {
- float m0, m4, m8, m12;
- float m1, m5, m9, m13;
- float m2, m6, m10, m14;
- float m3, m7, m11, m15;
-} Matrix;
-
-// Color type, RGBA (32bit)
-typedef struct Color {
- unsigned char r;
- unsigned char g;
- unsigned char b;
- unsigned char a;
-} Color;
-
-// Rectangle type
-typedef struct Rectangle {
- int x;
- int y;
- int width;
- int height;
-} Rectangle;
-
-// Image type, bpp always RGBA (32bit)
-// NOTE: Data stored in CPU memory (RAM)
-typedef struct Image {
- void *data; // Image raw data
- int width; // Image base width
- int height; // Image base height
- int mipmaps; // Mipmap levels, 1 by default
- int format; // Data format (TextureFormat type)
-} Image;
-
-// Texture2D type
-// NOTE: Data stored in GPU memory
-typedef struct Texture2D {
- unsigned int id; // OpenGL texture id
- int width; // Texture base width
- int height; // Texture base height
- int mipmaps; // Mipmap levels, 1 by default
- int format; // Data format (TextureFormat type)
-} Texture2D;
-
-// RenderTexture2D type, for texture rendering
-typedef struct RenderTexture2D {
- unsigned int id; // OpenGL Framebuffer Object (FBO) id
- Texture2D texture; // Color buffer attachment texture
- Texture2D depth; // Depth buffer attachment texture
-} RenderTexture2D;
-
-// SpriteFont character info
-typedef struct CharInfo {
- int value; // Character value (Unicode)
- Rectangle rec; // Character rectangle in sprite font
- int offsetX; // Character offset X when drawing
- int offsetY; // Character offset Y when drawing
- int advanceX; // Character advance position X
-} CharInfo;
-
-// SpriteFont type, includes texture and charSet array data
-typedef struct SpriteFont {
- Texture2D texture; // Font texture
- int baseSize; // Base size (default chars height)
- int charsCount; // Number of characters
- CharInfo *chars; // Characters info data
-} SpriteFont;
-
-// Camera type, defines a camera position/orientation in 3d space
-typedef struct Camera {
- Vector3 position; // Camera position
- Vector3 target; // Camera target it looks-at
- Vector3 up; // Camera up vector (rotation over its axis)
- float fovy; // Camera field-of-view apperture in Y (degrees)
-} Camera;
-
-// Camera2D type, defines a 2d camera
-typedef struct Camera2D {
- Vector2 offset; // Camera offset (displacement from target)
- Vector2 target; // Camera target (rotation and zoom origin)
- float rotation; // Camera rotation in degrees
- float zoom; // Camera zoom (scaling), should be 1.0f by default
-} Camera2D;
-
-// Bounding box type
-typedef struct BoundingBox {
- Vector3 min; // Minimum vertex box-corner
- Vector3 max; // Maximum vertex box-corner
-} BoundingBox;
-
-// Vertex data definning a mesh
-// NOTE: Data stored in CPU memory (and GPU)
-typedef struct Mesh {
- int vertexCount; // Number of vertices stored in arrays
- int triangleCount; // Number of triangles stored (indexed or not)
-
- float *vertices; // Vertex position (XYZ - 3 components per vertex) (shader-location = 0)
- float *texcoords; // Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1)
- float *texcoords2; // Vertex second texture coordinates (useful for lightmaps) (shader-location = 5)
- float *normals; // Vertex normals (XYZ - 3 components per vertex) (shader-location = 2)
- float *tangents; // Vertex tangents (XYZ - 3 components per vertex) (shader-location = 4)
- unsigned char *colors; // Vertex colors (RGBA - 4 components per vertex) (shader-location = 3)
- unsigned short *indices;// Vertex indices (in case vertex data comes indexed)
-
- unsigned int vaoId; // OpenGL Vertex Array Object id
- unsigned int vboId[7]; // OpenGL Vertex Buffer Objects id (7 types of vertex data)
-} Mesh;
-
-// Shader type (generic)
-typedef struct Shader {
- unsigned int id; // Shader program id
- int locs[MAX_SHADER_LOCATIONS]; // Shader locations array
-} Shader;
-
-// Material texture map
-typedef struct MaterialMap {
- Texture2D texture; // Material map texture
- Color color; // Material map color
- float value; // Material map value
-} MaterialMap;
-
-// Material type (generic)
-typedef struct Material {
- Shader shader; // Material shader
- MaterialMap maps[MAX_MATERIAL_MAPS]; // Material maps
- float *params; // Material generic parameters (if required)
-} Material;
-
-// Model type
-typedef struct Model {
- Mesh mesh; // Vertex data buffers (RAM and VRAM)
- Matrix transform; // Local transform matrix
- Material material; // Shader and textures data
-} Model;
-
-// Ray type (useful for raycast)
-typedef struct Ray {
- Vector3 position; // Ray position (origin)
- Vector3 direction; // Ray direction
-} Ray;
-
-// Raycast hit information
-typedef struct RayHitInfo {
- bool hit; // Did the ray hit something?
- float distance; // Distance to nearest hit
- Vector3 position; // Position of nearest hit
- Vector3 normal; // Surface normal of hit
-} RayHitInfo;
-
-// Wave type, defines audio wave data
-typedef struct Wave {
- unsigned int sampleCount; // Number of samples
- unsigned int sampleRate; // Frequency (samples per second)
- unsigned int sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported)
- unsigned int channels; // Number of channels (1-mono, 2-stereo)
- void *data; // Buffer data pointer
-} Wave;
-
-// Sound source type
-typedef struct Sound {
- unsigned int source; // OpenAL audio source id
- unsigned int buffer; // OpenAL audio buffer id
- int format; // OpenAL audio format specifier
-} Sound;
-
-// Music type (file streaming from memory)
-// NOTE: Anything longer than ~10 seconds should be streamed
-typedef struct MusicData *Music;
-
-// Audio stream type
-// NOTE: Useful to create custom audio streams not bound to a specific file
-typedef struct AudioStream {
- unsigned int sampleRate; // Frequency (samples per second)
- unsigned int sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported)
- unsigned int channels; // Number of channels (1-mono, 2-stereo)
-
- int format; // OpenAL audio format specifier
- unsigned int source; // OpenAL audio source id
- unsigned int buffers[2]; // OpenAL audio buffers (double buffering)
-} AudioStream;
-
-// rRES data returned when reading a resource,
-// it contains all required data for user (24 byte)
-typedef struct RRESData {
- unsigned int type; // Resource type (4 byte)
-
- unsigned int param1; // Resouce parameter 1 (4 byte)
- unsigned int param2; // Resouce parameter 2 (4 byte)
- unsigned int param3; // Resouce parameter 3 (4 byte)
- unsigned int param4; // Resouce parameter 4 (4 byte)
-
- void *data; // Resource data pointer (4 byte)
-} RRESData;
-
-// RRES type (pointer to RRESData array)
-typedef struct RRESData *RRES;
-
-// Head-Mounted-Display device parameters
-typedef struct VrDeviceInfo {
- int hResolution; // HMD horizontal resolution in pixels
- int vResolution; // HMD vertical resolution in pixels
- float hScreenSize; // HMD horizontal size in meters
- float vScreenSize; // HMD vertical size in meters
- float vScreenCenter; // HMD screen center in meters
- float eyeToScreenDistance; // HMD distance between eye and display in meters
- float lensSeparationDistance; // HMD lens separation distance in meters
- float interpupillaryDistance; // HMD IPD (distance between pupils) in meters
- float lensDistortionValues[4]; // HMD lens distortion constant parameters
- float chromaAbCorrection[4]; // HMD chromatic aberration correction parameters
-} VrDeviceInfo;
-
-//----------------------------------------------------------------------------------
-// Enumerators Definition
-//----------------------------------------------------------------------------------
-// Trace log type
-typedef enum {
- LOG_INFO = 0,
- LOG_WARNING,
- LOG_ERROR,
- LOG_DEBUG,
- LOG_OTHER
-} LogType;
-
-// Shader location point type
-typedef enum {
- LOC_VERTEX_POSITION = 0,
- LOC_VERTEX_TEXCOORD01,
- LOC_VERTEX_TEXCOORD02,
- LOC_VERTEX_NORMAL,
- LOC_VERTEX_TANGENT,
- LOC_VERTEX_COLOR,
- LOC_MATRIX_MVP,
- LOC_MATRIX_MODEL,
- LOC_MATRIX_VIEW,
- LOC_MATRIX_PROJECTION,
- LOC_VECTOR_VIEW,
- LOC_COLOR_DIFFUSE,
- LOC_COLOR_SPECULAR,
- LOC_COLOR_AMBIENT,
- LOC_MAP_ALBEDO, // LOC_MAP_DIFFUSE
- LOC_MAP_METALNESS, // LOC_MAP_SPECULAR
- LOC_MAP_NORMAL,
- LOC_MAP_ROUGHNESS,
- LOC_MAP_OCCUSION,
- LOC_MAP_EMISSION,
- LOC_MAP_HEIGHT,
- LOC_MAP_CUBEMAP,
- LOC_MAP_IRRADIANCE,
- LOC_MAP_PREFILTER,
- LOC_MAP_BRDF
-} ShaderLocationIndex;
-
-#define LOC_MAP_DIFFUSE LOC_MAP_ALBEDO
-#define LOC_MAP_SPECULAR LOC_MAP_METALNESS
-
-// Material map type
-typedef enum {
- MAP_ALBEDO = 0, // MAP_DIFFUSE
- MAP_METALNESS = 1, // MAP_SPECULAR
- MAP_NORMAL = 2,
- MAP_ROUGHNESS = 3,
- MAP_OCCLUSION,
- MAP_EMISSION,
- MAP_HEIGHT,
- MAP_CUBEMAP, // NOTE: Uses GL_TEXTURE_CUBE_MAP
- MAP_IRRADIANCE, // NOTE: Uses GL_TEXTURE_CUBE_MAP
- MAP_PREFILTER, // NOTE: Uses GL_TEXTURE_CUBE_MAP
- MAP_BRDF
-} TexmapIndex;
-
-#define MAP_DIFFUSE MAP_ALBEDO
-#define MAP_SPECULAR MAP_METALNESS
-
-// Texture formats
-// NOTE: Support depends on OpenGL version and platform
-typedef enum {
- UNCOMPRESSED_GRAYSCALE = 1, // 8 bit per pixel (no alpha)
- UNCOMPRESSED_GRAY_ALPHA, // 16 bpp (2 channels)
- UNCOMPRESSED_R5G6B5, // 16 bpp
- UNCOMPRESSED_R8G8B8, // 24 bpp
- UNCOMPRESSED_R5G5B5A1, // 16 bpp (1 bit alpha)
- UNCOMPRESSED_R4G4B4A4, // 16 bpp (4 bit alpha)
- UNCOMPRESSED_R8G8B8A8, // 32 bpp
- UNCOMPRESSED_R32G32B32, // 32 bit per channel (float) - HDR
- COMPRESSED_DXT1_RGB, // 4 bpp (no alpha)
- COMPRESSED_DXT1_RGBA, // 4 bpp (1 bit alpha)
- COMPRESSED_DXT3_RGBA, // 8 bpp
- COMPRESSED_DXT5_RGBA, // 8 bpp
- COMPRESSED_ETC1_RGB, // 4 bpp
- COMPRESSED_ETC2_RGB, // 4 bpp
- COMPRESSED_ETC2_EAC_RGBA, // 8 bpp
- COMPRESSED_PVRT_RGB, // 4 bpp
- COMPRESSED_PVRT_RGBA, // 4 bpp
- COMPRESSED_ASTC_4x4_RGBA, // 8 bpp
- COMPRESSED_ASTC_8x8_RGBA // 2 bpp
-} TextureFormat;
-
-// Texture parameters: filter mode
-// NOTE 1: Filtering considers mipmaps if available in the texture
-// NOTE 2: Filter is accordingly set for minification and magnification
-typedef enum {
- FILTER_POINT = 0, // No filter, just pixel aproximation
- FILTER_BILINEAR, // Linear filtering
- FILTER_TRILINEAR, // Trilinear filtering (linear with mipmaps)
- FILTER_ANISOTROPIC_4X, // Anisotropic filtering 4x
- FILTER_ANISOTROPIC_8X, // Anisotropic filtering 8x
- FILTER_ANISOTROPIC_16X, // Anisotropic filtering 16x
-} TextureFilterMode;
-
-// Texture parameters: wrap mode
-typedef enum {
- WRAP_REPEAT = 0,
- WRAP_CLAMP,
- WRAP_MIRROR
-} TextureWrapMode;
-
-// Color blending modes (pre-defined)
-typedef enum {
- BLEND_ALPHA = 0,
- BLEND_ADDITIVE,
- BLEND_MULTIPLIED
-} BlendMode;
-
-// Gestures type
-// NOTE: It could be used as flags to enable only some gestures
-typedef enum {
- GESTURE_NONE = 0,
- GESTURE_TAP = 1,
- GESTURE_DOUBLETAP = 2,
- GESTURE_HOLD = 4,
- GESTURE_DRAG = 8,
- GESTURE_SWIPE_RIGHT = 16,
- GESTURE_SWIPE_LEFT = 32,
- GESTURE_SWIPE_UP = 64,
- GESTURE_SWIPE_DOWN = 128,
- GESTURE_PINCH_IN = 256,
- GESTURE_PINCH_OUT = 512
-} Gestures;
-
-// Camera system modes
-typedef enum {
- CAMERA_CUSTOM = 0,
- CAMERA_FREE,
- CAMERA_ORBITAL,
- CAMERA_FIRST_PERSON,
- CAMERA_THIRD_PERSON
-} CameraMode;
-
-// Head Mounted Display devices
-typedef enum {
- HMD_DEFAULT_DEVICE = 0,
- HMD_OCULUS_RIFT_DK2,
- HMD_OCULUS_RIFT_CV1,
- HMD_OCULUS_GO,
- HMD_VALVE_HTC_VIVE,
- HMD_SONY_PSVR
-} VrDeviceType;
-
-// RRESData type
-typedef enum {
- RRES_TYPE_RAW = 0,
- RRES_TYPE_IMAGE,
- RRES_TYPE_WAVE,
- RRES_TYPE_VERTEX,
- RRES_TYPE_TEXT,
- RRES_TYPE_FONT_IMAGE,
- RRES_TYPE_FONT_CHARDATA, // CharInfo data array
- RRES_TYPE_DIRECTORY
-} RRESDataType;
-
-#ifdef __cplusplus
-extern "C" { // Prevents name mangling of functions
-#endif
-
-//------------------------------------------------------------------------------------
-// Global Variables Definition
-//------------------------------------------------------------------------------------
-// It's lonely here...
-
-//------------------------------------------------------------------------------------
-// Window and Graphics Device Functions (Module: core)
-//------------------------------------------------------------------------------------
-
-// Window-related functions
-#if defined(PLATFORM_ANDROID)
-RLAPI void InitWindow(int width, int height, void *state); // Initialize Android activity
-#elif defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
-RLAPI void InitWindow(int width, int height, const char *title); // Initialize window and OpenGL context
-#endif
-RLAPI void CloseWindow(void); // Close window and unload OpenGL context
-RLAPI bool WindowShouldClose(void); // Check if KEY_ESCAPE pressed or Close icon pressed
-RLAPI bool IsWindowMinimized(void); // Check if window has been minimized (or lost focus)
-RLAPI void ToggleFullscreen(void); // Toggle fullscreen mode (only PLATFORM_DESKTOP)
-RLAPI void SetWindowIcon(Image image); // Set icon for window (only PLATFORM_DESKTOP)
-RLAPI void SetWindowTitle(const char *title); // Set title for window (only PLATFORM_DESKTOP)
-RLAPI void SetWindowPosition(int x, int y); // Set window position on screen (only PLATFORM_DESKTOP)
-RLAPI void SetWindowMonitor(int monitor); // Set monitor for the current window (fullscreen mode)
-RLAPI void SetWindowMinSize(int width, int height); // Set window minimum dimensions (for FLAG_WINDOW_RESIZABLE)
-RLAPI int GetScreenWidth(void); // Get current screen width
-RLAPI int GetScreenHeight(void); // Get current screen height
-
-#if !defined(PLATFORM_ANDROID)
-// Cursor-related functions
-RLAPI void ShowCursor(void); // Shows cursor
-RLAPI void HideCursor(void); // Hides cursor
-RLAPI bool IsCursorHidden(void); // Check if cursor is not visible
-RLAPI void EnableCursor(void); // Enables cursor (unlock cursor)
-RLAPI void DisableCursor(void); // Disables cursor (lock cursor)
-#endif
-
-// Drawing-related functions
-RLAPI void ClearBackground(Color color); // Set background color (framebuffer clear color)
-RLAPI void BeginDrawing(void); // Setup canvas (framebuffer) to start drawing
-RLAPI void EndDrawing(void); // End canvas drawing and swap buffers (double buffering)
-RLAPI void Begin2dMode(Camera2D camera); // Initialize 2D mode with custom camera (2D)
-RLAPI void End2dMode(void); // Ends 2D mode with custom camera
-RLAPI void Begin3dMode(Camera camera); // Initializes 3D mode with custom camera (3D)
-RLAPI void End3dMode(void); // Ends 3D mode and returns to default 2D orthographic mode
-RLAPI void BeginTextureMode(RenderTexture2D target); // Initializes render texture for drawing
-RLAPI void EndTextureMode(void); // Ends drawing to render texture
-
-// Screen-space-related functions
-RLAPI Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Returns a ray trace from mouse position
-RLAPI Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Returns the screen space position for a 3d world space position
-RLAPI Matrix GetCameraMatrix(Camera camera); // Returns camera transform matrix (view matrix)
-
-// Timming-related functions
-RLAPI void SetTargetFPS(int fps); // Set target FPS (maximum)
-RLAPI int GetFPS(void); // Returns current FPS
-RLAPI float GetFrameTime(void); // Returns time in seconds for last frame drawn
-
-// Color-related functions
-RLAPI int GetHexValue(Color color); // Returns hexadecimal value for a Color
-RLAPI Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value
-RLAPI Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0f to 1.0f
-RLAPI float *ColorToFloat(Color color); // Converts Color to float array and normalizes
-
-// Math useful functions (available from raymath.h)
-RLAPI float *VectorToFloat(Vector3 vec); // Returns Vector3 as float array
-RLAPI float *MatrixToFloat(Matrix mat); // Returns Matrix as float array
-RLAPI Vector3 Vector3Zero(void); // Vector with components value 0.0f
-RLAPI Vector3 Vector3One(void); // Vector with components value 1.0f
-RLAPI Matrix MatrixIdentity(void); // Returns identity matrix
-
-// Misc. functions
-RLAPI void ShowLogo(void); // Activate raylib logo at startup (can be done with flags)
-RLAPI void SetConfigFlags(char flags); // Setup window configuration flags (view FLAGS)
-RLAPI void TraceLog(int logType, const char *text, ...); // Show trace log messages (LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_DEBUG)
-RLAPI void TakeScreenshot(const char *fileName); // Takes a screenshot of current screen (saved a .png)
-RLAPI int GetRandomValue(int min, int max); // Returns a random value between min and max (both included)
-
-// Files management functions
-RLAPI bool IsFileExtension(const char *fileName, const char *ext);// Check file extension
-RLAPI const char *GetExtension(const char *fileName); // Get file extension
-RLAPI const char *GetDirectoryPath(const char *fileName); // Get directory for a given fileName (with path)
-RLAPI const char *GetWorkingDirectory(void); // Get current working directory
-RLAPI bool ChangeDirectory(const char *dir); // Change working directory, returns true if success
-RLAPI bool IsFileDropped(void); // Check if a file has been dropped into window
-RLAPI char **GetDroppedFiles(int *count); // Get dropped files names
-RLAPI void ClearDroppedFiles(void); // Clear dropped files paths buffer
-
-// Persistent storage management
-RLAPI void StorageSaveValue(int position, int value); // Save integer value to storage file (to defined position)
-RLAPI int StorageLoadValue(int position); // Load integer value from storage file (from defined position)
-
-//------------------------------------------------------------------------------------
-// Input Handling Functions (Module: core)
-//------------------------------------------------------------------------------------
-
-// Input-related functions: keyboard
-RLAPI bool IsKeyPressed(int key); // Detect if a key has been pressed once
-RLAPI bool IsKeyDown(int key); // Detect if a key is being pressed
-RLAPI bool IsKeyReleased(int key); // Detect if a key has been released once
-RLAPI bool IsKeyUp(int key); // Detect if a key is NOT being pressed
-RLAPI int GetKeyPressed(void); // Get latest key pressed
-RLAPI void SetExitKey(int key); // Set a custom key to exit program (default is ESC)
-
-// Input-related functions: gamepads
-RLAPI bool IsGamepadAvailable(int gamepad); // Detect if a gamepad is available
-RLAPI bool IsGamepadName(int gamepad, const char *name); // Check gamepad name (if available)
-RLAPI const char *GetGamepadName(int gamepad); // Return gamepad internal name id
-RLAPI bool IsGamepadButtonPressed(int gamepad, int button); // Detect if a gamepad button has been pressed once
-RLAPI bool IsGamepadButtonDown(int gamepad, int button); // Detect if a gamepad button is being pressed
-RLAPI bool IsGamepadButtonReleased(int gamepad, int button); // Detect if a gamepad button has been released once
-RLAPI bool IsGamepadButtonUp(int gamepad, int button); // Detect if a gamepad button is NOT being pressed
-RLAPI int GetGamepadButtonPressed(void); // Get the last gamepad button pressed
-RLAPI int GetGamepadAxisCount(int gamepad); // Return gamepad axis count for a gamepad
-RLAPI float GetGamepadAxisMovement(int gamepad, int axis); // Return axis movement value for a gamepad axis
-
-// Input-related functions: mouse
-RLAPI bool IsMouseButtonPressed(int button); // Detect if a mouse button has been pressed once
-RLAPI bool IsMouseButtonDown(int button); // Detect if a mouse button is being pressed
-RLAPI bool IsMouseButtonReleased(int button); // Detect if a mouse button has been released once
-RLAPI bool IsMouseButtonUp(int button); // Detect if a mouse button is NOT being pressed
-RLAPI int GetMouseX(void); // Returns mouse position X
-RLAPI int GetMouseY(void); // Returns mouse position Y
-RLAPI Vector2 GetMousePosition(void); // Returns mouse position XY
-RLAPI void SetMousePosition(Vector2 position); // Set mouse position XY
-RLAPI int GetMouseWheelMove(void); // Returns mouse wheel movement Y
-
-// Input-related functions: touch
-RLAPI int GetTouchX(void); // Returns touch position X for touch point 0 (relative to screen size)
-RLAPI int GetTouchY(void); // Returns touch position Y for touch point 0 (relative to screen size)
-RLAPI Vector2 GetTouchPosition(int index); // Returns touch position XY for a touch point index (relative to screen size)
-
-//------------------------------------------------------------------------------------
-// Gestures and Touch Handling Functions (Module: gestures)
-//------------------------------------------------------------------------------------
-RLAPI void SetGesturesEnabled(unsigned int gestureFlags); // Enable a set of gestures using flags
-RLAPI bool IsGestureDetected(int gesture); // Check if a gesture have been detected
-RLAPI int GetGestureDetected(void); // Get latest detected gesture
-RLAPI int GetTouchPointsCount(void); // Get touch points count
-RLAPI float GetGestureHoldDuration(void); // Get gesture hold time in milliseconds
-RLAPI Vector2 GetGestureDragVector(void); // Get gesture drag vector
-RLAPI float GetGestureDragAngle(void); // Get gesture drag angle
-RLAPI Vector2 GetGesturePinchVector(void); // Get gesture pinch delta
-RLAPI float GetGesturePinchAngle(void); // Get gesture pinch angle
-
-//------------------------------------------------------------------------------------
-// Camera System Functions (Module: camera)
-//------------------------------------------------------------------------------------
-RLAPI void SetCameraMode(Camera camera, int mode); // Set camera mode (multiple camera modes available)
-RLAPI void UpdateCamera(Camera *camera); // Update camera position for selected mode
-
-RLAPI void SetCameraPanControl(int panKey); // Set camera pan key to combine with mouse movement (free camera)
-RLAPI void SetCameraAltControl(int altKey); // Set camera alt key to combine with mouse movement (free camera)
-RLAPI void SetCameraSmoothZoomControl(int szKey); // Set camera smooth zoom key to combine with mouse (free camera)
-RLAPI void SetCameraMoveControls(int frontKey, int backKey,
- int rightKey, int leftKey,
- int upKey, int downKey); // Set camera move controls (1st person and 3rd person cameras)
-
-//------------------------------------------------------------------------------------
-// Basic Shapes Drawing Functions (Module: shapes)
-//------------------------------------------------------------------------------------
-
-// Basic shapes drawing functions
-RLAPI void DrawPixel(int posX, int posY, Color color); // Draw a pixel
-RLAPI void DrawPixelV(Vector2 position, Color color); // Draw a pixel (Vector version)
-RLAPI void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw a line
-RLAPI void DrawLineV(Vector2 startPos, Vector2 endPos, Color color); // Draw a line (Vector version)
-RLAPI void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw a line defining thickness
-RLAPI void DrawLineBezier(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw a line using cubic-bezier curves in-out
-RLAPI void DrawCircle(int centerX, int centerY, float radius, Color color); // Draw a color-filled circle
-RLAPI void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2); // Draw a gradient-filled circle
-RLAPI void DrawCircleV(Vector2 center, float radius, Color color); // Draw a color-filled circle (Vector version)
-RLAPI void DrawCircleLines(int centerX, int centerY, float radius, Color color); // Draw circle outline
-RLAPI void DrawRectangle(int posX, int posY, int width, int height, Color color); // Draw a color-filled rectangle
-RLAPI void DrawRectangleRec(Rectangle rec, Color color); // Draw a color-filled rectangle
-RLAPI void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color); // Draw a color-filled rectangle with pro parameters
-RLAPI void DrawRectangleGradientV(int posX, int posY, int width, int height, Color color1, Color color2);// Draw a vertical-gradient-filled rectangle
-RLAPI void DrawRectangleGradientH(int posX, int posY, int width, int height, Color color1, Color color2);// Draw a horizontal-gradient-filled rectangle
-RLAPI void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4); // Draw a gradient-filled rectangle with custom vertex colors
-RLAPI void DrawRectangleV(Vector2 position, Vector2 size, Color color); // Draw a color-filled rectangle (Vector version)
-RLAPI void DrawRectangleLines(int posX, int posY, int width, int height, Color color); // Draw rectangle outline
-RLAPI void DrawRectangleT(int posX, int posY, int width, int height, Color color); // Draw rectangle using text character
-RLAPI void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle
-RLAPI void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline
-RLAPI void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a regular polygon (Vector version)
-RLAPI void DrawPolyEx(Vector2 *points, int numPoints, Color color); // Draw a closed polygon defined by points
-RLAPI void DrawPolyExLines(Vector2 *points, int numPoints, Color color); // Draw polygon lines
-
-// Basic shapes collision detection functions
-RLAPI bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2); // Check collision between two rectangles
-RLAPI bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, float radius2); // Check collision between two circles
-RLAPI bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec); // Check collision between circle and rectangle
-RLAPI Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2); // Get collision rectangle for two rectangles collision
-RLAPI bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle
-RLAPI bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius); // Check if point is inside circle
-RLAPI bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3); // Check if point is inside a triangle
-
-//------------------------------------------------------------------------------------
-// Texture Loading and Drawing Functions (Module: textures)
-//------------------------------------------------------------------------------------
-
-// Image/Texture2D data loading/unloading/saving functions
-RLAPI Image LoadImage(const char *fileName); // Load image from file into CPU memory (RAM)
-RLAPI Image LoadImageEx(Color *pixels, int width, int height); // Load image from Color array data (RGBA - 32bit)
-RLAPI Image LoadImagePro(void *data, int width, int height, int format); // Load image from raw data with parameters
-RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image from RAW file data
-RLAPI Texture2D LoadTexture(const char *fileName); // Load texture from file into GPU memory (VRAM)
-RLAPI Texture2D LoadTextureFromImage(Image image); // Load texture from image data
-RLAPI RenderTexture2D LoadRenderTexture(int width, int height); // Load texture for rendering (framebuffer)
-RLAPI void UnloadImage(Image image); // Unload image from CPU memory (RAM)
-RLAPI void UnloadTexture(Texture2D texture); // Unload texture from GPU memory (VRAM)
-RLAPI void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory (VRAM)
-RLAPI Color *GetImageData(Image image); // Get pixel data from image as a Color struct array
-RLAPI Image GetTextureData(Texture2D texture); // Get pixel data from GPU texture and return an Image
-RLAPI void UpdateTexture(Texture2D texture, const void *pixels); // Update GPU texture with new data
-RLAPI void SaveImageAs(const char *fileName, Image image); // Save image to a PNG file
-
-// Image manipulation functions
-RLAPI void ImageToPOT(Image *image, Color fillColor); // Convert image to POT (power-of-two)
-RLAPI void ImageFormat(Image *image, int newFormat); // Convert image data to desired format
-RLAPI void ImageAlphaMask(Image *image, Image alphaMask); // Apply alpha mask to image
-RLAPI void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp); // Dither image data to 16bpp or lower (Floyd-Steinberg dithering)
-RLAPI Image ImageCopy(Image image); // Create an image duplicate (useful for transformations)
-RLAPI void ImageCrop(Image *image, Rectangle crop); // Crop an image to a defined rectangle
-RLAPI void ImageResize(Image *image, int newWidth, int newHeight); // Resize and image (bilinear filtering)
-RLAPI void ImageResizeNN(Image *image,int newWidth,int newHeight); // Resize and image (Nearest-Neighbor scaling algorithm)
-RLAPI Image ImageText(const char *text, int fontSize, Color color); // Create an image from text (default font)
-RLAPI Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing, Color tint); // Create an image from text (custom sprite font)
-RLAPI void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec); // Draw a source image within a destination image
-RLAPI void ImageDrawText(Image *dst, Vector2 position, const char *text, int fontSize, Color color); // Draw text (default font) within an image (destination)
-RLAPI void ImageDrawTextEx(Image *dst, Vector2 position, SpriteFont font, const char *text,
- float fontSize, int spacing, Color color); // Draw text (custom sprite font) within an image (destination)
-RLAPI void ImageFlipVertical(Image *image); // Flip image vertically
-RLAPI void ImageFlipHorizontal(Image *image); // Flip image horizontally
-RLAPI void ImageColorTint(Image *image, Color color); // Modify image color: tint
-RLAPI void ImageColorInvert(Image *image); // Modify image color: invert
-RLAPI void ImageColorGrayscale(Image *image); // Modify image color: grayscale
-RLAPI void ImageColorContrast(Image *image, float contrast); // Modify image color: contrast (-100 to 100)
-RLAPI void ImageColorBrightness(Image *image, int brightness); // Modify image color: brightness (-255 to 255)
-
-// Image generation functions
-RLAPI Image GenImageGradientV(int width, int height, Color top, Color bottom); // Generate image: vertical gradient
-RLAPI Image GenImageGradientH(int width, int height, Color left, Color right); // Generate image: horizontal gradient
-RLAPI Image GenImageGradientRadial(int width, int height, float density, Color inner, Color outer); // Generate image: radial gradient
-RLAPI Image GenImageChecked(int width, int height, int checksX, int checksY, Color col1, Color col2); // Generate image: checked
-RLAPI Image GenImageWhiteNoise(int width, int height, float factor); // Generate image: white noise
-RLAPI Image GenImagePerlinNoise(int width, int height, float scale); // Generate image: perlin noise
-RLAPI Image GenImageCellular(int width, int height, int tileSize); // Generate image: cellular algorithm. Bigger tileSize means bigger cells
-
-// Texture2D configuration functions
-RLAPI void GenTextureMipmaps(Texture2D *texture); // Generate GPU mipmaps for a texture
-RLAPI void SetTextureFilter(Texture2D texture, int filterMode); // Set texture scaling filter mode
-RLAPI void SetTextureWrap(Texture2D texture, int wrapMode); // Set texture wrapping mode
-
-// Texture2D drawing functions
-RLAPI void DrawTexture(Texture2D texture, int posX, int posY, Color tint); // Draw a Texture2D
-RLAPI void DrawTextureV(Texture2D texture, Vector2 position, Color tint); // Draw a Texture2D with position defined as Vector2
-RLAPI void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint); // Draw a Texture2D with extended parameters
-RLAPI void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint); // Draw a part of a texture defined by a rectangle
-RLAPI void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, // Draw a part of a texture defined by a rectangle with 'pro' parameters
- float rotation, Color tint);
-
-//------------------------------------------------------------------------------------
-// Font Loading and Text Drawing Functions (Module: text)
-//------------------------------------------------------------------------------------
-
-// SpriteFont loading/unloading functions
-RLAPI SpriteFont GetDefaultFont(void); // Get the default SpriteFont
-RLAPI SpriteFont LoadSpriteFont(const char *fileName); // Load SpriteFont from file into GPU memory (VRAM)
-RLAPI SpriteFont LoadSpriteFontEx(const char *fileName, int fontSize, int charsCount, int *fontChars); // Load SpriteFont from file with extended parameters
-RLAPI void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory (VRAM)
-
-// Text drawing functions
-RLAPI void DrawFPS(int posX, int posY); // Shows current FPS
-RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font)
-RLAPI void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, // Draw text using SpriteFont and additional parameters
- float fontSize, int spacing, Color tint);
-
-// Text misc. functions
-RLAPI int MeasureText(const char *text, int fontSize); // Measure string width for default font
-RLAPI Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, int spacing); // Measure string size for SpriteFont
-RLAPI const char *FormatText(const char *text, ...); // Formatting of text with variables to 'embed'
-RLAPI const char *SubText(const char *text, int position, int length); // Get a piece of a text string
-
-//------------------------------------------------------------------------------------
-// Basic 3d Shapes Drawing Functions (Module: models)
-//------------------------------------------------------------------------------------
-
-// Basic geometric 3D shapes drawing functions
-RLAPI void DrawLine3D(Vector3 startPos, Vector3 endPos, Color color); // Draw a line in 3D world space
-RLAPI void DrawCircle3D(Vector3 center, float radius, Vector3 rotationAxis, float rotationAngle, Color color); // Draw a circle in 3D world space
-RLAPI void DrawCube(Vector3 position, float width, float height, float length, Color color); // Draw cube
-RLAPI void DrawCubeV(Vector3 position, Vector3 size, Color color); // Draw cube (Vector version)
-RLAPI void DrawCubeWires(Vector3 position, float width, float height, float length, Color color); // Draw cube wires
-RLAPI void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float height, float length, Color color); // Draw cube textured
-RLAPI void DrawSphere(Vector3 centerPos, float radius, Color color); // Draw sphere
-RLAPI void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere with extended parameters
-RLAPI void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere wires
-RLAPI void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone
-RLAPI void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone wires
-RLAPI void DrawPlane(Vector3 centerPos, Vector2 size, Color color); // Draw a plane XZ
-RLAPI void DrawRay(Ray ray, Color color); // Draw a ray line
-RLAPI void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0))
-RLAPI void DrawGizmo(Vector3 position); // Draw simple gizmo
-//DrawTorus(), DrawTeapot() could be useful?
-
-//------------------------------------------------------------------------------------
-// Model 3d Loading and Drawing Functions (Module: models)
-//------------------------------------------------------------------------------------
-
-// Model loading/unloading functions
-RLAPI Model LoadModel(const char *fileName); // Load model from files (mesh and material)
-RLAPI Model LoadModelFromMesh(Mesh mesh); // Load model from generated mesh
-RLAPI void UnloadModel(Model model); // Unload model from memory (RAM and/or VRAM)
-
-// Mesh loading/unloading functions
-RLAPI Mesh LoadMesh(const char *fileName); // Load mesh from file
-RLAPI void UnloadMesh(Mesh *mesh); // Unload mesh from memory (RAM and/or VRAM)
-
-// Mesh generation functions
-RLAPI Mesh GenMeshPlane(float width, float length, int resX, int resZ); // Generate plane mesh (with subdivisions)
-RLAPI Mesh GenMeshCube(float width, float height, float length); // Generate cuboid mesh
-RLAPI Mesh GenMeshSphere(float radius, int rings, int slices); // Generate sphere mesh (standard sphere)
-RLAPI Mesh GenMeshHemiSphere(float radius, int rings, int slices); // Generate half-sphere mesh (no bottom cap)
-RLAPI Mesh GenMeshCylinder(float radius, float height, int slices); // Generate cylinder mesh
-RLAPI Mesh GenMeshTorus(float radius, float size, int radSeg, int sides); // Generate torus mesh
-RLAPI Mesh GenMeshKnot(float radius, float size, int radSeg, int sides); // Generate trefoil knot mesh
-RLAPI Mesh GenMeshHeightmap(Image heightmap, Vector3 size); // Generate heightmap mesh from image data
-RLAPI Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize); // Generate cubes-based map mesh from image data
-
-// Material loading/unloading functions
-RLAPI Material LoadMaterial(const char *fileName); // Load material from file
-RLAPI Material LoadMaterialDefault(void); // Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps)
-RLAPI void UnloadMaterial(Material material); // Unload material from GPU memory (VRAM)
-
-// Model drawing functions
-RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set)
-RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis,
- float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters
-RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set)
-RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis,
- float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters
-RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires)
-RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture
-RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec,
- Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec
-
-// Collision detection functions
-RLAPI BoundingBox CalculateBoundingBox(Mesh mesh); // Calculate mesh bounding box limits
-RLAPI bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB); // Detect collision between two spheres
-RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Detect collision between two bounding boxes
-RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 centerSphere, float radiusSphere); // Detect collision between box and sphere
-RLAPI bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius); // Detect collision between ray and sphere
-RLAPI bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadius,
- Vector3 *collisionPoint); // Detect collision between ray and sphere, returns collision point
-RLAPI bool CheckCollisionRayBox(Ray ray, BoundingBox box); // Detect collision between ray and box
-RLAPI RayHitInfo GetCollisionRayMesh(Ray ray, Mesh *mesh); // Get collision info between ray and mesh
-RLAPI RayHitInfo GetCollisionRayTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3); // Get collision info between ray and triangle
-RLAPI RayHitInfo GetCollisionRayGround(Ray ray, float groundHeight); // Get collision info between ray and ground plane (Y-normal plane)
-
-//------------------------------------------------------------------------------------
-// Shaders System Functions (Module: rlgl)
-// NOTE: This functions are useless when using OpenGL 1.1
-//------------------------------------------------------------------------------------
-
-// Shader loading/unloading functions
-RLAPI char *LoadText(const char *fileName); // Load chars array from text file
-RLAPI Shader LoadShader(char *vsFileName, char *fsFileName); // Load shader from files and bind default locations
-RLAPI void UnloadShader(Shader shader); // Unload shader from GPU memory (VRAM)
-
-RLAPI Shader GetShaderDefault(void); // Get default shader
-RLAPI Texture2D GetTextureDefault(void); // Get default texture
-
-// Shader configuration functions
-RLAPI int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location
-RLAPI void SetShaderValue(Shader shader, int uniformLoc, float *value, int size); // Set shader uniform value (float)
-RLAPI void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size); // Set shader uniform value (int)
-RLAPI void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat); // Set shader uniform value (matrix 4x4)
-RLAPI void SetMatrixProjection(Matrix proj); // Set a custom projection matrix (replaces internal projection matrix)
-RLAPI void SetMatrixModelview(Matrix view); // Set a custom modelview matrix (replaces internal modelview matrix)
-
-// Texture maps generation (PBR)
-// NOTE: Required shaders should be provided
-RLAPI Texture2D GenTextureCubemap(Shader shader, Texture2D skyHDR, int size); // Generate cubemap texture from HDR texture
-RLAPI Texture2D GenTextureIrradiance(Shader shader, Texture2D cubemap, int size); // Generate irradiance texture using cubemap data
-RLAPI Texture2D GenTexturePrefilter(Shader shader, Texture2D cubemap, int size); // Generate prefilter texture using cubemap data
-RLAPI Texture2D GenTextureBRDF(Shader shader, Texture2D cubemap, int size); // Generate BRDF texture using cubemap data
-
-// Shading begin/end functions
-RLAPI void BeginShaderMode(Shader shader); // Begin custom shader drawing
-RLAPI void EndShaderMode(void); // End custom shader drawing (use default shader)
-RLAPI void BeginBlendMode(int mode); // Begin blending mode (alpha, additive, multiplied)
-RLAPI void EndBlendMode(void); // End blending mode (reset to default: alpha blending)
-
-// VR control functions
-VrDeviceInfo GetVrDeviceInfo(int vrDeviceType); // Get VR device information for some standard devices
-void InitVrSimulator(VrDeviceInfo info); // Init VR simulator for selected device parameters
-RLAPI void CloseVrSimulator(void); // Close VR simulator for current device
-RLAPI bool IsVrSimulatorReady(void); // Detect if VR simulator is ready
-RLAPI void UpdateVrTracking(Camera *camera); // Update VR tracking (position and orientation) and camera
-RLAPI void ToggleVrMode(void); // Enable/Disable VR experience
-RLAPI void BeginVrDrawing(void); // Begin VR simulator stereo rendering
-RLAPI void EndVrDrawing(void); // End VR simulator stereo rendering
-
-//------------------------------------------------------------------------------------
-// Audio Loading and Playing Functions (Module: audio)
-//------------------------------------------------------------------------------------
-
-// Audio device management functions
-RLAPI void InitAudioDevice(void); // Initialize audio device and context
-RLAPI void CloseAudioDevice(void); // Close the audio device and context
-RLAPI bool IsAudioDeviceReady(void); // Check if audio device has been initialized successfully
-RLAPI void SetMasterVolume(float volume); // Set master volume (listener)
-
-// Wave/Sound loading/unloading functions
-RLAPI Wave LoadWave(const char *fileName); // Load wave data from file
-RLAPI Wave LoadWaveEx(void *data, int sampleCount, int sampleRate, int sampleSize, int channels); // Load wave data from raw array data
-RLAPI Sound LoadSound(const char *fileName); // Load sound from file
-RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound from wave data
-RLAPI void UpdateSound(Sound sound, const void *data, int samplesCount);// Update sound buffer with new data
-RLAPI void UnloadWave(Wave wave); // Unload wave data
-RLAPI void UnloadSound(Sound sound); // Unload sound
-
-// Wave/Sound management functions
-RLAPI void PlaySound(Sound sound); // Play a sound
-RLAPI void PauseSound(Sound sound); // Pause a sound
-RLAPI void ResumeSound(Sound sound); // Resume a paused sound
-RLAPI void StopSound(Sound sound); // Stop playing a sound
-RLAPI bool IsSoundPlaying(Sound sound); // Check if a sound is currently playing
-RLAPI void SetSoundVolume(Sound sound, float volume); // Set volume for a sound (1.0 is max level)
-RLAPI void SetSoundPitch(Sound sound, float pitch); // Set pitch for a sound (1.0 is base level)
-RLAPI void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels); // Convert wave data to desired format
-RLAPI Wave WaveCopy(Wave wave); // Copy a wave to a new wave
-RLAPI void WaveCrop(Wave *wave, int initSample, int finalSample); // Crop a wave to defined samples range
-RLAPI float *GetWaveData(Wave wave); // Get samples data from wave as a floats array
-
-// Music management functions
-RLAPI Music LoadMusicStream(const char *fileName); // Load music stream from file
-RLAPI void UnloadMusicStream(Music music); // Unload music stream
-RLAPI void PlayMusicStream(Music music); // Start music playing
-RLAPI void UpdateMusicStream(Music music); // Updates buffers for music streaming
-RLAPI void StopMusicStream(Music music); // Stop music playing
-RLAPI void PauseMusicStream(Music music); // Pause music playing
-RLAPI void ResumeMusicStream(Music music); // Resume playing paused music
-RLAPI bool IsMusicPlaying(Music music); // Check if music is playing
-RLAPI void SetMusicVolume(Music music, float volume); // Set volume for music (1.0 is max level)
-RLAPI void SetMusicPitch(Music music, float pitch); // Set pitch for a music (1.0 is base level)
-RLAPI void SetMusicLoopCount(Music music, float count); // Set music loop count (loop repeats)
-RLAPI float GetMusicTimeLength(Music music); // Get music time length (in seconds)
-RLAPI float GetMusicTimePlayed(Music music); // Get current music time played (in seconds)
-
-// AudioStream management functions
-RLAPI AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize,
- unsigned int channels); // Init audio stream (to stream raw audio pcm data)
-RLAPI void UpdateAudioStream(AudioStream stream, const void *data, int samplesCount); // Update audio stream buffers with data
-RLAPI void CloseAudioStream(AudioStream stream); // Close audio stream and free memory
-RLAPI bool IsAudioBufferProcessed(AudioStream stream); // Check if any audio stream buffers requires refill
-RLAPI void PlayAudioStream(AudioStream stream); // Play audio stream
-RLAPI void PauseAudioStream(AudioStream stream); // Pause audio stream
-RLAPI void ResumeAudioStream(AudioStream stream); // Resume audio stream
-RLAPI void StopAudioStream(AudioStream stream); // Stop audio stream
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // RAYLIB_H
diff --git a/release/libs/win32/msvc/OpenAL32.dll b/release/libs/win32/msvc/OpenAL32.dll
deleted file mode 100644
index 36b986bdc..000000000
Binary files a/release/libs/win32/msvc/OpenAL32.dll and /dev/null differ
diff --git a/release/libs/win32/msvc/OpenAL32.lib b/release/libs/win32/msvc/OpenAL32.lib
deleted file mode 100644
index 10c4e7e64..000000000
Binary files a/release/libs/win32/msvc/OpenAL32.lib and /dev/null differ
diff --git a/release/libs/win32/msvc/glfw3.dll b/release/libs/win32/msvc/glfw3.dll
deleted file mode 100644
index ebf2933bc..000000000
Binary files a/release/libs/win32/msvc/glfw3.dll and /dev/null differ
diff --git a/release/libs/win32/msvc/glfw3.lib b/release/libs/win32/msvc/glfw3.lib
deleted file mode 100644
index 741756ab6..000000000
Binary files a/release/libs/win32/msvc/glfw3.lib and /dev/null differ
diff --git a/release/libs/win32/msvc/glfw3dll.lib b/release/libs/win32/msvc/glfw3dll.lib
deleted file mode 100644
index 37b406649..000000000
Binary files a/release/libs/win32/msvc/glfw3dll.lib and /dev/null differ
diff --git a/release/libs/win32/msvc/libOpenAL32.dll.a b/release/libs/win32/msvc/libOpenAL32.dll.a
deleted file mode 100644
index 6d07e0007..000000000
Binary files a/release/libs/win32/msvc/libOpenAL32.dll.a and /dev/null differ
diff --git a/release/libs/win32/msvc/raylib.dll b/release/libs/win32/msvc/raylib.dll
new file mode 100644
index 000000000..b9896ff81
Binary files /dev/null and b/release/libs/win32/msvc/raylib.dll differ
diff --git a/release/libs/win32/msvc/raylib.lib b/release/libs/win32/msvc/raylib.lib
index 6983d9a86..451725651 100644
Binary files a/release/libs/win32/msvc/raylib.lib and b/release/libs/win32/msvc/raylib.lib differ
diff --git a/release/libs/win32/msvc/raylibdll.lib b/release/libs/win32/msvc/raylibdll.lib
new file mode 100644
index 000000000..8ad371ae8
Binary files /dev/null and b/release/libs/win32/msvc/raylibdll.lib differ
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index a398d6656..64d7f1fdf 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,26 +1,37 @@
# Setup the project and settings
project(raylib)
-include("../utils.cmake")
+include(GNUInstallDirs)
-set(raylib_VERSION_MAJOR 1)
-set(raylib_VERSION_MINOR 8)
+set(PROJECT_VERSION 1.9.7)
+set(API_VERSION 1)
set(RAYLIB raylib) # Name of the generated library
+include("CMakeOptions.txt")
+configure_file(config.h.in ${CMAKE_BINARY_DIR}/cmake/config.h)
+include_directories(${CMAKE_BINARY_DIR})
+
+include("../utils.cmake")
+
+# Get the sources together
+file(GLOB raylib_sources *.c)
+
+if(glfw3_FOUND)
+ list(REMOVE_ITEM raylib_sources ${CMAKE_CURRENT_SOURCE_DIR}/rglfw.c)
+else()
+ include_directories(external/glfw/include)
+endif()
+
+if(USE_AUDIO)
+ file(GLOB stb_vorbis external/stb_vorbis.c)
+ file(GLOB mini_al external/mini_al.c ${stb_vorbis})
+ set(sources ${raylib_sources} ${mini_al})
+else()
+ set(INCLUDE_AUDIO_MODULE 0)
+ list(REMOVE_ITEM raylib_sources ${CMAKE_CURRENT_SOURCE_DIR}/audio.c)
+ set(sources ${raylib_sources})
+endif()
### Config options ###
-# Build a static or shared raylib?
-set(SHARED_RAYLIB OFF CACHE BOOL "Build raylib as a dynamic library")
-
-# Platform
-set(PLATFORM "Desktop" CACHE STRING "Platform to build for.")
-set_property(CACHE PLATFORM PROPERTY STRINGS "Desktop" "Web" "Android" "Raspberry Pi")
-
-# OpenGL version
-set(OPENGL_VERSION "3.3" CACHE STRING "OpenGL Version to build raylib with")
-set_property(CACHE OPENGL_VERSION PROPERTY STRINGS "3.3" "2.1" "1.1" "ES 2.0")
-### Config options ###
-
-
# Translate the config options to what raylib wants
if(${PLATFORM} MATCHES "Desktop")
set(PLATFORM "PLATFORM_DESKTOP")
@@ -40,7 +51,12 @@ if(${PLATFORM} MATCHES "Desktop")
# See: https://github.com/raysan5/raylib/issues/341
if(APPLE)
set(GRAPHICS "GRAPHICS_API_OPENGL_33")
+ set_source_files_properties(rglfw.c PROPERTIES COMPILE_FLAGS "-x objective-c")
+ link_libraries("${LIBS_PRIVATE}")
+ elseif(WIN32)
+ add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif()
+
elseif(${PLATFORM} MATCHES "Web")
set(PLATFORM "PLATFORM_WEB")
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
@@ -60,51 +76,75 @@ elseif(${PLATFORM} MATCHES "Raspberry Pi")
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
endif()
-# Get the sources together
-file(GLOB raylib_sources *.c)
-file(GLOB stb_vorbis external/stb_vorbis.c)
-set(sources ${raylib_sources} ${stb_vorbis})
+if(MACOS_FATLIB)
+ if (CMAKE_OSX_ARCHITECTURES)
+ message(FATAL_ERROR "User supplied -DCMAKE_OSX_ARCHITECTURES overrides -DMACOS_FATLIB=ON")
+ else()
+ SET(CMAKE_OSX_ARCHITECTURES "x86_64;i386")
+ endif()
+endif()
# Which platform?
if(${PLATFORM} MATCHES "PLATFORM_DESKTOP")
- # Build a static or shared raylib?
- # TODO clean this up a bit?
- if(${SHARED_RAYLIB})
- # Shared library
- add_library(${RAYLIB} SHARED ${sources})
-
- # Will link -framework (if on OS X)
- link_os_x_frameworks(raylib)
- else()
- # Static library
- add_library(${RAYLIB} STATIC ${sources})
-
- if(LINUX)
- # On Linux, need to link a few extra things for static
- target_link_libraries(${RAYLIB} m pthread dl)
- target_link_libraries(${RAYLIB} X11 Xrandr Xinerama Xi Xxf86vm Xcursor) # X11 stuff
+
+ if(${SHARED})
+ add_library(${RAYLIB}_shared SHARED ${sources})
+
+ target_compile_definitions(${RAYLIB}_shared
+ PUBLIC ${PLATFORM}
+ PUBLIC ${GRAPHICS}
+ )
+
+ set_property(TARGET ${RAYLIB}_shared PROPERTY POSITION_INDEPENDENT_CODE ON)
+ set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_LIBDIR}")
+ set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
+ set(CMAKE_MACOSX_RPATH ON)
+
+ target_link_libraries(${RAYLIB}_shared ${LIBS_PRIVATE})
+ set_target_properties(${RAYLIB}_shared PROPERTIES
+ VERSION ${PROJECT_VERSION}
+ SOVERSION ${API_VERSION}
+ PUBLIC_HEADER "raylib.h"
+ )
+ if(WIN32)
+ install(
+ TARGETS ${RAYLIB}_shared
+ RUNTIME DESTINATION lib
+ PUBLIC_HEADER DESTINATION include
+ )
+ else() # Keep lib*.(a|dll) name, but avoid *.lib files overwriting each other on Windows
+ set_target_properties(${RAYLIB}_shared PROPERTIES OUTPUT_NAME ${RAYLIB})
+ install(
+ TARGETS ${RAYLIB}_shared
+ LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+ PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
+ )
endif()
- endif()
-
- # Always need to link OpenAL and OpenGL
- if(LINUX)
- # Elsewhere (such as Linux), need `-lopenal -lGL`
- target_link_libraries(${RAYLIB} openal)
- target_link_libraries(${RAYLIB} GL)
- endif()
-
- # Add in GLFW as a linking target
- target_link_libraries(${RAYLIB} glfw)
-
- # Library file & Header
- set_target_properties(${RAYLIB} PROPERTIES PUBLIC_HEADER "raylib.h")
- install(
- TARGETS ${RAYLIB}
- ARCHIVE DESTINATION lib
- LIBRARY DESTINATION lib
- PUBLIC_HEADER DESTINATION include
- )
-
+ endif(${SHARED})
+
+ if(${STATIC})
+ add_library(${RAYLIB} STATIC ${sources})
+
+ target_compile_definitions(${RAYLIB}
+ PUBLIC ${PLATFORM}
+ PUBLIC ${GRAPHICS}
+ )
+
+ set(PKG_CONFIG_LIBS_PRIVATE ${__PKG_CONFIG_LIBS_PRIVATE})
+
+ if (WITH_PIC)
+ set_property(TARGET ${RAYLIB} PROPERTY POSITION_INDEPENDENT_CODE ON)
+ endif()
+ set_target_properties(${RAYLIB} PROPERTIES PUBLIC_HEADER "raylib.h")
+ install(TARGETS ${RAYLIB}
+ ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+ PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
+ )
+ endif(${STATIC})
+
+ configure_file(../raylib.pc.in raylib.pc @ONLY)
+ install(FILES ${CMAKE_BINARY_DIR}/release/raylib.pc DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
+
# Copy the header files to the build directory
file(COPY "raylib.h" DESTINATION ".")
file(COPY "rlgl.h" DESTINATION ".")
@@ -116,17 +156,21 @@ elseif(${PLATFORM} MATCHES "PLATFORM_WEB")
add_executable(${RAYLIB} ${sources})
endif()
-
-# Set the compile flags to raylib
-target_compile_definitions(${RAYLIB}
- PUBLIC ${PLATFORM}
- PUBLIC ${GRAPHICS}
-)
-
-
-
# Print the flags for the user
message(STATUS "Compiling with the flags:")
message(STATUS " PLATFORM=" ${PLATFORM})
message(STATUS " GRAPHICS=" ${GRAPHICS})
+# Packaging
+SET(CPACK_PACKAGE_NAME "raylib")
+SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Simple and easy-to-use library to learn videogames programming")
+SET(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}")
+SET(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}")
+SET(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}")
+SET(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}")
+SET(CPACK_PACKAGE_DESCRIPTION_FILE "${PROJECT_SOURCE_DIR}/../README.md")
+SET(CPACK_RESOURCE_FILE_WELCOME "${PROJECT_SOURCE_DIR}/../README.md")
+SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/../LICENSE.md")
+SET(CPACK_PACKAGE_FILE_NAME "raylib-${PROJECT_VERSION}$ENV{RAYLIB_PACKAGE_SUFFIX}")
+SET(CPACK_GENERATOR "ZIP;TGZ") # Remove this, if you want the NSIS installer on Windows
+include(CPack)
diff --git a/src/CMakeOptions.txt b/src/CMakeOptions.txt
new file mode 100644
index 000000000..7fc7a9154
--- /dev/null
+++ b/src/CMakeOptions.txt
@@ -0,0 +1,89 @@
+### Config options ###
+include(CMakeDependentOption)
+
+# Shared library is always PIC. Static library should be PIC too if linked into a shared library
+option(WITH_PIC "Compile static library as position-independent code" OFF)
+option(SHARED "Build raylib as a dynamic library" OFF)
+option(STATIC "Build raylib as a static library" ON)
+option(MACOS_FATLIB "Build fat library for both i386 and x86_64 on macOS" ON)
+option(USE_AUDIO "Build raylib with audio module" ON)
+cmake_dependent_option(USE_OPENAL_BACKEND "Link raylib with openAL instead of mini-al" OFF "USE_AUDIO" OFF)
+set(USE_EXTERNAL_GLFW OFF CACHE STRING "Link raylib against system GLFW instead of embedded one")
+set_property(CACHE USE_EXTERNAL_GLFW PROPERTY STRINGS ON OFF IF_POSSIBLE)
+if(UNIX AND NOT APPLE)
+ option(USE_WAYLAND "Use Wayland for window creation" OFF)
+endif()
+
+
+set(PLATFORM "Desktop" CACHE STRING "Platform to build for.")
+set_property(CACHE PLATFORM PROPERTY STRINGS "Desktop" "Web" "Android" "Raspberry Pi")
+
+set(OPENGL_VERSION "3.3" CACHE STRING "OpenGL Version to build raylib with")
+set_property(CACHE OPENGL_VERSION PROPERTY STRINGS "3.3" "2.1" "1.1" "ES 2.0")
+
+# core.c
+option(SUPPORT_BUSY_WAIT_LOOP "Use busy wait loop for timing sync instead of a high-resolution timer" ON)
+option(SUPPORT_CAMERA_SYSTEM "Provide camera module (camera.h) with multiple predefined cameras: free, 1st/3rd person, orbital" ON)
+option(SUPPORT_DEFAULT_FONT "Default font is loaded on window initialization to be available for the user to render simple text. If enabled, uses external module functions to load default raylib font (module: text)" ON)
+option(SUPPORT_GIF_RECORDING "Allow automatic gif recording of current screen pressing CTRL+F12, defined in KeyCallback()" ON)
+option(SUPPORT_GESTURES_SYSTEM "Gestures module is included (gestures.h) to support gestures detection: tap, hold, swipe, drag" ON)
+option(SUPPORT_MOUSE_GESTURES "Mouse gestures are directly mapped like touches and processed by gestures system" ON)
+
+# rlgl.c
+option(SUPPORT_VR_SIMULATOR "Support VR simulation functionality (stereo rendering)" ON)
+option(SUPPORT_DISTORTION_SHADER "Include stereo rendering distortion shader (shader_distortion.h)" ON)
+
+# models.c
+option(SUPPORT_FILEFORMAT_OBJ "Support loading OBJ file format" ON)
+option(SUPPORT_FILEFORMAT_MTL "Support loading MTL file format" ON)
+option(SUPPORT_MESH_GENERATION "Support procedural mesh generation functions, uses external par_shapes.h library. NOTE: Some generated meshes DO NOT include generated texture coordinates" ON)
+
+# textures.c
+option(SUPPORT_IMAGE_GENERATION "Support proedural image generation functionality (gradient, spot, perlin-noise, cellular)" ON)
+option(SUPPORT_FILEFORMAT_PNG "Support loading PNG as textures" ON)
+option(SUPPORT_FILEFORMAT_DDS "Support loading DDS as textures" ON)
+option(SUPPORT_FILEFORMAT_HDR "Support loading HDR as textures" ON)
+option(SUPPORT_FILEFORMAT_KTX "Support loading KTX as textures" ON)
+option(SUPPORT_FILEFORMAT_ASTC "Support loading ASTC as textures" ON)
+option(SUPPORT_FILEFORMAT_BMP "Support loading BMP as textures" OFF)
+option(SUPPORT_FILEFORMAT_TGA "Support loading TGA as textures" OFF)
+option(SUPPORT_FILEFORMAT_JPG "Support loading JPG as textures" OFF)
+option(SUPPORT_FILEFORMAT_GIF "Support loading GIF as textures" OFF)
+option(SUPPORT_FILEFORMAT_PSD "Support loading PSD as textures" OFF)
+option(SUPPORT_FILEFORMAT_PKM "Support loading PKM as textures" OFF)
+option(SUPPORT_FILEFORMAT_PVR "Support loading PVR as textures" OFF)
+
+# audio.c
+option(SUPPORT_FILEFORMAT_WAV "Support loading WAV for sound" ON)
+option(SUPPORT_FILEFORMAT_OGG "Support loading OGG for sound" ON)
+option(SUPPORT_FILEFORMAT_XM "Support loading XM for sound" ON)
+option(SUPPORT_FILEFORMAT_MOD "Support loading MOD for sound" ON)
+option(SUPPORT_FILEFORMAT_FLAC "Support loading FLAC for sound" OFF)
+
+# shapes.c
+option(USE_DEFAULT_FONT_TEXTURE "Draw rectangle shapes using font texture white character instead of default white texture. Allows drawing rectangles and text with a single draw call, very useful for GUI systems!" ON)
+
+# utils.c
+option(SUPPORT_SAVE_PNG "Support saving image data in PNG file format" ON)
+option(SUPPORT_SAVE_BMP "Support saving image data in BMP file format" OFF)
+option(SUPPORT_TRACELOG "Show TraceLog() output messages. NOTE: By default LOG_DEBUG traces not shown" ON)
+
+option(SUPPORT_FILEFORMAT_FNT "Support loading fonts in FNT format" ON)
+option(SUPPORT_FILEFORMAT_TTF "Support loading font in TTF format" ON)
+
+option(SUPPORT_IMAGE_MANIPULATION "Support multiple image editing functions to scale, adjust colors, flip, draw on images, crop... If not defined only three image editing functions supported: ImageFormat(), ImageAlphaMask(), ImageToPOT()" ON)
+
+if(NOT (STATIC OR SHARED))
+ message(FATAL_ERROR "Nothing to do if both -DSHARED=OFF and -DSTATIC=OFF...")
+endif()
+
+if(DEFINED SHARED_RAYLIB)
+ set(SHARED ${SHARED_RAYLIB})
+ message(DEPRECATION "-DSHARED_RAYLIB is deprecated. Please use -DSHARED instead.")
+endif()
+if(DEFINED STATIC_RAYLIB)
+ set(STATIC ${STATIC_RAYLIB})
+ message(DEPRECATION "-DSTATIC_RAYLIB is deprecated. Please use -DSTATIC instead.")
+endif()
+
+# vim: ft=cmake
diff --git a/src/Makefile b/src/Makefile
index 13be78448..8444ed577 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -2,18 +2,19 @@
#
# raylib makefile
#
-# Platforms supported:
-# PLATFORM_DESKTOP: Windows (win32/Win64)
-# PLATFORM_DESKTOP: Linux
-# PLATFORM_DESKTOP: OSX (Mac)
-# PLATFORM_ANDROID: Android (ARM or ARM64)
+# Platforms supported:
+# PLATFORM_DESKTOP: Windows (Win32, Win64)
+# PLATFORM_DESKTOP: Linux (32 and 64 bit)
+# PLATFORM_DESKTOP: OSX/macOS
+# PLATFORM_DESKTOP: FreeBSD
+# PLATFORM_ANDROID: Android (ARM, ARM64)
# PLATFORM_RPI: Raspberry Pi (Raspbian)
# PLATFORM_WEB: HTML5 (Chrome, Firefox)
#
# Many thanks to Milan Nikolic (@gen2brain) for implementing Android platform pipeline.
# Many thanks to Emanuele Petriglia for his contribution on GNU/Linux pipeline.
#
-# Copyright (c) 2014-2017 Ramon Santamaria (@raysan5)
+# Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
#
# This software is provided "as-is", without any express or implied warranty.
# In no event will the authors be held liable for any damages arising from
@@ -35,30 +36,62 @@
#
#******************************************************************************
-# Please read the wiki to know how to compile raylib, because there are
-# different methods.
+# Please read the wiki to know how to compile raylib, because there are different methods.
+# https://github.com/raysan5/raylib/wiki
.PHONY: all clean install uninstall
# Define required raylib variables
-PLATFORM ?= PLATFORM_DESKTOP
-RAYLIB_PATH ?= ..
+RAYLIB_VERSION = 1.9.7
+RAYLIB_API_VERSION = 1
-# Library type used for raylib and OpenAL Soft: STATIC (.a) or SHARED (.so/.dll)
-# NOTE: OpenAL Soft library should be provided in the selected form
-RAYLIB_LIBTYPE ?= STATIC
-OPENAL_LIBTYPE ?= STATIC
+# See below for alternatives.
+RAYLIB_PATH = ..
-# On PLATFORM_WEB force OpenAL Soft shared library
+# Define default options
+
+# One of PLATFORM_DESKTOP, PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB
+PLATFORM ?= PLATFORM_DESKTOP
+
+# Library type used for raylib: STATIC (.a) or SHARED (.so/.dll)
+RAYLIB_LIBTYPE ?= STATIC
+
+# Build mode for library: DEBUG or RELEASE
+RAYLIB_BUILD_MODE ?= RELEASE
+
+# Included raylib audio module on compilation
+# NOTE: Some programs like tools could not require audio support
+INCLUDE_AUDIO_MODULE ?= TRUE
+
+# Use OpenAL Soft backend for audio
+USE_OPENAL_BACKEND ?= FALSE
+
+# OpenAL Soft audio backend forced on HTML5 and OSX (see below)
ifeq ($(PLATFORM),PLATFORM_WEB)
- OPENAL_LIBTYPE = SHARED
+ USE_OPENAL_BACKEND = TRUE
endif
+# Use external GLFW library instead of rglfw module
+# TODO: Review usage of examples on Linux.
+USE_EXTERNAL_GLFW ?= FALSE
+
+# Use Wayland display server protocol on Linux desktop
+# by default it uses X11 windowing system
+USE_WAYLAND_DISPLAY ?= FALSE
+
+# See below for more GRAPHICS options.
+
+# See below for RAYLIB_RELEASE_PATH.
+
+# See install target for *_INSTALL_PATH locations.
+
# Use cross-compiler for PLATFORM_RPI
ifeq ($(PLATFORM),PLATFORM_RPI)
- RPI_CROSS_COMPILE ?= YES
- RPI_TOOLCHAIN ?= C:/SysGCC/Raspberry
- RPI_TOOLCHAIN_SYSROOT ?= $(RPI_TOOLCHAIN)/arm-linux-gnueabihf/sysroot
+ USE_RPI_CROSS_COMPILER ?= FALSE
+ ifeq ($(USE_RPI_CROSS_COMPILER),TRUE)
+ RPI_TOOLCHAIN ?= C:/SysGCC/Raspberry
+ RPI_TOOLCHAIN_SYSROOT ?= $(RPI_TOOLCHAIN)/arm-linux-gnueabihf/sysroot
+ endif
endif
# Determine if the file has root access (only for installing raylib)
@@ -76,19 +109,51 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
UNAMEOS=$(shell uname)
ifeq ($(UNAMEOS),Linux)
PLATFORM_OS=LINUX
- else
+ endif
+ ifeq ($(UNAMEOS),FreeBSD)
+ PLATFORM_OS=FREEBSD
+ endif
ifeq ($(UNAMEOS),Darwin)
PLATFORM_OS=OSX
endif
- endif
endif
endif
+ifeq ($(PLATFORM),PLATFORM_RPI)
+ UNAMEOS=$(shell uname)
+ ifeq ($(UNAMEOS),Linux)
+ PLATFORM_OS=LINUX
+ endif
+endif
+
+# RAYLIB_PATH adjustment for different platforms.
+# If using GNU make, we can get the full path to the top of the tree. Windows? BSD?
+# Required for ldconfig or other tools that do not perform path expansion.
+ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ ifeq ($(PLATFORM_OS),LINUX)
+ RAYLIB_PREFIX ?= ..
+ RAYLIB_PATH = $(realpath $(RAYLIB_PREFIX))
+ endif
+endif
+# Default path for raylib on Raspberry Pi, if installed in different path, update it!
+# TODO: update install: target in src/Makefile for RPI, consider relation to LINUX.
+# WARNING: The following is copied from examples/Makefile and is here only for reference.
+# Consequences of enabling this are UNKNOWN. Please test and report.
+#ifeq ($(PLATFORM),PLATFORM_RPI)
+# RAYLIB_PATH ?= /home/pi/raylib
+#endif
+
+# Force OpenAL Soft audio backend for OSX platform
+# NOTE 1: mini_al library does not support CoreAudio yet
+# NOTE 2: Required OpenAL libraries should be available on OSX
+ifeq ($(PLATFORM_OS),OSX)
+ USE_OPENAL_BACKEND = TRUE
+endif
ifeq ($(PLATFORM),PLATFORM_WEB)
# Emscripten required variables
EMSDK_PATH = C:/emsdk
- EMSCRIPTEN_VERSION = 1.37.21
- CLANG_VERSION=e1.37.21_64bit
+ EMSCRIPTEN_VERSION = 1.37.28
+ CLANG_VERSION=e1.37.28_64bit
PYTHON_VERSION=2.7.5.3_64bit
NODE_VERSION=4.1.1_64bit
export PATH=$(EMSDK_PATH);$(EMSDK_PATH)\clang\$(CLANG_VERSION);$(EMSDK_PATH)\node\$(NODE_VERSION)\bin;$(EMSDK_PATH)\python\$(PYTHON_VERSION);$(EMSDK_PATH)\emscripten\$(EMSCRIPTEN_VERSION);C:\raylib\MinGW\bin:$$(PATH)
@@ -104,7 +169,9 @@ ifeq ($(PLATFORM),PLATFORM_ANDROID)
ANDROID_ARCH ?= ARM
endif
-RAYLIB_RELEASE_PATH ?= $(RAYLIB_PATH)/release/libs
+# RAYLIB_RELEASE_PATH points to provided binaries or your immediate build of raylib.
+# It is further modified below by PLATFORM below.
+RAYLIB_RELEASE_PATH ?= $(RAYLIB_PATH)/release/libs
# Define output directory for compiled library
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
@@ -117,6 +184,9 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),OSX)
RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/osx
endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/freebsd
+ endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/rpi
@@ -140,23 +210,20 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
#GRAPHICS = GRAPHICS_API_OPENGL_11 # Uncomment to use OpenGL 1.1
#GRAPHICS = GRAPHICS_API_OPENGL_21 # Uncomment to use OpenGL 2.1
endif
-
ifeq ($(PLATFORM),PLATFORM_RPI)
# On RPI OpenGL ES 2.0 must be used
GRAPHICS = GRAPHICS_API_OPENGL_ES2
endif
-
ifeq ($(PLATFORM),PLATFORM_WEB)
# On HTML5 OpenGL ES 2.0 is used, emscripten translates it to WebGL 1.0
GRAPHICS = GRAPHICS_API_OPENGL_ES2
endif
-
ifeq ($(PLATFORM),PLATFORM_ANDROID)
# By default use OpenGL ES 2.0 on Android
GRAPHICS = GRAPHICS_API_OPENGL_ES2
endif
-# Default C compiler: gcc
+# Define default C compiler: gcc
# NOTE: define g++ compiler if using C++
CC = gcc
@@ -164,10 +231,15 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),OSX)
# OSX default compiler
CC = clang
+ GLFW_CFLAGS = -x objective-c
+ endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ # FreeBSD default compiler
+ CC = clang
endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
- ifeq ($(RPI_CROSS_COMPILE),YES)
+ ifeq ($(USE_RPI_CROSS_COMPILER),TRUE)
# Define RPI cross-compiler
#CC = armv6j-hardfloat-linux-gnueabi-gcc
CC = $(RPI_TOOLCHAIN)/bin/arm-linux-gnueabihf-gcc
@@ -192,7 +264,7 @@ endif
AR = ar
ifeq ($(PLATFORM),PLATFORM_RPI)
- ifeq ($(RPI_CROSS_COMPILE),YES)
+ ifeq ($(USE_RPI_CROSS_COMPILER),TRUE)
# Define RPI cross-archiver
#CC = armv6j-hardfloat-linux-gnueabi-gcc
AR = $(RPI_TOOLCHAIN)/bin/arm-linux-gnueabihf-ar
@@ -210,19 +282,31 @@ ifeq ($(PLATFORM),PLATFORM_ANDROID)
endif
# Define compiler flags:
-# -O1 defines optimization level
-# -Og enable debugging
-# -s strip unnecessary data from build
-# -Wall turns on most, but not all, compiler warnings
-# -std=c99 defines C language mode (standard C from 1999 revision)
-# -std=gnu99 defines C language mode (GNU C from 1999 revision)
-# -fgnu89-inline declaring inline functions support (GCC optimized)
-# -Wno-missing-braces ignore invalid warning (GCC bug 53119)
-# -D_DEFAULT_SOURCE use with -std=c99
-CFLAGS += -O1 -Wall -std=c99 -D_DEFAULT_SOURCE -fgnu89-inline -Wno-missing-braces
+# -O1 defines optimization level
+# -g enable debugging
+# -s strip unnecessary data from build
+# -Wall turns on most, but not all, compiler warnings
+# -std=c99 defines C language mode (standard C from 1999 revision)
+# -std=gnu99 defines C language mode (GNU C from 1999 revision)
+# -Wno-missing-braces ignore invalid warning (GCC bug 53119)
+# -D_DEFAULT_SOURCE use with -std=c99 on Linux and PLATFORM_WEB, required for timespec
+# -Werror=pointer-arith catch unportable code that does direct arithmetic on void pointers
+# -fno-strict-aliasing jar_xm.h does shady stuff (breaks strict aliasing)
+CFLAGS += -O1 -Wall -std=c99 -D_DEFAULT_SOURCE -Wno-missing-braces -Werror=pointer-arith -fno-strict-aliasing
+
+ifeq ($(RAYLIB_BUILD_MODE), DEBUG)
+ CFLAGS += -g
+ #CC = clang
+endif
# Additional flags for compiler (if desired)
-#CFLAGS += -Wextra -Wmissing-prototypes -Wstrict-prototypes
+# -Wextra enables some extra warning flags that are not enabled by -Wall
+# -Wmissing-prototypes warn if a global function is defined without a previous prototype declaration
+# -Wstrict-prototypes warn if a function is declared or defined without specifying the argument types
+# -Werror=implicit-function-declaration catch function calls without prior declaration
+ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ CFLAGS += -Werror=implicit-function-declaration
+endif
ifeq ($(PLATFORM),PLATFORM_WEB)
# -O2 # if used, also set --memory-init-file 0
# --memory-init-file 0 # to avoid an external memory initialization code file (.mem)
@@ -237,7 +321,8 @@ ifeq ($(PLATFORM),PLATFORM_ANDROID)
# Compilation functions attributes options
CFLAGS += -ffunction-sections -funwind-tables -fstack-protector-strong -fPIC
# Compiler options for the linker
- CFLAGS += -Wa,--noexecstack -Wformat -Werror=format-security -no-canonical-prefixes
+ # -Werror=format-security
+ CFLAGS += -Wa,--noexecstack -Wformat -no-canonical-prefixes
# Preprocessor macro definitions
CFLAGS += -DANDROID -DPLATFORM_ANDROID -D__ANDROID_API__=16
endif
@@ -245,23 +330,44 @@ endif
# Define required compilation flags for raylib SHARED lib
ifeq ($(RAYLIB_LIBTYPE),SHARED)
# make sure code is compiled as position independent
- # BE CAREFUL: It seems that for gcc -fpic si not the same as -fPIC
+ # BE CAREFUL: It seems that for gcc -fpic is not the same as -fPIC
# MinGW32 just doesn't need -fPIC, it shows warnings
CFLAGS += -fPIC -DBUILD_LIBTYPE_SHARED
endif
-# Define required compilation flags for OpenAL Soft STATIC lib
-ifeq ($(OPENAL_LIBTYPE),STATIC)
- ALFLAGS = -DAL_LIBTYPE_STATIC -Wl,-allow-multiple-definition
+# Use OpenAL Soft backend instead of mini_al
+ifeq ($(USE_OPENAL_BACKEND),TRUE)
+ CFLAGS += -DUSE_OPENAL_BACKEND
+endif
+
+# Use Wayland display on Linux desktop
+ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ ifeq ($(PLATFORM_OS), LINUX)
+ ifeq ($(USE_WAYLAND_DISPLAY),TRUE)
+ CFLAGS += -D_GLFW_WAYLAND
+ endif
+ endif
endif
# Define include paths for required headers
# NOTE: Several external required libraries (stb and others)
-INCLUDE_PATHS = -I. -Iexternal -Iexternal/include
+INCLUDE_PATHS = -I. -Iexternal -Iexternal/glfw/include
+
+ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ INCLUDE_PATHS += -I/usr/local/include
+ LDFLAGS += -L. -Lsrc -L/usr/local/lib -L$(RAYLIB_RELEASE_PATH)
+ endif
+ ifeq ($(USE_EXTERNAL_GLFW),TRUE)
+ # Check the version name. If GLFW3 was built manually, it may have produced
+ # a static library known as libglfw3.a. In that case, the name should be -lglfw3
+ LDFLAGS += -lglfw
+ endif
+endif
# Define additional directories containing required header files
ifeq ($(PLATFORM),PLATFORM_RPI)
- # RPI requried libraries
+ # RPI required libraries
INCLUDE_PATHS += -I$(RPI_TOOLCHAIN_SYSROOT)/opt/vc/include
INCLUDE_PATHS += -I$(RPI_TOOLCHAIN_SYSROOT)/opt/vc/include/interface/vmcs_host/linux
INCLUDE_PATHS += -I$(RPI_TOOLCHAIN_SYSROOT)/opt/vc/include/interface/vcos/pthreads
@@ -277,21 +383,44 @@ endif
# Define linker options
ifeq ($(PLATFORM),PLATFORM_ANDROID)
- LDFLAGS = -Wl,-soname,libraylib.so -Wl,--exclude-libs,libatomic.a
- LDFLAGS += -Wl,--build-id -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel -Wl,--fatal-warnings
+ LDFLAGS = -Wl,-soname,libraylib.$(API_VERSION).so -Wl,--exclude-libs,libatomic.a
+ LDFLAGS += -Wl,--build-id -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel -Wl,--fatal-warnings
# Force linking of library module to define symbol
LDFLAGS += -u ANativeActivity_onCreate
# Library paths containing required libs
LDFLAGS += -L. -Lsrc -L$(RAYLIB_RELEASE_PATH)
- LDLIBS = -lopenal -llog -landroid -lEGL -lGLESv2 -lOpenSLES -latomic -lc -lm
+ LDLIBS = -llog -landroid -lEGL -lGLESv2 -lOpenSLES -latomic -lc -lm
endif
# Define all object files required with a wildcard
# The wildcard takes all files that finish with ".c",
# and replaces extentions with ".o", that are the object files
-OBJS = $(patsubst %.c, %.o, $(wildcard *.c))
-OBJS += stb_vorbis.o
+# NOTE: Some objects depend on the PLATFORM to be added or not!
+# OBJS = $(patsubst %.c, %.o, $(wildcard *.c))
+
+# Define object required on compilation
+OBJS = core.o \
+ rlgl.o \
+ shapes.o \
+ textures.o \
+ text.o \
+ models.o \
+ utils.o
+
+ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ ifeq ($(USE_EXTERNAL_GLFW),FALSE)
+ OBJS += rglfw.o
+ endif
+endif
+
+ifeq ($(INCLUDE_AUDIO_MODULE),TRUE)
+ OBJS += audio.o
+ OBJS += stb_vorbis.o
+ ifeq ($(USE_OPENAL_BACKEND),FALSE)
+ OBJS += mini_al.o
+ endif
+endif
# Default target entry
all: raylib
@@ -316,37 +445,43 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
@echo "raylib library generated (libraylib.bc)!"
else
ifeq ($(RAYLIB_LIBTYPE),SHARED)
- # NOTE: If using OpenAL Soft as static library, all its dependencies must be also linked in the shared library
ifeq ($(PLATFORM_OS),WINDOWS)
- $(CC) -shared -o $(RAYLIB_RELEASE_PATH)/raylib.dll $(OBJS) -L$(RAYLIB_RELEASE_PATH) -lglfw3 -lgdi32 -lopenal32 -lwinmm -Wl,--out-implib,$(RAYLIB_RELEASE_PATH)/libraylibdll.a
+ $(CC) -shared -o $(RAYLIB_RELEASE_PATH)/raylib.dll $(OBJS) -L$(RAYLIB_RELEASE_PATH) -static-libgcc -lopengl32 -lgdi32 -Wl,--out-implib,$(RAYLIB_RELEASE_PATH)/libraylibdll.a
@echo "raylib dynamic library (raylib.dll) and import library (libraylibdll.a) generated!"
- @echo "expected OpenAL Soft static library linking"
endif
ifeq ($(PLATFORM_OS),LINUX)
- # Compile raylib to shared library version for GNU/Linux.
+ # Compile raylib shared library version $(RAYLIB_VERSION).
# WARNING: you should type "make clean" before doing this target
- $(CC) -shared -o $(RAYLIB_RELEASE_PATH)/libraylib.so $(OBJS) -lglfw -lGL -lopenal -lm -lpthread -ldl
- @echo "raylib shared library generated (libraylib.so)!"
+ $(CC) -shared -o $(RAYLIB_RELEASE_PATH)/libraylib.so.$(RAYLIB_VERSION) $(OBJS) -shared -Wl,-soname,libraylib.so.$(RAYLIB_API_VERSION) -lGL -lc -lm -lpthread -ldl -lrt
+ @echo "raylib shared library generated (libraylib.so.$(RAYLIB_VERSION)) in $(RAYLIB_RELEASE_PATH)!"
+ cd $(RAYLIB_RELEASE_PATH) && ln -fsv libraylib.so.$(RAYLIB_VERSION) libraylib.so.$(RAYLIB_API_VERSION)
+ cd $(RAYLIB_RELEASE_PATH) && ln -fsv libraylib.so.$(RAYLIB_API_VERSION) libraylib.so
endif
ifeq ($(PLATFORM_OS),OSX)
- $(CC) -dynamiclib -o $(RAYLIB_RELEASE_PATH)/libraylib.dylib $(OBJS) -L/usr/local/Cellar/glfw/3.2.1/lib -lglfw -framework OpenGL -framework OpenAL -framework Cocoa
- install_name_tool -id "libraylib.dylib" $(RAYLIB_RELEASE_PATH)/libraylib.dylib
- @echo "raylib shared library generated (libraylib.dylib)!"
+ $(CC) -dynamiclib -o $(RAYLIB_RELEASE_PATH)/libraylib.$(RAYLIB_VERSION).dylib $(OBJS) -compatibility_version $(RAYLIB_API_VERSION) -current_version $(RAYLIB_VERSION) -framework OpenGL -framework OpenAL -framework IOKit -framework CoreVideo -framework Cocoa
+ install_name_tool -id "libraylib.$(VERSION).dylib" $(RAYLIB_RELEASE_PATH)/libraylib.$(RAYLIB_VERSION).dylib
+ @echo "raylib shared library generated (libraylib.$(RAYLIB_VERSION).dylib)!"
+ cd $(RAYLIB_RELEASE_PATH) && ln -fs libraylib.$(RAYLIB_VERSION).dylib libraylib.$(RAYLIB_API_VERSION).dylib
+ cd $(RAYLIB_RELEASE_PATH) && ln -fs libraylib.$(RAYLIB_VERSION).dylib libraylib.dylib
+ endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ # WARNING: you should type "gmake clean" before doing this target
+ $(CC) -shared -o $(RAYLIB_RELEASE_PATH)/libraylib.$(RAYLIB_VERSION).so $(OBJS) -Wl,-soname,libraylib.$(RAYLIB_API_VERSION).so -lGL -lpthread
+ @echo "raylib shared library generated (libraylib.$(RAYLIB_VERSION).so)!"
+ cd $(RAYLIB_RELEASE_PATH) && ln -fs libraylib.$(RAYLIB_VERSION).so libraylib.$(RAYLIB_API_VERSION).so
+ cd $(RAYLIB_RELEASE_PATH) && ln -fs libraylib.$(RAYLIB_VERSION).so libraylib.so
endif
ifeq ($(PLATFORM),PLATFORM_ANDROID)
- $(CC) -shared -o $(RAYLIB_RELEASE_PATH)/libraylib.so $(OBJS) $(LDFLAGS) $(LDLIBS)
- @echo "raylib shared library generated (libraylib.so)!"
+ $(CC) -shared -o $(RAYLIB_RELEASE_PATH)/libraylib.$(RAYLIB_VERSION).so $(OBJS) $(LDFLAGS) $(LDLIBS)
+ @echo "raylib shared library generated (libraylib.$(RAYLIB_VERSION).so)!"
+ cd $(RAYLIB_RELEASE_PATH) && ln -fs libraylib.$(RAYLIB_VERSION).so libraylib.$(RAYLIB_API_VERSION).so
+ cd $(RAYLIB_RELEASE_PATH) && ln -fs libraylib.$(RAYLIB_VERSION).so libraylib.so
endif
else
- # Compile raylib static library
- @echo raylib library release path is $(RAYLIB_RELEASE_PATH)
+ # Compile raylib static library version $(RAYLIB_VERSION)
+ # WARNING: You should type "make clean" before doing this target.
$(AR) rcs $(RAYLIB_RELEASE_PATH)/libraylib.a $(OBJS)
- @echo "raylib static library generated (libraylib.a)!"
- ifeq ($(OPENAL_LIBTYPE),STATIC)
- @echo "expected OpenAL Soft static library linking"
- else
- @echo "expected OpenAL Soft shared library linking"
- endif
+ @echo "raylib static library generated (libraylib.a) in $(RAYLIB_RELEASE_PATH)!"
endif
endif
@@ -356,6 +491,10 @@ endif
core.o : core.c raylib.h rlgl.h utils.h raymath.h gestures.h
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM) -D$(GRAPHICS)
+# Compile rglfw module
+rglfw.o : rglfw.c
+ $(CC) $(GLFW_CFLAGS) -c $< $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM) -D$(GRAPHICS)
+
# Compile rlgl module
rlgl.o : rlgl.c rlgl.h raymath.h
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM) -D$(GRAPHICS)
@@ -378,7 +517,11 @@ models.o : models.c raylib.h rlgl.h raymath.h
# Compile audio module
audio.o : audio.c raylib.h
- $(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM) $(ALFLAGS)
+ $(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM)
+
+# Compile mini_al audio library
+mini_al.o : external/mini_al.c external/mini_al.h
+ $(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM)
# Compile stb_vorbis library
stb_vorbis.o: external/stb_vorbis.c external/stb_vorbis.h
@@ -388,46 +531,85 @@ stb_vorbis.o: external/stb_vorbis.c external/stb_vorbis.h
utils.o : utils.c utils.h
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM)
-# Install generated and needed files to required directories
-# TODO: add other platforms.
+# Install generated and needed files to desired directories.
+# On GNU/Linux and BSDs, there are some standard directories that contain extra
+# libraries and header files. These directories (often /usr/local/lib and
+# /usr/local/include) are for libraries that are installed manually
+# (without a package manager). We'll use /usr/local/lib/raysan5 and /usr/local/include/raysan5
+# for our -L and -I specification to simplify management of the raylib source package.
+# Customize these locations if you like but don't forget to pass them to make
+# for compilation and enable runtime linking with -rpath, LD_LIBRARY_PATH, or ldconfig.
+# Hint: add -L$(RAYLIB_INSTALL_PATH) -I$(RAYLIB_H_INSTALL_PATH) to your own makefiles.
+# See below and ../examples/Makefile for more information.
+# TODO: Add other platforms. Remove sudo requirement, i.e. add USER mode.
+
+# RAYLIB_INSTALL_PATH should be the desired full path to libraylib. No relative paths.
+DESTDIR ?= /usr/local
+RAYLIB_INSTALL_PATH ?= $(DESTDIR)/lib
+# RAYLIB_H_INSTALL_PATH locates the installed raylib header and associated source files.
+RAYLIB_H_INSTALL_PATH ?= $(DESTDIR)/include
+
install :
ifeq ($(ROOT),root)
ifeq ($(PLATFORM_OS),LINUX)
- # On GNU/Linux there are some standard directories that contain
- # libraries and header files. These directory (/usr/local/lib and
- # /usr/local/include/) are for libraries that are installed
- # manually (without a package manager).
+ # Attention! You are root, writing files to $(RAYLIB_INSTALL_PATH)
+ # and $(RAYLIB_H_INSTALL_PATH). Consult this Makefile for more information.
+ # Prepare the environment as needed.
+ mkdir --parents --verbose $(RAYLIB_INSTALL_PATH)
+ mkdir --parents --verbose $(RAYLIB_H_INSTALL_PATH)
ifeq ($(RAYLIB_LIBTYPE),SHARED)
- cp --update $(RAYLIB_RELEASE_PATH)/libraylib.so /usr/local/lib/libraylib.so
+ # Installing raylib to $(RAYLIB_INSTALL_PATH).
+ cp --update --verbose $(RAYLIB_RELEASE_PATH)/libraylib.so.$(RAYLIB_VERSION) $(RAYLIB_INSTALL_PATH)/libraylib.so.$(RAYLIB_VERSION)
+ cd $(RAYLIB_INSTALL_PATH); ln -fsv libraylib.so.$(RAYLIB_VERSION) libraylib.so.$(RAYLIB_API_VERSION)
+ cd $(RAYLIB_INSTALL_PATH); ln -fsv libraylib.so.$(RAYLIB_API_VERSION) libraylib.so
+ # Uncomment to update the runtime linker cache with RAYLIB_INSTALL_PATH.
+ # Not necessary if later embedding RPATH in your executable. See examples/Makefile.
+ ldconfig $(RAYLIB_INSTALL_PATH)
else
- cp --update raylib.h /usr/local/include/raylib.h
- cp --update $(RAYLIB_RELEASE_PATH)/libraylib.a /usr/local/lib/libraylib.a
+ # Installing raylib to $(RAYLIB_INSTALL_PATH).
+ cp --update --verbose $(RAYLIB_RELEASE_PATH)/libraylib.a $(RAYLIB_INSTALL_PATH)/libraylib.a
endif
- @echo "raylib dev files installed/updated!"
+ # Copying raylib development files to $(RAYLIB_H_INSTALL_PATH).
+ cp --update raylib.h $(RAYLIB_H_INSTALL_PATH)/raylib.h
+ cp --update raymath.h $(RAYLIB_H_INSTALL_PATH)/raymath.h
+ cp --update rlgl.h $(RAYLIB_H_INSTALL_PATH)/rlgl.h
+ cp --update rlgl.c $(RAYLIB_H_INSTALL_PATH)/rlgl.c
+ cp --update physac.h $(RAYLIB_H_INSTALL_PATH)/physac.h
+ @echo "raylib development files installed/updated!"
else
- @echo "This function works only on GNU/Linux systems"
+ @echo "This function currently works on GNU/Linux systems. Add yours today (^;"
endif
else
- @echo "Error: no root permissions"
+ @echo "Error: Root permissions needed for installation. Try sudo make install"
endif
# Remove raylib dev files installed on the system
# TODO: see 'install' target.
uninstall :
ifeq ($(ROOT),root)
+ # WARNING: You are root, about to delete items from $(RAYLIB_INSTALL_PATH).
+ # and $(RAYLIB_H_INSTALL_PATH). Please confirm each item.
ifeq ($(PLATFORM_OS),LINUX)
- rm --force /usr/local/include/raylib.h
ifeq ($(RAYLIB_LIBTYPE),SHARED)
- rm --force /usr/local/lib/libraylib.so
+ rm --force --interactive --verbose $(RAYLIB_INSTALL_PATH)/libraylib.so
+ rm --force --interactive --verbose $(RAYLIB_INSTALL_PATH)/libraylib.so.$(RAYLIB_API_VERSION)
+ rm --force --interactive --verbose $(RAYLIB_INSTALL_PATH)/libraylib.so.$(RAYLIB_VERSION)
+ # Uncomment to clean up the runtime linker cache. See install target.
+ ldconfig
else
- rm --force /usr/local/lib/libraylib.a
+ rm --force --interactive --verbose $(RAYLIB_INSTALL_PATH)/libraylib.a
endif
+ rm --force --interactive --verbose $(RAYLIB_H_INSTALL_PATH)/raylib.h
+ rm --force --interactive --verbose $(RAYLIB_H_INSTALL_PATH)/raymath.h
+ rm --force --interactive --verbose $(RAYLIB_H_INSTALL_PATH)/rlgl.h
+ rm --force --interactive --verbose $(RAYLIB_H_INSTALL_PATH)/rlgl.c
+ rm --force --interactive --verbose $(RAYLIB_H_INSTALL_PATH)/physac.h
@echo "raylib development files removed!"
- else
- @echo "This function works only on GNU/Linux systems"
+ else
+ @echo "This function currently works on GNU/Linux systems. Add yours today (^;"
endif
else
- @echo "Error: no root permissions"
+ @echo "Error: Root permissions needed for uninstallation. Try sudo make uninstall"
endif
# Clean everything
@@ -435,7 +617,7 @@ clean:
ifeq ($(PLATFORM_OS),WINDOWS)
del *.o $(RAYLIB_RELEASE_PATH)/libraylib.a $(RAYLIB_RELEASE_PATH)/libraylib.bc $(RAYLIB_RELEASE_PATH)/libraylib.so external/stb_vorbis.o
else
- rm -f *.o $(RAYLIB_RELEASE_PATH)/libraylib.a $(RAYLIB_RELEASE_PATH)/libraylib.bc $(RAYLIB_RELEASE_PATH)/libraylib.so external/stb_vorbis.o
+ rm -fv *.o $(RAYLIB_RELEASE_PATH)/libraylib.a $(RAYLIB_RELEASE_PATH)/libraylib.bc $(RAYLIB_RELEASE_PATH)/libraylib.so* external/stb_vorbis.o
endif
ifeq ($(PLATFORM),PLATFORM_ANDROID)
rm -rf $(ANDROID_TOOLCHAIN)
diff --git a/src/audio.c b/src/audio.c
index d397b064b..3ee1fe81f 100644
--- a/src/audio.c
+++ b/src/audio.c
@@ -11,32 +11,40 @@
* - Manage raw audio context
*
* CONFIGURATION:
-*
+*
* #define AUDIO_STANDALONE
* Define to use the module as standalone library (independently of raylib).
* Required types and functions are defined in the same module.
*
+* #define USE_OPENAL_BACKEND
+* Use OpenAL Soft audio backend usage
+*
* #define SUPPORT_FILEFORMAT_WAV
* #define SUPPORT_FILEFORMAT_OGG
* #define SUPPORT_FILEFORMAT_XM
* #define SUPPORT_FILEFORMAT_MOD
* #define SUPPORT_FILEFORMAT_FLAC
-* Selected desired fileformats to be supported for loading. Some of those formats are
+* Selected desired fileformats to be supported for loading. Some of those formats are
* supported by default, to remove support, just comment unrequired #define in this module
*
-* LIMITATIONS:
+* LIMITATIONS (only OpenAL Soft):
* Only up to two channels supported: MONO and STEREO (for additional channels, use AL_EXT_MCFORMATS)
* Only the following sample sizes supported: 8bit PCM, 16bit PCM, 32-bit float PCM (using AL_EXT_FLOAT32)
*
* DEPENDENCIES:
-* OpenAL Soft - Audio device management (http://kcat.strangesoft.net/openal.html)
+* mini_al - Audio device/context management (https://github.com/dr-soft/mini_al)
* stb_vorbis - OGG audio files loading (http://www.nothings.org/stb_vorbis/)
* jar_xm - XM module file loading
* jar_mod - MOD audio file loading
* dr_flac - FLAC audio file loading
*
+* *OpenAL Soft - Audio device management, still used on HTML5 and OSX platforms
+*
* CONTRIBUTORS:
-* Joshua Reisenauer (github: @kd7tck):
+* David Reid (github: @mackron) (Nov. 2017):
+* - Complete port to mini_al library
+*
+* Joshua Reisenauer (github: @kd7tck) (2015)
* - XM audio module support (jar_xm)
* - MOD audio module support (jar_mod)
* - Mixing channels support
@@ -45,7 +53,7 @@
*
* LICENSE: zlib/libpng
*
-* Copyright (c) 2014-2017 Ramon Santamaria (@raysan5)
+* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
@@ -64,16 +72,10 @@
*
**********************************************************************************************/
-// Default configuration flags (supported features)
-//-------------------------------------------------
-#define SUPPORT_FILEFORMAT_WAV
-#define SUPPORT_FILEFORMAT_OGG
-#define SUPPORT_FILEFORMAT_XM
-#define SUPPORT_FILEFORMAT_MOD
-//-------------------------------------------------
+#include "config.h"
-#ifndef USE_MINI_AL
-#define USE_MINI_AL 1 // Set to 1 to use mini_al; 0 to use OpenAL.
+#if !defined(USE_OPENAL_BACKEND)
+ #define USE_MINI_AL 1 // Set to 1 to use mini_al; 0 to use OpenAL.
#endif
#if defined(AUDIO_STANDALONE)
@@ -86,7 +88,7 @@
#include "external/mini_al.h" // Implemented in mini_al.c. Cannot implement this here because it conflicts with Win32 APIs such as CloseWindow(), etc.
-#if !defined(USE_MINI_AL) || USE_MINI_AL == 0
+#if !defined(USE_MINI_AL) || (USE_MINI_AL == 0)
#if defined(__APPLE__)
#include "OpenAL/al.h" // OpenAL basic header
#include "OpenAL/alc.h" // OpenAL context header (like OpenGL, OpenAL requires a context to work)
@@ -153,7 +155,12 @@
// Types and Structures Definition
//----------------------------------------------------------------------------------
-typedef enum { MUSIC_AUDIO_OGG = 0, MUSIC_AUDIO_FLAC, MUSIC_MODULE_XM, MUSIC_MODULE_MOD } MusicContextType;
+typedef enum {
+ MUSIC_AUDIO_OGG = 0,
+ MUSIC_AUDIO_FLAC,
+ MUSIC_MODULE_XM,
+ MUSIC_MODULE_MOD
+} MusicContextType;
// Music type (file streaming from memory)
typedef struct MusicData {
@@ -179,7 +186,13 @@ typedef struct MusicData {
} MusicData;
#if defined(AUDIO_STANDALONE)
-typedef enum { LOG_INFO = 0, LOG_ERROR, LOG_WARNING, LOG_DEBUG, LOG_OTHER } TraceLogType;
+typedef enum {
+ LOG_INFO = 0,
+ LOG_ERROR,
+ LOG_WARNING,
+ LOG_DEBUG,
+ LOG_OTHER
+} TraceLogType;
#endif
//----------------------------------------------------------------------------------
@@ -206,105 +219,78 @@ void TraceLog(int msgType, const char *text, ...); // Show trace lo
#endif
//----------------------------------------------------------------------------------
-// Module Functions Definition - Audio Device initialization and Closing
+// mini_al AudioBuffer Functionality
//----------------------------------------------------------------------------------
#if USE_MINI_AL
+
#define DEVICE_FORMAT mal_format_f32
#define DEVICE_CHANNELS 2
#define DEVICE_SAMPLE_RATE 44100
typedef enum { AUDIO_BUFFER_USAGE_STATIC = 0, AUDIO_BUFFER_USAGE_STREAM } AudioBufferUsage;
+// Audio buffer structure
+// NOTE: Slightly different logic is used when feeding data to the playback device depending on whether or not data is streamed
typedef struct AudioBuffer AudioBuffer;
-struct AudioBuffer
-{
- mal_dsp dsp; // For format conversion.
+struct AudioBuffer {
+ mal_dsp dsp; // Required for format conversion
float volume;
float pitch;
bool playing;
bool paused;
- bool looping; // Always true for AudioStreams.
- AudioBufferUsage usage; // Slightly different logic is used when feeding data to the playback device depending on whether or not data is streamed.
+ bool looping; // Always true for AudioStreams
+ int usage; // AudioBufferUsage type
bool isSubBufferProcessed[2];
unsigned int frameCursorPos;
unsigned int bufferSizeInFrames;
- AudioBuffer* next;
- AudioBuffer* prev;
+ AudioBuffer *next;
+ AudioBuffer *prev;
unsigned char buffer[1];
};
-void StopAudioBuffer(AudioBuffer* audioBuffer);
-
-
+// mini_al global variables
static mal_context context;
static mal_device device;
-static mal_bool32 isAudioInitialized = MAL_FALSE;
-static float masterVolume = 1;
static mal_mutex audioLock;
-static AudioBuffer* firstAudioBuffer = NULL; // Audio buffers are tracked in a linked list.
-static AudioBuffer* lastAudioBuffer = NULL;
+static bool isAudioInitialized = MAL_FALSE;
+static float masterVolume = 1.0f;
-static void TrackAudioBuffer(AudioBuffer* audioBuffer)
-{
- mal_mutex_lock(&audioLock);
- {
- if (firstAudioBuffer == NULL) {
- firstAudioBuffer = audioBuffer;
- } else {
- lastAudioBuffer->next = audioBuffer;
- audioBuffer->prev = lastAudioBuffer;
- }
+// Audio buffers are tracked in a linked list
+static AudioBuffer *firstAudioBuffer = NULL;
+static AudioBuffer *lastAudioBuffer = NULL;
- lastAudioBuffer = audioBuffer;
- }
- mal_mutex_unlock(&audioLock);
-}
+// mini_al functions declaration
+static void OnLog(mal_context *pContext, mal_device *pDevice, const char *message);
+static mal_uint32 OnSendAudioDataToDevice(mal_device *pDevice, mal_uint32 frameCount, void *pFramesOut);
+static mal_uint32 OnAudioBufferDSPRead(mal_dsp *pDSP, mal_uint32 frameCount, void *pFramesOut, void *pUserData);
+static void MixAudioFrames(float *framesOut, const float *framesIn, mal_uint32 frameCount, float localVolume);
-static void UntrackAudioBuffer(AudioBuffer* audioBuffer)
-{
- mal_mutex_lock(&audioLock);
- {
- if (audioBuffer->prev == NULL) {
- firstAudioBuffer = audioBuffer->next;
- } else {
- audioBuffer->prev->next = audioBuffer->next;
- }
+// AudioBuffer management functions declaration
+// NOTE: Those functions are not exposed by raylib... for the moment
+AudioBuffer *CreateAudioBuffer(mal_format format, mal_uint32 channels, mal_uint32 sampleRate, mal_uint32 bufferSizeInFrames, AudioBufferUsage usage);
+void DeleteAudioBuffer(AudioBuffer *audioBuffer);
+bool IsAudioBufferPlaying(AudioBuffer *audioBuffer);
+void PlayAudioBuffer(AudioBuffer *audioBuffer);
+void StopAudioBuffer(AudioBuffer *audioBuffer);
+void PauseAudioBuffer(AudioBuffer *audioBuffer);
+void ResumeAudioBuffer(AudioBuffer *audioBuffer);
+void SetAudioBufferVolume(AudioBuffer *audioBuffer, float volume);
+void SetAudioBufferPitch(AudioBuffer *audioBuffer, float pitch);
+void TrackAudioBuffer(AudioBuffer *audioBuffer);
+void UntrackAudioBuffer(AudioBuffer *audioBuffer);
- if (audioBuffer->next == NULL) {
- lastAudioBuffer = audioBuffer->prev;
- } else {
- audioBuffer->next->prev = audioBuffer->prev;
- }
- audioBuffer->prev = NULL;
- audioBuffer->next = NULL;
- }
- mal_mutex_unlock(&audioLock);
-}
-
-static void OnLog_MAL(mal_context* pContext, mal_device* pDevice, const char* message)
+// Log callback function
+static void OnLog(mal_context *pContext, mal_device *pDevice, const char *message)
{
(void)pContext;
(void)pDevice;
- TraceLog(LOG_ERROR, message); // All log messages from mini_al are errors.
+
+ TraceLog(LOG_ERROR, message); // All log messages from mini_al are errors
}
-// This is the main mixing function. Mixing is pretty simple in this project - it's just an accumulation.
-//
-// framesOut is both an input and an output. It will be initially filled with zeros outside of this function.
-static void MixFrames(float* framesOut, const float* framesIn, mal_uint32 frameCount, float localVolume)
-{
- for (mal_uint32 iFrame = 0; iFrame < frameCount; ++iFrame) {
- for (mal_uint32 iChannel = 0; iChannel < device.channels; ++iChannel) {
- float* frameOut = framesOut + (iFrame * device.channels);
- const float* frameIn = framesIn + (iFrame * device.channels);
-
- frameOut[iChannel] += frameIn[iChannel] * masterVolume * localVolume;
- }
- }
-}
-
-static mal_uint32 OnSendAudioDataToDevice(mal_device* pDevice, mal_uint32 frameCount, void* pFramesOut)
+// Sending audio data to device callback function
+static mal_uint32 OnSendAudioDataToDevice(mal_device *pDevice, mal_uint32 frameCount, void *pFramesOut)
{
// This is where all of the mixing takes place.
(void)pDevice;
@@ -316,80 +302,194 @@ static mal_uint32 OnSendAudioDataToDevice(mal_device* pDevice, mal_uint32 frameC
// want to consider how you might want to avoid this.
mal_mutex_lock(&audioLock);
{
- for (AudioBuffer* audioBuffer = firstAudioBuffer; audioBuffer != NULL; audioBuffer = audioBuffer->next)
+ for (AudioBuffer *audioBuffer = firstAudioBuffer; audioBuffer != NULL; audioBuffer = audioBuffer->next)
{
// Ignore stopped or paused sounds.
- if (!audioBuffer->playing || audioBuffer->paused) {
- continue;
- }
+ if (!audioBuffer->playing || audioBuffer->paused) continue;
mal_uint32 framesRead = 0;
- for (;;) {
- if (framesRead > frameCount) {
+ for (;;)
+ {
+ if (framesRead > frameCount)
+ {
TraceLog(LOG_DEBUG, "Mixed too many frames from audio buffer");
break;
}
- if (framesRead == frameCount) {
- break;
- }
+
+ if (framesRead == frameCount) break;
// Just read as much data as we can from the stream.
mal_uint32 framesToRead = (frameCount - framesRead);
- while (framesToRead > 0) {
+ while (framesToRead > 0)
+ {
float tempBuffer[1024]; // 512 frames for stereo.
mal_uint32 framesToReadRightNow = framesToRead;
- if (framesToReadRightNow > sizeof(tempBuffer)/sizeof(tempBuffer[0])/DEVICE_CHANNELS) {
+ if (framesToReadRightNow > sizeof(tempBuffer)/sizeof(tempBuffer[0])/DEVICE_CHANNELS)
+ {
framesToReadRightNow = sizeof(tempBuffer)/sizeof(tempBuffer[0])/DEVICE_CHANNELS;
}
// If we're not looping, we need to make sure we flush the internal buffers of the DSP pipeline to ensure we get the
// last few samples.
- mal_bool32 flushDSP = !audioBuffer->looping;
+ bool flushDSP = !audioBuffer->looping;
mal_uint32 framesJustRead = mal_dsp_read_frames_ex(&audioBuffer->dsp, framesToReadRightNow, tempBuffer, flushDSP);
- if (framesJustRead > 0) {
- float* framesOut = (float*)pFramesOut + (framesRead * device.channels);
- float* framesIn = tempBuffer;
- MixFrames(framesOut, framesIn, framesJustRead, audioBuffer->volume);
+ if (framesJustRead > 0)
+ {
+ float *framesOut = (float *)pFramesOut + (framesRead*device.channels);
+ float *framesIn = tempBuffer;
+ MixAudioFrames(framesOut, framesIn, framesJustRead, audioBuffer->volume);
framesToRead -= framesJustRead;
framesRead += framesJustRead;
}
// If we weren't able to read all the frames we requested, break.
- if (framesJustRead < framesToReadRightNow) {
- if (!audioBuffer->looping) {
+ if (framesJustRead < framesToReadRightNow)
+ {
+ if (!audioBuffer->looping)
+ {
StopAudioBuffer(audioBuffer);
break;
- } else {
- // Should never get here, but just for safety, move the cursor position back to the start and continue the loop.
+ }
+ else
+ {
+ // Should never get here, but just for safety,
+ // move the cursor position back to the start and continue the loop.
audioBuffer->frameCursorPos = 0;
continue;
}
}
}
- // If for some reason we weren't able to read every frame we'll need to break from the loop. Not doing this could
- // theoretically put us into an infinite loop.
- if (framesToRead > 0) {
- break;
- }
+ // If for some reason we weren't able to read every frame we'll need to break from the loop.
+ // Not doing this could theoretically put us into an infinite loop.
+ if (framesToRead > 0) break;
}
}
}
+
mal_mutex_unlock(&audioLock);
return frameCount; // We always output the same number of frames that were originally requested.
}
+
+// DSP read from audio buffer callback function
+static mal_uint32 OnAudioBufferDSPRead(mal_dsp *pDSP, mal_uint32 frameCount, void *pFramesOut, void *pUserData)
+{
+ AudioBuffer *audioBuffer = (AudioBuffer *)pUserData;
+
+ mal_uint32 subBufferSizeInFrames = audioBuffer->bufferSizeInFrames/2;
+ mal_uint32 currentSubBufferIndex = audioBuffer->frameCursorPos/subBufferSizeInFrames;
+
+ if (currentSubBufferIndex > 1)
+ {
+ TraceLog(LOG_DEBUG, "Frame cursor position moved too far forward in audio stream");
+ return 0;
+ }
+
+ // Another thread can update the processed state of buffers so we just take a copy here to try and avoid potential synchronization problems.
+ bool isSubBufferProcessed[2];
+ isSubBufferProcessed[0] = audioBuffer->isSubBufferProcessed[0];
+ isSubBufferProcessed[1] = audioBuffer->isSubBufferProcessed[1];
+
+ mal_uint32 frameSizeInBytes = mal_get_sample_size_in_bytes(audioBuffer->dsp.config.formatIn)*audioBuffer->dsp.config.channelsIn;
+
+ // Fill out every frame until we find a buffer that's marked as processed. Then fill the remainder with 0.
+ mal_uint32 framesRead = 0;
+ for (;;)
+ {
+ // We break from this loop differently depending on the buffer's usage. For static buffers, we simply fill as much data as we can. For
+ // streaming buffers we only fill the halves of the buffer that are processed. Unprocessed halves must keep their audio data in-tact.
+ if (audioBuffer->usage == AUDIO_BUFFER_USAGE_STATIC)
+ {
+ if (framesRead >= frameCount) break;
+ }
+ else
+ {
+ if (isSubBufferProcessed[currentSubBufferIndex]) break;
+ }
+
+ mal_uint32 totalFramesRemaining = (frameCount - framesRead);
+ if (totalFramesRemaining == 0) break;
+
+ mal_uint32 framesRemainingInOutputBuffer;
+ if (audioBuffer->usage == AUDIO_BUFFER_USAGE_STATIC)
+ {
+ framesRemainingInOutputBuffer = audioBuffer->bufferSizeInFrames - audioBuffer->frameCursorPos;
+ }
+ else
+ {
+ mal_uint32 firstFrameIndexOfThisSubBuffer = subBufferSizeInFrames * currentSubBufferIndex;
+ framesRemainingInOutputBuffer = subBufferSizeInFrames - (audioBuffer->frameCursorPos - firstFrameIndexOfThisSubBuffer);
+ }
+
+ mal_uint32 framesToRead = totalFramesRemaining;
+ if (framesToRead > framesRemainingInOutputBuffer) framesToRead = framesRemainingInOutputBuffer;
+
+ memcpy((unsigned char *)pFramesOut + (framesRead*frameSizeInBytes), audioBuffer->buffer + (audioBuffer->frameCursorPos*frameSizeInBytes), framesToRead*frameSizeInBytes);
+ audioBuffer->frameCursorPos = (audioBuffer->frameCursorPos + framesToRead) % audioBuffer->bufferSizeInFrames;
+ framesRead += framesToRead;
+
+ // If we've read to the end of the buffer, mark it as processed.
+ if (framesToRead == framesRemainingInOutputBuffer)
+ {
+ audioBuffer->isSubBufferProcessed[currentSubBufferIndex] = true;
+ isSubBufferProcessed[currentSubBufferIndex] = true;
+
+ currentSubBufferIndex = (currentSubBufferIndex + 1)%2;
+
+ // We need to break from this loop if we're not looping.
+ if (!audioBuffer->looping)
+ {
+ StopAudioBuffer(audioBuffer);
+ break;
+ }
+ }
+ }
+
+ // Zero-fill excess.
+ mal_uint32 totalFramesRemaining = (frameCount - framesRead);
+ if (totalFramesRemaining > 0)
+ {
+ memset((unsigned char*)pFramesOut + (framesRead*frameSizeInBytes), 0, totalFramesRemaining*frameSizeInBytes);
+
+ // For static buffers we can fill the remaining frames with silence for safety, but we don't want
+ // to report those frames as "read". The reason for this is that the caller uses the return value
+ // to know whether or not a non-looping sound has finished playback.
+ if (audioBuffer->usage != AUDIO_BUFFER_USAGE_STATIC) framesRead += totalFramesRemaining;
+ }
+
+ return framesRead;
+}
+
+// This is the main mixing function. Mixing is pretty simple in this project - it's just an accumulation.
+// NOTE: framesOut is both an input and an output. It will be initially filled with zeros outside of this function.
+static void MixAudioFrames(float *framesOut, const float *framesIn, mal_uint32 frameCount, float localVolume)
+{
+ for (mal_uint32 iFrame = 0; iFrame < frameCount; ++iFrame)
+ {
+ for (mal_uint32 iChannel = 0; iChannel < device.channels; ++iChannel)
+ {
+ float *frameOut = framesOut + (iFrame*device.channels);
+ const float *frameIn = framesIn + (iFrame*device.channels);
+
+ frameOut[iChannel] += frameIn[iChannel]*masterVolume*localVolume;
+ }
+ }
+}
#endif
+//----------------------------------------------------------------------------------
+// Module Functions Definition - Audio Device initialization and Closing
+//----------------------------------------------------------------------------------
// Initialize audio device
void InitAudioDevice(void)
{
#if USE_MINI_AL
// Context.
- mal_context_config contextConfig = mal_context_config_init(OnLog_MAL);
+ mal_context_config contextConfig = mal_context_config_init(OnLog);
mal_result result = mal_context_init(NULL, 0, &contextConfig, &context);
if (result != MAL_SUCCESS)
{
@@ -400,12 +500,6 @@ void InitAudioDevice(void)
// Device. Using the default device. Format is floating point because it simplifies mixing.
mal_device_config deviceConfig = mal_device_config_init(DEVICE_FORMAT, DEVICE_CHANNELS, DEVICE_SAMPLE_RATE, NULL, OnSendAudioDataToDevice);
- // Special case for PLATFORM_RPI.
-//#if defined(PLATFORM_RPI)
-// deviceConfig.alsa.noMMap = MAL_TRUE;
-// deviceConfig.bufferSizeInFrames = 2048;
-//#endif
-
result = mal_device_init(&context, mal_device_type_playback, NULL, &deviceConfig, NULL, &device);
if (result != MAL_SUCCESS)
{
@@ -471,11 +565,8 @@ void InitAudioDevice(void)
alListenerf(AL_GAIN, 1.0f);
- if (alIsExtensionPresent("AL_EXT_float32")) {
- TraceLog(LOG_INFO, "AL_EXT_float32 supported");
- } else {
- TraceLog(LOG_INFO, "AL_EXT_float32 not supported");
- }
+ if (alIsExtensionPresent("AL_EXT_float32")) TraceLog(LOG_INFO, "[EXTENSION] AL_EXT_float32 supported");
+ else TraceLog(LOG_INFO, "[EXTENSION] AL_EXT_float32 not supported");
}
}
#endif
@@ -485,7 +576,8 @@ void InitAudioDevice(void)
void CloseAudioDevice(void)
{
#if USE_MINI_AL
- if (!isAudioInitialized) {
+ if (!isAudioInitialized)
+ {
TraceLog(LOG_WARNING, "Could not close audio device because it is not currently initialized");
return;
}
@@ -535,110 +627,20 @@ void SetMasterVolume(float volume)
else if (volume > 1.0f) volume = 1.0f;
#if USE_MINI_AL
- masterVolume = 1;
+ masterVolume = volume;
#else
alListenerf(AL_GAIN, volume);
#endif
}
-
//----------------------------------------------------------------------------------
-// Audio Buffer
+// Module Functions Definition - Audio Buffer management
//----------------------------------------------------------------------------------
#if USE_MINI_AL
-static mal_uint32 AudioBuffer_OnDSPRead(mal_dsp* pDSP, mal_uint32 frameCount, void* pFramesOut, void* pUserData)
+// Create a new audio buffer. Initially filled with silence
+AudioBuffer *CreateAudioBuffer(mal_format format, mal_uint32 channels, mal_uint32 sampleRate, mal_uint32 bufferSizeInFrames, AudioBufferUsage usage)
{
- AudioBuffer* audioBuffer = (AudioBuffer*)pUserData;
-
- mal_uint32 subBufferSizeInFrames = audioBuffer->bufferSizeInFrames / 2;
- mal_uint32 currentSubBufferIndex = audioBuffer->frameCursorPos / subBufferSizeInFrames;
- if (currentSubBufferIndex > 1) {
- TraceLog(LOG_DEBUG, "Frame cursor position moved too far forward in audio stream");
- return 0;
- }
-
- // Another thread can update the processed state of buffers so we just take a copy here to try and avoid potential synchronization problems.
- bool isSubBufferProcessed[2];
- isSubBufferProcessed[0] = audioBuffer->isSubBufferProcessed[0];
- isSubBufferProcessed[1] = audioBuffer->isSubBufferProcessed[1];
-
- mal_uint32 frameSizeInBytes = mal_get_sample_size_in_bytes(audioBuffer->dsp.config.formatIn) * audioBuffer->dsp.config.channelsIn;
-
- // Fill out every frame until we find a buffer that's marked as processed. Then fill the remainder with 0.
- mal_uint32 framesRead = 0;
- for (;;)
- {
- // We break from this loop differently depending on the buffer's usage. For static buffers, we simply fill as much data as we can. For
- // streaming buffers we only fill the halves of the buffer that are processed. Unprocessed halves must keep their audio data in-tact.
- if (audioBuffer->usage == AUDIO_BUFFER_USAGE_STATIC) {
- if (framesRead >= frameCount) {
- break;
- }
- } else {
- if (isSubBufferProcessed[currentSubBufferIndex]) {
- break;
- }
- }
-
- mal_uint32 totalFramesRemaining = (frameCount - framesRead);
- if (totalFramesRemaining == 0) {
- break;
- }
-
- mal_uint32 framesRemainingInOutputBuffer;
- if (audioBuffer->usage == AUDIO_BUFFER_USAGE_STATIC) {
- framesRemainingInOutputBuffer = audioBuffer->bufferSizeInFrames - audioBuffer->frameCursorPos;
- } else {
- mal_uint32 firstFrameIndexOfThisSubBuffer = subBufferSizeInFrames * currentSubBufferIndex;
- framesRemainingInOutputBuffer = subBufferSizeInFrames - (audioBuffer->frameCursorPos - firstFrameIndexOfThisSubBuffer);
- }
-
-
-
- mal_uint32 framesToRead = totalFramesRemaining;
- if (framesToRead > framesRemainingInOutputBuffer) {
- framesToRead = framesRemainingInOutputBuffer;
- }
-
- memcpy((unsigned char*)pFramesOut + (framesRead*frameSizeInBytes), audioBuffer->buffer + (audioBuffer->frameCursorPos*frameSizeInBytes), framesToRead*frameSizeInBytes);
- audioBuffer->frameCursorPos = (audioBuffer->frameCursorPos + framesToRead) % audioBuffer->bufferSizeInFrames;
- framesRead += framesToRead;
-
- // If we've read to the end of the buffer, mark it as processed.
- if (framesToRead == framesRemainingInOutputBuffer) {
- audioBuffer->isSubBufferProcessed[currentSubBufferIndex] = true;
- isSubBufferProcessed[currentSubBufferIndex] = true;
-
- currentSubBufferIndex = (currentSubBufferIndex + 1) % 2;
-
- // We need to break from this loop if we're not looping.
- if (!audioBuffer->looping) {
- StopAudioBuffer(audioBuffer);
- break;
- }
- }
- }
-
- // Zero-fill excess.
- mal_uint32 totalFramesRemaining = (frameCount - framesRead);
- if (totalFramesRemaining > 0) {
- memset((unsigned char*)pFramesOut + (framesRead*frameSizeInBytes), 0, totalFramesRemaining*frameSizeInBytes);
-
- // For static buffers we can fill the remaining frames with silence for safety, but we don't want
- // to report those frames as "read". The reason for this is that the caller uses the return value
- // to know whether or not a non-looping sound has finished playback.
- if (audioBuffer->usage != AUDIO_BUFFER_USAGE_STATIC) {
- framesRead += totalFramesRemaining;
- }
- }
-
- return framesRead;
-}
-
-// Create a new audio buffer. Initially filled with silence.
-AudioBuffer* CreateAudioBuffer(mal_format format, mal_uint32 channels, mal_uint32 sampleRate, mal_uint32 bufferSizeInFrames, AudioBufferUsage usage)
-{
- AudioBuffer* audioBuffer = (AudioBuffer*)calloc(sizeof(*audioBuffer) + (bufferSizeInFrames*channels*mal_get_sample_size_in_bytes(format)), 1);
+ AudioBuffer *audioBuffer = (AudioBuffer *)calloc(sizeof(*audioBuffer) + (bufferSizeInFrames*channels*mal_get_sample_size_in_bytes(format)), 1);
if (audioBuffer == NULL)
{
TraceLog(LOG_ERROR, "CreateAudioBuffer() : Failed to allocate memory for audio buffer");
@@ -654,8 +656,9 @@ AudioBuffer* CreateAudioBuffer(mal_format format, mal_uint32 channels, mal_uint3
dspConfig.channelsOut = DEVICE_CHANNELS;
dspConfig.sampleRateIn = sampleRate;
dspConfig.sampleRateOut = DEVICE_SAMPLE_RATE;
- mal_result resultMAL = mal_dsp_init(&dspConfig, AudioBuffer_OnDSPRead, audioBuffer, &audioBuffer->dsp);
- if (resultMAL != MAL_SUCCESS) {
+ mal_result resultMAL = mal_dsp_init(&dspConfig, OnAudioBufferDSPRead, audioBuffer, &audioBuffer->dsp);
+ if (resultMAL != MAL_SUCCESS)
+ {
TraceLog(LOG_ERROR, "LoadSoundFromWave() : Failed to create data conversion pipeline");
free(audioBuffer);
return NULL;
@@ -679,8 +682,8 @@ AudioBuffer* CreateAudioBuffer(mal_format format, mal_uint32 channels, mal_uint3
return audioBuffer;
}
-// Delete an audio buffer.
-void DeleteAudioBuffer(AudioBuffer* audioBuffer)
+// Delete an audio buffer
+void DeleteAudioBuffer(AudioBuffer *audioBuffer)
{
if (audioBuffer == NULL)
{
@@ -692,8 +695,8 @@ void DeleteAudioBuffer(AudioBuffer* audioBuffer)
free(audioBuffer);
}
-// Check if an audio buffer is playing.
-bool IsAudioBufferPlaying(AudioBuffer* audioBuffer)
+// Check if an audio buffer is playing
+bool IsAudioBufferPlaying(AudioBuffer *audioBuffer)
{
if (audioBuffer == NULL)
{
@@ -704,11 +707,10 @@ bool IsAudioBufferPlaying(AudioBuffer* audioBuffer)
return audioBuffer->playing && !audioBuffer->paused;
}
-// Play an audio buffer.
-//
-// This will restart the buffer from the start. Use PauseAudioBuffer() and ResumeAudioBuffer() if the playback position
-// should be maintained.
-void PlayAudioBuffer(AudioBuffer* audioBuffer)
+// Play an audio buffer
+// NOTE: Buffer is restarted to the start.
+// Use PauseAudioBuffer() and ResumeAudioBuffer() if the playback position should be maintained.
+void PlayAudioBuffer(AudioBuffer *audioBuffer)
{
if (audioBuffer == NULL)
{
@@ -721,8 +723,8 @@ void PlayAudioBuffer(AudioBuffer* audioBuffer)
audioBuffer->frameCursorPos = 0;
}
-// Stop an audio buffer.
-void StopAudioBuffer(AudioBuffer* audioBuffer)
+// Stop an audio buffer
+void StopAudioBuffer(AudioBuffer *audioBuffer)
{
if (audioBuffer == NULL)
{
@@ -731,10 +733,7 @@ void StopAudioBuffer(AudioBuffer* audioBuffer)
}
// Don't do anything if the audio buffer is already stopped.
- if (!IsAudioBufferPlaying(audioBuffer))
- {
- return;
- }
+ if (!IsAudioBufferPlaying(audioBuffer)) return;
audioBuffer->playing = false;
audioBuffer->paused = false;
@@ -743,8 +742,8 @@ void StopAudioBuffer(AudioBuffer* audioBuffer)
audioBuffer->isSubBufferProcessed[1] = true;
}
-// Pause an audio buffer.
-void PauseAudioBuffer(AudioBuffer* audioBuffer)
+// Pause an audio buffer
+void PauseAudioBuffer(AudioBuffer *audioBuffer)
{
if (audioBuffer == NULL)
{
@@ -755,8 +754,8 @@ void PauseAudioBuffer(AudioBuffer* audioBuffer)
audioBuffer->paused = true;
}
-// Resume an audio buffer.
-void ResumeAudioBuffer(AudioBuffer* audioBuffer)
+// Resume an audio buffer
+void ResumeAudioBuffer(AudioBuffer *audioBuffer)
{
if (audioBuffer == NULL)
{
@@ -767,8 +766,8 @@ void ResumeAudioBuffer(AudioBuffer* audioBuffer)
audioBuffer->paused = false;
}
-// Set volume for an audio buffer.
-void SetAudioBufferVolume(AudioBuffer* audioBuffer, float volume)
+// Set volume for an audio buffer
+void SetAudioBufferVolume(AudioBuffer *audioBuffer, float volume)
{
if (audioBuffer == NULL)
{
@@ -779,8 +778,8 @@ void SetAudioBufferVolume(AudioBuffer* audioBuffer, float volume)
audioBuffer->volume = volume;
}
-// Set pitch for an audio buffer.
-void SetAudioBufferPitch(AudioBuffer* audioBuffer, float pitch)
+// Set pitch for an audio buffer
+void SetAudioBufferPitch(AudioBuffer *audioBuffer, float pitch)
{
if (audioBuffer == NULL)
{
@@ -795,6 +794,44 @@ void SetAudioBufferPitch(AudioBuffer* audioBuffer, float pitch)
mal_uint32 newOutputSampleRate = (mal_uint32)((((float)audioBuffer->dsp.config.sampleRateOut / (float)audioBuffer->dsp.config.sampleRateIn) / pitch) * audioBuffer->dsp.config.sampleRateIn);
mal_dsp_set_output_sample_rate(&audioBuffer->dsp, newOutputSampleRate);
}
+
+// Track audio buffer to linked list next position
+void TrackAudioBuffer(AudioBuffer *audioBuffer)
+{
+ mal_mutex_lock(&audioLock);
+
+ {
+ if (firstAudioBuffer == NULL) firstAudioBuffer = audioBuffer;
+ else
+ {
+ lastAudioBuffer->next = audioBuffer;
+ audioBuffer->prev = lastAudioBuffer;
+ }
+
+ lastAudioBuffer = audioBuffer;
+ }
+
+ mal_mutex_unlock(&audioLock);
+}
+
+// Untrack audio buffer from linked list
+void UntrackAudioBuffer(AudioBuffer *audioBuffer)
+{
+ mal_mutex_lock(&audioLock);
+
+ {
+ if (audioBuffer->prev == NULL) firstAudioBuffer = audioBuffer->next;
+ else audioBuffer->prev->next = audioBuffer->next;
+
+ if (audioBuffer->next == NULL) lastAudioBuffer = audioBuffer->prev;
+ else audioBuffer->next->prev = audioBuffer->prev;
+
+ audioBuffer->prev = NULL;
+ audioBuffer->next = NULL;
+ }
+
+ mal_mutex_unlock(&audioLock);
+}
#endif
//----------------------------------------------------------------------------------
@@ -812,19 +849,6 @@ Wave LoadWave(const char *fileName)
#endif
#if defined(SUPPORT_FILEFORMAT_FLAC)
else if (IsFileExtension(fileName, ".flac")) wave = LoadFLAC(fileName);
-#endif
-#if !defined(AUDIO_STANDALONE)
- else if (IsFileExtension(fileName, ".rres"))
- {
- RRES rres = LoadResource(fileName, 0);
-
- // NOTE: Parameters for RRES_TYPE_WAVE are: sampleCount, sampleRate, sampleSize, channels
-
- if (rres[0].type == RRES_TYPE_WAVE) wave = LoadWaveEx(rres[0].data, rres[0].param1, rres[0].param2, rres[0].param3, rres[0].param4);
- else TraceLog(LOG_WARNING, "[%s] Resource file does not contain wave data", fileName);
-
- UnloadResource(rres);
- }
#endif
else TraceLog(LOG_WARNING, "[%s] Audio fileformat not supported, it can't be loaded", fileName);
@@ -884,23 +908,13 @@ Sound LoadSoundFromWave(Wave wave)
mal_uint32 frameCountIn = wave.sampleCount; // Is wave->sampleCount actually the frame count? That terminology needs to change, if so.
mal_uint32 frameCount = mal_convert_frames(NULL, DEVICE_FORMAT, DEVICE_CHANNELS, DEVICE_SAMPLE_RATE, NULL, formatIn, wave.channels, wave.sampleRate, frameCountIn);
- if (frameCount == 0) {
- TraceLog(LOG_ERROR, "LoadSoundFromWave() : Failed to get frame count for format conversion");
- }
-
+ if (frameCount == 0) TraceLog(LOG_WARNING, "LoadSoundFromWave() : Failed to get frame count for format conversion");
AudioBuffer* audioBuffer = CreateAudioBuffer(DEVICE_FORMAT, DEVICE_CHANNELS, DEVICE_SAMPLE_RATE, frameCount, AUDIO_BUFFER_USAGE_STATIC);
- if (audioBuffer == NULL)
- {
- TraceLog(LOG_ERROR, "LoadSoundFromWave() : Failed to create audio buffer");
- }
-
+ if (audioBuffer == NULL) TraceLog(LOG_WARNING, "LoadSoundFromWave() : Failed to create audio buffer");
frameCount = mal_convert_frames(audioBuffer->buffer, audioBuffer->dsp.config.formatIn, audioBuffer->dsp.config.channelsIn, audioBuffer->dsp.config.sampleRateIn, wave.data, formatIn, wave.channels, wave.sampleRate, frameCountIn);
- if (frameCount == 0)
- {
- TraceLog(LOG_ERROR, "LoadSoundFromWave() : Format conversion failed");
- }
+ if (frameCount == 0) TraceLog(LOG_WARNING, "LoadSoundFromWave() : Format conversion failed");
sound.audioBuffer = audioBuffer;
#else
@@ -975,7 +989,7 @@ void UnloadWave(Wave wave)
void UnloadSound(Sound sound)
{
#if USE_MINI_AL
- DeleteAudioBuffer((AudioBuffer*)sound.audioBuffer);
+ DeleteAudioBuffer((AudioBuffer *)sound.audioBuffer);
#else
alSourceStop(sound.source);
@@ -991,7 +1005,7 @@ void UnloadSound(Sound sound)
void UpdateSound(Sound sound, const void *data, int samplesCount)
{
#if USE_MINI_AL
- AudioBuffer* audioBuffer = (AudioBuffer*)sound.audioBuffer;
+ AudioBuffer *audioBuffer = (AudioBuffer *)sound.audioBuffer;
if (audioBuffer == NULL)
{
TraceLog(LOG_ERROR, "UpdateSound() : Invalid sound - no audio buffer");
@@ -1031,7 +1045,7 @@ void UpdateSound(Sound sound, const void *data, int samplesCount)
void PlaySound(Sound sound)
{
#if USE_MINI_AL
- PlayAudioBuffer((AudioBuffer*)sound.audioBuffer);
+ PlayAudioBuffer((AudioBuffer *)sound.audioBuffer);
#else
alSourcePlay(sound.source); // Play the sound
#endif
@@ -1056,7 +1070,7 @@ void PlaySound(Sound sound)
void PauseSound(Sound sound)
{
#if USE_MINI_AL
- PauseAudioBuffer((AudioBuffer*)sound.audioBuffer);
+ PauseAudioBuffer((AudioBuffer *)sound.audioBuffer);
#else
alSourcePause(sound.source);
#endif
@@ -1066,7 +1080,7 @@ void PauseSound(Sound sound)
void ResumeSound(Sound sound)
{
#if USE_MINI_AL
- ResumeAudioBuffer((AudioBuffer*)sound.audioBuffer);
+ ResumeAudioBuffer((AudioBuffer *)sound.audioBuffer);
#else
ALenum state;
@@ -1080,7 +1094,7 @@ void ResumeSound(Sound sound)
void StopSound(Sound sound)
{
#if USE_MINI_AL
- StopAudioBuffer((AudioBuffer*)sound.audioBuffer);
+ StopAudioBuffer((AudioBuffer *)sound.audioBuffer);
#else
alSourceStop(sound.source);
#endif
@@ -1090,7 +1104,7 @@ void StopSound(Sound sound)
bool IsSoundPlaying(Sound sound)
{
#if USE_MINI_AL
- return IsAudioBufferPlaying((AudioBuffer*)sound.audioBuffer);
+ return IsAudioBufferPlaying((AudioBuffer *)sound.audioBuffer);
#else
bool playing = false;
ALint state;
@@ -1106,7 +1120,7 @@ bool IsSoundPlaying(Sound sound)
void SetSoundVolume(Sound sound, float volume)
{
#if USE_MINI_AL
- SetAudioBufferVolume((AudioBuffer*)sound.audioBuffer, volume);
+ SetAudioBufferVolume((AudioBuffer *)sound.audioBuffer, volume);
#else
alSourcef(sound.source, AL_GAIN, volume);
#endif
@@ -1116,7 +1130,7 @@ void SetSoundVolume(Sound sound, float volume)
void SetSoundPitch(Sound sound, float pitch)
{
#if USE_MINI_AL
- SetAudioBufferPitch((AudioBuffer*)sound.audioBuffer, pitch);
+ SetAudioBufferPitch((AudioBuffer *)sound.audioBuffer, pitch);
#else
alSourcef(sound.source, AL_PITCH, pitch);
#endif
@@ -1125,21 +1139,24 @@ void SetSoundPitch(Sound sound, float pitch)
// Convert wave data to desired format
void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels)
{
+#if USE_MINI_AL
mal_format formatIn = ((wave->sampleSize == 8) ? mal_format_u8 : ((wave->sampleSize == 16) ? mal_format_s16 : mal_format_f32));
mal_format formatOut = (( sampleSize == 8) ? mal_format_u8 : (( sampleSize == 16) ? mal_format_s16 : mal_format_f32));
mal_uint32 frameCountIn = wave->sampleCount; // Is wave->sampleCount actually the frame count? That terminology needs to change, if so.
mal_uint32 frameCount = mal_convert_frames(NULL, formatOut, channels, sampleRate, NULL, formatIn, wave->channels, wave->sampleRate, frameCountIn);
- if (frameCount == 0) {
+ if (frameCount == 0)
+ {
TraceLog(LOG_ERROR, "WaveFormat() : Failed to get frame count for format conversion.");
return;
}
- void* data = malloc(frameCount * channels * (sampleSize/8));
+ void *data = malloc(frameCount*channels*(sampleSize/8));
frameCount = mal_convert_frames(data, formatOut, channels, sampleRate, wave->data, formatIn, wave->channels, wave->sampleRate, frameCountIn);
- if (frameCount == 0) {
+ if (frameCount == 0)
+ {
TraceLog(LOG_ERROR, "WaveFormat() : Format conversion failed.");
return;
}
@@ -1151,7 +1168,7 @@ void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels)
free(wave->data);
wave->data = data;
-#if 0
+#else
// Format sample rate
// NOTE: Only supported 22050 <--> 44100
if (wave->sampleRate != sampleRate)
@@ -1414,7 +1431,7 @@ void UnloadMusicStream(Music music)
void PlayMusicStream(Music music)
{
#if USE_MINI_AL
- AudioBuffer* audioBuffer = (AudioBuffer*)music->stream.audioBuffer;
+ AudioBuffer *audioBuffer = (AudioBuffer *)music->stream.audioBuffer;
if (audioBuffer == NULL)
{
TraceLog(LOG_ERROR, "PlayMusicStream() : No audio buffer");
@@ -1426,9 +1443,9 @@ void PlayMusicStream(Music music)
// // just make sure to play again on window restore
// if (IsMusicPlaying(music)) PlayMusicStream(music);
mal_uint32 frameCursorPos = audioBuffer->frameCursorPos;
- {
- PlayAudioStream(music->stream); // <-- This resets the cursor position.
- }
+
+ PlayAudioStream(music->stream); // <-- This resets the cursor position.
+
audioBuffer->frameCursorPos = frameCursorPos;
#else
alSourcePlay(music->stream.source);
@@ -1512,7 +1529,7 @@ void UpdateMusicStream(Music music)
#if USE_MINI_AL
bool streamEnding = false;
- unsigned int subBufferSizeInFrames = ((AudioBuffer*)music->stream.audioBuffer)->bufferSizeInFrames / 2;
+ unsigned int subBufferSizeInFrames = ((AudioBuffer *)music->stream.audioBuffer)->bufferSizeInFrames/2;
// NOTE: Using dynamic allocation because it could require more than 16KB
void *pcm = calloc(subBufferSizeInFrames*music->stream.sampleSize/8*music->stream.channels, 1);
@@ -1530,7 +1547,7 @@ void UpdateMusicStream(Music music)
case MUSIC_AUDIO_OGG:
{
// NOTE: Returns the number of samples to process (be careful! we ask for number of shorts!)
- int numSamplesOgg = stb_vorbis_get_samples_short_interleaved(music->ctxOgg, music->stream.channels, (short *)pcm, samplesCount*music->stream.channels);
+ stb_vorbis_get_samples_short_interleaved(music->ctxOgg, music->stream.channels, (short *)pcm, samplesCount*music->stream.channels);
} break;
#if defined(SUPPORT_FILEFORMAT_FLAC)
@@ -1576,10 +1593,7 @@ void UpdateMusicStream(Music music)
}
else
{
- if (music->loopCount == -1)
- {
- PlayMusicStream(music);
- }
+ if (music->loopCount == -1) PlayMusicStream(music);
}
}
else
@@ -1766,11 +1780,9 @@ AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, un
// The size of a streaming buffer must be at least double the size of a period.
unsigned int periodSize = device.bufferSizeInFrames / device.periods;
unsigned int subBufferSize = AUDIO_BUFFER_SIZE;
- if (subBufferSize < periodSize) {
- subBufferSize = periodSize;
- }
+ if (subBufferSize < periodSize) subBufferSize = periodSize;
- AudioBuffer* audioBuffer = CreateAudioBuffer(formatIn, stream.channels, stream.sampleRate, subBufferSize*2, AUDIO_BUFFER_USAGE_STREAM);
+ AudioBuffer *audioBuffer = CreateAudioBuffer(formatIn, stream.channels, stream.sampleRate, subBufferSize*2, AUDIO_BUFFER_USAGE_STREAM);
if (audioBuffer == NULL)
{
TraceLog(LOG_ERROR, "InitAudioStream() : Failed to create audio buffer");
@@ -1835,7 +1847,7 @@ AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, un
void CloseAudioStream(AudioStream stream)
{
#if USE_MINI_AL
- DeleteAudioBuffer((AudioBuffer*)stream.audioBuffer);
+ DeleteAudioBuffer((AudioBuffer *)stream.audioBuffer);
#else
// Stop playing channel
alSourceStop(stream.source);
@@ -1866,7 +1878,7 @@ void CloseAudioStream(AudioStream stream)
void UpdateAudioStream(AudioStream stream, const void *data, int samplesCount)
{
#if USE_MINI_AL
- AudioBuffer* audioBuffer = (AudioBuffer*)stream.audioBuffer;
+ AudioBuffer *audioBuffer = (AudioBuffer *)stream.audioBuffer;
if (audioBuffer == NULL)
{
TraceLog(LOG_ERROR, "UpdateAudioStream() : No audio buffer");
@@ -1889,23 +1901,22 @@ void UpdateAudioStream(AudioStream stream, const void *data, int samplesCount)
}
mal_uint32 subBufferSizeInFrames = audioBuffer->bufferSizeInFrames/2;
- unsigned char *subBuffer = audioBuffer->buffer + ((subBufferSizeInFrames * stream.channels * (stream.sampleSize/8)) * subBufferToUpdate);
+ unsigned char *subBuffer = audioBuffer->buffer + ((subBufferSizeInFrames*stream.channels*(stream.sampleSize/8))*subBufferToUpdate);
// Does this API expect a whole buffer to be updated in one go? Assuming so, but if not will need to change this logic.
if (subBufferSizeInFrames >= (mal_uint32)samplesCount)
{
mal_uint32 framesToWrite = subBufferSizeInFrames;
- if (framesToWrite > (mal_uint32)samplesCount) {
- framesToWrite = (mal_uint32)samplesCount;
- }
+ if (framesToWrite > (mal_uint32)samplesCount) framesToWrite = (mal_uint32)samplesCount;
- mal_uint32 bytesToWrite = framesToWrite * stream.channels * (stream.sampleSize/8);
+ mal_uint32 bytesToWrite = framesToWrite*stream.channels*(stream.sampleSize/8);
memcpy(subBuffer, data, bytesToWrite);
// Any leftover frames should be filled with zeros.
mal_uint32 leftoverFrameCount = subBufferSizeInFrames - framesToWrite;
- if (leftoverFrameCount > 0) {
- memset(subBuffer + bytesToWrite, 0, leftoverFrameCount * stream.channels * (stream.sampleSize/8));
+ if (leftoverFrameCount > 0)
+ {
+ memset(subBuffer + bytesToWrite, 0, leftoverFrameCount*stream.channels*(stream.sampleSize/8));
}
audioBuffer->isSubBufferProcessed[subBufferToUpdate] = false;
@@ -1939,7 +1950,7 @@ void UpdateAudioStream(AudioStream stream, const void *data, int samplesCount)
bool IsAudioBufferProcessed(AudioStream stream)
{
#if USE_MINI_AL
- AudioBuffer* audioBuffer = (AudioBuffer*)stream.audioBuffer;
+ AudioBuffer *audioBuffer = (AudioBuffer *)stream.audioBuffer;
if (audioBuffer == NULL)
{
TraceLog(LOG_ERROR, "IsAudioBufferProcessed() : No audio buffer");
@@ -1961,7 +1972,7 @@ bool IsAudioBufferProcessed(AudioStream stream)
void PlayAudioStream(AudioStream stream)
{
#if USE_MINI_AL
- PlayAudioBuffer((AudioBuffer*)stream.audioBuffer);
+ PlayAudioBuffer((AudioBuffer *)stream.audioBuffer);
#else
alSourcePlay(stream.source);
#endif
@@ -1971,7 +1982,7 @@ void PlayAudioStream(AudioStream stream)
void PauseAudioStream(AudioStream stream)
{
#if USE_MINI_AL
- PauseAudioBuffer((AudioBuffer*)stream.audioBuffer);
+ PauseAudioBuffer((AudioBuffer *)stream.audioBuffer);
#else
alSourcePause(stream.source);
#endif
@@ -1981,7 +1992,7 @@ void PauseAudioStream(AudioStream stream)
void ResumeAudioStream(AudioStream stream)
{
#if USE_MINI_AL
- ResumeAudioBuffer((AudioBuffer*)stream.audioBuffer);
+ ResumeAudioBuffer((AudioBuffer *)stream.audioBuffer);
#else
ALenum state;
alGetSourcei(stream.source, AL_SOURCE_STATE, &state);
@@ -1994,7 +2005,7 @@ void ResumeAudioStream(AudioStream stream)
bool IsAudioStreamPlaying(AudioStream stream)
{
#if USE_MINI_AL
- return IsAudioBufferPlaying((AudioBuffer*)stream.audioBuffer);
+ return IsAudioBufferPlaying((AudioBuffer *)stream.audioBuffer);
#else
bool playing = false;
ALint state;
@@ -2011,7 +2022,7 @@ bool IsAudioStreamPlaying(AudioStream stream)
void StopAudioStream(AudioStream stream)
{
#if USE_MINI_AL
- StopAudioBuffer((AudioBuffer*)stream.audioBuffer);
+ StopAudioBuffer((AudioBuffer *)stream.audioBuffer);
#else
alSourceStop(stream.source);
#endif
@@ -2020,7 +2031,7 @@ void StopAudioStream(AudioStream stream)
void SetAudioStreamVolume(AudioStream stream, float volume)
{
#if USE_MINI_AL
- SetAudioBufferVolume((AudioBuffer*)stream.audioBuffer, volume);
+ SetAudioBufferVolume((AudioBuffer *)stream.audioBuffer, volume);
#else
alSourcef(stream.source, AL_GAIN, volume);
#endif
@@ -2029,7 +2040,7 @@ void SetAudioStreamVolume(AudioStream stream, float volume)
void SetAudioStreamPitch(AudioStream stream, float pitch)
{
#if USE_MINI_AL
- SetAudioBufferPitch((AudioBuffer*)stream.audioBuffer, pitch);
+ SetAudioBufferPitch((AudioBuffer *)stream.audioBuffer, pitch);
#else
alSourcef(stream.source, AL_PITCH, pitch);
#endif
diff --git a/src/audio.h b/src/audio.h
index 48ef7403b..01c937419 100644
--- a/src/audio.h
+++ b/src/audio.h
@@ -10,19 +10,24 @@
* - Manage mixing channels
* - Manage raw audio context
*
-* LIMITATIONS:
+* LIMITATIONS (only OpenAL Soft):
* Only up to two channels supported: MONO and STEREO (for additional channels, use AL_EXT_MCFORMATS)
* Only the following sample sizes supported: 8bit PCM, 16bit PCM, 32-bit float PCM (using AL_EXT_FLOAT32)
*
* DEPENDENCIES:
-* OpenAL Soft - Audio device management (http://kcat.strangesoft.net/openal.html)
+* mini_al - Audio device/context management (https://github.com/dr-soft/mini_al)
* stb_vorbis - OGG audio files loading (http://www.nothings.org/stb_vorbis/)
-* jar_xm - XM module file loading (#define SUPPORT_FILEFORMAT_XM)
-* jar_mod - MOD audio file loading (#define SUPPORT_FILEFORMAT_MOD)
-* dr_flac - FLAC audio file loading (#define SUPPORT_FILEFORMAT_FLAC)
+* jar_xm - XM module file loading
+* jar_mod - MOD audio file loading
+* dr_flac - FLAC audio file loading
+*
+* *OpenAL Soft - Audio device management, still used on HTML5 and OSX platforms
*
* CONTRIBUTORS:
-* Joshua Reisenauer (github: @kd7tck):
+* David Reid (github: @mackron) (Nov. 2017):
+* - Complete port to mini_al library
+*
+* Joshua Reisenauer (github: @kd7tck) (2015)
* - XM audio module support (jar_xm)
* - MOD audio module support (jar_mod)
* - Mixing channels support
@@ -31,7 +36,7 @@
*
* LICENSE: zlib/libpng
*
-* Copyright (c) 2014-2017 Ramon Santamaria (@raysan5)
+* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
@@ -81,9 +86,11 @@ typedef struct Wave {
// Sound source type
typedef struct Sound {
- unsigned int source; // OpenAL audio source id
- unsigned int buffer; // OpenAL audio buffer id
- int format; // OpenAL audio format specifier
+ void *audioBuffer; // Pointer to internal data used by the audio system
+
+ unsigned int source; // Audio source id
+ unsigned int buffer; // Audio buffer id
+ int format; // Audio format specifier
} Sound;
// Music type (file streaming from memory)
@@ -97,9 +104,11 @@ typedef struct AudioStream {
unsigned int sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported)
unsigned int channels; // Number of channels (1-mono, 2-stereo)
- int format; // OpenAL audio format specifier
- unsigned int source; // OpenAL audio source id
- unsigned int buffers[2]; // OpenAL audio buffers (double buffering)
+ void *audioBuffer; // Pointer to internal data used by the audio system.
+
+ int format; // Audio format specifier
+ unsigned int source; // Audio source id
+ unsigned int buffers[2]; // Audio buffers (double buffering)
} AudioStream;
#ifdef __cplusplus
@@ -147,12 +156,12 @@ void ResumeMusicStream(Music music); // Resume playin
bool IsMusicPlaying(Music music); // Check if music is playing
void SetMusicVolume(Music music, float volume); // Set volume for music (1.0 is max level)
void SetMusicPitch(Music music, float pitch); // Set pitch for a music (1.0 is base level)
-void SetMusicLoopCount(Music music, float count); // Set music loop count (loop repeats)
+void SetMusicLoopCount(Music music, int count); // Set music loop count (loop repeats)
float GetMusicTimeLength(Music music); // Get music time length (in seconds)
float GetMusicTimePlayed(Music music); // Get current music time played (in seconds)
-// Raw audio stream functions
-AudioStream InitAudioStream(unsigned int sampleRate,
+// AudioStream management functions
+AudioStream InitAudioStream(unsigned int sampleRate,
unsigned int sampleSize,
unsigned int channels); // Init audio stream (to stream raw audio pcm data)
void UpdateAudioStream(AudioStream stream, const void *data, int samplesCount); // Update audio stream buffers with data
@@ -161,7 +170,10 @@ bool IsAudioBufferProcessed(AudioStream stream); // Check if any
void PlayAudioStream(AudioStream stream); // Play audio stream
void PauseAudioStream(AudioStream stream); // Pause audio stream
void ResumeAudioStream(AudioStream stream); // Resume audio stream
+bool IsAudioStreamPlaying(AudioStream stream); // Check if audio stream is playing
void StopAudioStream(AudioStream stream); // Stop audio stream
+void SetAudioStreamVolume(AudioStream stream, float volume); // Set volume for audio stream (1.0 is max level)
+void SetAudioStreamPitch(AudioStream stream, float pitch); // Set pitch for audio stream (1.0 is base level)
#ifdef __cplusplus
}
diff --git a/src/config.h b/src/config.h
new file mode 100644
index 000000000..a8b5ea195
--- /dev/null
+++ b/src/config.h
@@ -0,0 +1,129 @@
+/**********************************************************************************************
+*
+* raylib configuration flags
+*
+* This file defines all the configuration flags for the different raylib modules
+*
+* LICENSE: zlib/libpng
+*
+* Copyright (c) 2018 Ahmad Fatoum & Ramon Santamaria (@raysan5)
+*
+* This software is provided "as-is", without any express or implied warranty. In no event
+* will the authors be held liable for any damages arising from the use of this software.
+*
+* Permission is granted to anyone to use this software for any purpose, including commercial
+* applications, and to alter it and redistribute it freely, subject to the following restrictions:
+*
+* 1. The origin of this software must not be misrepresented; you must not claim that you
+* wrote the original software. If you use this software in a product, an acknowledgment
+* in the product documentation would be appreciated but is not required.
+*
+* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
+* as being the original software.
+*
+* 3. This notice may not be removed or altered from any source distribution.
+*
+**********************************************************************************************/
+
+#define RAYLIB_VERSION "1.9.7-dev"
+
+// Edit to control what features Makefile'd raylib is compiled with
+#if defined(RAYLIB_CMAKE)
+ // Edit CMakeOptions.txt for CMake instead
+ #include "cmake/config.h"
+#else
+
+//------------------------------------------------------------------------------------
+// Module: core - Configuration Flags
+//------------------------------------------------------------------------------------
+// Camera module is included (camera.h) and multiple predefined cameras are available: free, 1st/3rd person, orbital
+#define SUPPORT_CAMERA_SYSTEM 1
+// Gestures module is included (gestures.h) to support gestures detection: tap, hold, swipe, drag
+#define SUPPORT_GESTURES_SYSTEM 1
+// Mouse gestures are directly mapped like touches and processed by gestures system
+#define SUPPORT_MOUSE_GESTURES 1
+// Use busy wait loop for timing sync, if not defined, a high-resolution timer is setup and used
+#define SUPPORT_BUSY_WAIT_LOOP 1
+// Allow automatic gif recording of current screen pressing CTRL+F12, defined in KeyCallback()
+#define SUPPORT_GIF_RECORDING 1
+
+
+//------------------------------------------------------------------------------------
+// Module: rlgl - Configuration Flags
+//------------------------------------------------------------------------------------
+// Support VR simulation functionality (stereo rendering)
+#define SUPPORT_VR_SIMULATOR 1
+// Include stereo rendering distortion shader (shader_distortion.h)
+#define SUPPORT_DISTORTION_SHADER 1
+
+
+//------------------------------------------------------------------------------------
+// Module: textures - Configuration Flags
+//------------------------------------------------------------------------------------
+// Selecte desired fileformats to be supported for image data loading
+#define SUPPORT_FILEFORMAT_PNG 1
+//#define SUPPORT_FILEFORMAT_BMP 1
+//#define SUPPORT_FILEFORMAT_TGA 1
+//#define SUPPORT_FILEFORMAT_JPG 1
+//#define SUPPORT_FILEFORMAT_GIF 1
+//#define SUPPORT_FILEFORMAT_PSD 1
+#define SUPPORT_FILEFORMAT_DDS 1
+#define SUPPORT_FILEFORMAT_HDR 1
+#define SUPPORT_FILEFORMAT_KTX 1
+#define SUPPORT_FILEFORMAT_ASTC 1
+//#define SUPPORT_FILEFORMAT_PKM 1
+//#define SUPPORT_FILEFORMAT_PVR 1
+
+// Support multiple image editing functions to scale, adjust colors, flip, draw on images, crop...
+// If not defined only three image editing functions supported: ImageFormat(), ImageAlphaMask(), ImageToPOT()
+#define SUPPORT_IMAGE_MANIPULATION 1
+// Support proedural image generation functionality (gradient, spot, perlin-noise, cellular)
+#define SUPPORT_IMAGE_GENERATION 1
+
+
+//------------------------------------------------------------------------------------
+// Module: text - Configuration Flags
+//------------------------------------------------------------------------------------
+// Default font is loaded on window initialization to be available for the user to render simple text
+// NOTE: If enabled, uses external module functions to load default raylib font
+#define SUPPORT_DEFAULT_FONT 1
+// Selected desired font fileformats to be supported for loading
+#define SUPPORT_FILEFORMAT_FNT 1
+#define SUPPORT_FILEFORMAT_TTF 1
+
+
+//------------------------------------------------------------------------------------
+// Module: models - Configuration Flags
+//------------------------------------------------------------------------------------
+// Selected desired model fileformats to be supported for loading
+#define SUPPORT_FILEFORMAT_OBJ 1
+#define SUPPORT_FILEFORMAT_MTL 1
+// Support procedural mesh generation functions, uses external par_shapes.h library
+// NOTE: Some generated meshes DO NOT include generated texture coordinates
+#define SUPPORT_MESH_GENERATION 1
+
+
+//------------------------------------------------------------------------------------
+// Module: audio - Configuration Flags
+//------------------------------------------------------------------------------------
+// Desired audio fileformats to be supported for loading
+#define SUPPORT_FILEFORMAT_WAV 1
+#define SUPPORT_FILEFORMAT_OGG 1
+#define SUPPORT_FILEFORMAT_XM 1
+#define SUPPORT_FILEFORMAT_MOD 1
+//#define SUPPORT_FILEFORMAT_FLAC 1
+
+
+//------------------------------------------------------------------------------------
+// Module: utils - Configuration Flags
+//------------------------------------------------------------------------------------
+// Show TraceLog() output messages
+// NOTE: By default LOG_DEBUG traces not shown
+#define SUPPORT_TRACELOG 1
+// Support saving image data fileformats
+// NOTE: Requires stb_image_write library
+#define SUPPORT_SAVE_PNG 1
+//#define SUPPORT_SAVE_BMP 1
+
+
+#endif //defined(RAYLIB_CMAKE)
diff --git a/src/config.h.in b/src/config.h.in
new file mode 100644
index 000000000..5b6ed0546
--- /dev/null
+++ b/src/config.h.in
@@ -0,0 +1,74 @@
+/* config.h.in */
+
+// text.c
+/* Default font is loaded on window initialization to be available for the user to render simple text. NOTE: If enabled, uses external module functions to load default raylib font (module: text) */
+#cmakedefine SUPPORT_DEFAULT_FONT 1
+/* Selected desired fileformats to be supported for loading. */
+#cmakedefine SUPPORT_FILEFORMAT_FNT 1
+#cmakedefine SUPPORT_FILEFORMAT_TTF 1
+
+// textures.c
+/* Selecte desired fileformats to be supported for image data loading. */
+#cmakedefine SUPPORT_FILEFORMAT_PNG 1
+#cmakedefine SUPPORT_FILEFORMAT_DDS 1
+#cmakedefine SUPPORT_FILEFORMAT_HDR 1
+#cmakedefine SUPPORT_FILEFORMAT_KTX 1
+#cmakedefine SUPPORT_FILEFORMAT_ASTC 1
+#cmakedefine SUPPORT_FILEFORMAT_BMP 1
+#cmakedefine SUPPORT_FILEFORMAT_TGA 1
+#cmakedefine SUPPORT_FILEFORMAT_JPG 1
+#cmakedefine SUPPORT_FILEFORMAT_GIF 1
+#cmakedefine SUPPORT_FILEFORMAT_PSD 1
+#cmakedefine SUPPORT_FILEFORMAT_PKM 1
+#cmakedefine SUPPORT_FILEFORMAT_PVR 1
+
+/* Support multiple image editing functions to scale, adjust colors, flip, draw on images, crop... If not defined only three image editing functions supported: ImageFormat(), ImageAlphaMask(), ImageToPOT() */
+#cmakedefine SUPPORT_IMAGE_MANIPULATION 1
+
+/* Support proedural image generation functionality (gradient, spot, perlin-noise, cellular) */
+#cmakedefine SUPPORT_IMAGE_GENERATION 1
+
+// rlgl.c
+/* Support VR simulation functionality (stereo rendering) */
+#cmakedefine SUPPORT_VR_SIMULATOR 1
+/* Include stereo rendering distortion shader (shader_distortion.h) */
+#cmakedefine SUPPORT_DISTORTION_SHADER 1
+
+// core.c
+/* Camera module is included (camera.h) and multiple predefined cameras are available: free, 1st/3rd person, orbital */
+#cmakedefine SUPPORT_CAMERA_SYSTEM 1
+/* Gestures module is included (gestures.h) to support gestures detection: tap, hold, swipe, drag */
+#cmakedefine SUPPORT_GESTURES_SYSTEM 1
+/* Mouse gestures are directly mapped like touches and processed by gestures system. */
+#cmakedefine SUPPORT_MOUSE_GESTURES 1
+/* Use busy wait loop for timing sync, if not defined, a high-resolution timer is setup and used */
+#cmakedefine SUPPORT_BUSY_WAIT_LOOP 1
+/* Allow automatic gif recording of current screen pressing CTRL+F12, defined in KeyCallback() */
+#cmakedefine SUPPORT_GIF_RECORDING 1
+
+// audio.c
+/* Desired fileformats to be supported for loading. */
+#cmakedefine SUPPORT_FILEFORMAT_WAV 1
+#cmakedefine SUPPORT_FILEFORMAT_OGG 1
+#cmakedefine SUPPORT_FILEFORMAT_XM 1
+#cmakedefine SUPPORT_FILEFORMAT_MOD 1
+#cmakedefine SUPPORT_FILEFORMAT_FLAC 1
+
+// models.c
+/* Selected desired fileformats to be supported for loading. */
+#cmakedefine SUPPORT_FILEFORMAT_OBJ 1
+#cmakedefine SUPPORT_FILEFORMAT_MTL 1
+
+/* Support procedural mesh generation functions, uses external par_shapes.h library
+ * NOTE: Some generated meshes DO NOT include generated texture coordinates
+ */
+#cmakedefine SUPPORT_MESH_GENERATION 1
+
+// utils.c
+/* Show TraceLog() output messages. NOTE: By default LOG_DEBUG traces not shown */
+#cmakedefine SUPPORT_TRACELOG 1
+
+/* Support saving image data as PNG fileformat. NOTE: Requires stb_image_write library */
+#cmakedefine SUPPORT_SAVE_PNG 1
+/* Support saving image data as PMP fileformat. NOTE: Requires stb_image_write library */
+#cmakedefine SUPPORT_SAVE_BMP 1
diff --git a/src/core.c b/src/core.c
index 5172a7108..7772027b1 100644
--- a/src/core.c
+++ b/src/core.c
@@ -3,17 +3,19 @@
* raylib.core - Basic functions to manage windows, OpenGL context and input on multiple platforms
*
* PLATFORMS SUPPORTED:
-* - Windows (win32/Win64)
-* - Linux (tested on Ubuntu)
-* - OSX (Mac)
-* - Android (ARM or ARM64)
-* - Raspberry Pi (Raspbian)
-* - HTML5 (Chrome, Firefox)
+* - PLATFORM_DESKTOP: Windows (Win32, Win64)
+* - PLATFORM_DESKTOP: Linux (X11 desktop mode)
+* - PLATFORM_DESKTOP: FreeBSD (X11 desktop)
+* - PLATFORM_DESKTOP: OSX/macOS
+* - PLATFORM_ANDROID: Android 4.0 (ARM, ARM64)
+* - PLATFORM_RPI: Raspberry Pi 0,1,2,3 (Raspbian)
+* - PLATFORM_WEB: HTML5 with asm.js (Chrome, Firefox)
+* - PLATFORM_UWP: Windows 10 App, Windows Phone, Xbox One
*
* CONFIGURATION:
*
* #define PLATFORM_DESKTOP
-* Windowing and input system configured for desktop platforms: Windows, Linux, OSX (managed by GLFW3 library)
+* Windowing and input system configured for desktop platforms: Windows, Linux, OSX, FreeBSD
* NOTE: Oculus Rift CV1 requires PLATFORM_DESKTOP for mirror rendering - View [rlgl] module to enable it
*
* #define PLATFORM_ANDROID
@@ -21,13 +23,17 @@
* NOTE: OpenGL ES 2.0 is required and graphic device is managed by EGL
*
* #define PLATFORM_RPI
-* Windowing and input system configured for Raspberry Pi (tested on Raspbian), graphic device is managed by EGL
-* and inputs are processed is raw mode, reading from /dev/input/
+* Windowing and input system configured for Raspberry Pi i native mode (no X.org required, tested on Raspbian),
+* graphic device is managed by EGL and inputs are processed is raw mode, reading from /dev/input/
*
* #define PLATFORM_WEB
* Windowing and input system configured for HTML5 (run on browser), code converted from C to asm.js
* using emscripten compiler. OpenGL ES 2.0 required for direct translation to WebGL equivalent code.
*
+* #define PLATFORM_UWP
+* Universal Windows Platform support, using OpenGL ES 2.0 through ANGLE on multiple Windows platforms,
+* including Windows 10 App, Windows Phone and Xbox One platforms.
+*
* #define SUPPORT_DEFAULT_FONT (default)
* Default font is loaded on window initialization to be available for the user to render simple text.
* NOTE: If enabled, uses external module functions to load default raylib font (module: text)
@@ -42,21 +48,21 @@
* Mouse gestures are directly mapped like touches and processed by gestures system.
*
* #define SUPPORT_BUSY_WAIT_LOOP
-* Use busy wait loop for timming sync, if not defined, a high-resolution timer is setup and used
+* Use busy wait loop for timing sync, if not defined, a high-resolution timer is setup and used
*
* #define SUPPORT_GIF_RECORDING
* Allow automatic gif recording of current screen pressing CTRL+F12, defined in KeyCallback()
*
* DEPENDENCIES:
-* GLFW3 - Manage graphic device, OpenGL context and inputs on PLATFORM_DESKTOP (Windows, Linux, OSX)
-* raymath - 3D math functionality (Vector3, Matrix, Quaternion)
+* rglfw - Manage graphic device, OpenGL context and inputs on PLATFORM_DESKTOP (Windows, Linux, OSX. FreeBSD)
+* raymath - 3D math functionality (Vector2, Vector3, Matrix, Quaternion)
* camera - Multiple 3D camera modes (free, orbital, 1st person, 3rd person)
* gestures - Gestures system for touch-ready devices (or simulated from mouse inputs)
*
*
* LICENSE: zlib/libpng
*
-* Copyright (c) 2014-2017 Ramon Santamaria (@raysan5)
+* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
@@ -75,25 +81,21 @@
*
**********************************************************************************************/
-// Default configuration flags (supported features)
-//-------------------------------------------------
-#define SUPPORT_DEFAULT_FONT
-#define SUPPORT_MOUSE_GESTURES
-#define SUPPORT_CAMERA_SYSTEM
-#define SUPPORT_GESTURES_SYSTEM
-#define SUPPORT_BUSY_WAIT_LOOP
-#define SUPPORT_GIF_RECORDING
-//-------------------------------------------------
+#include "config.h"
#include "raylib.h"
+#if (defined(__linux__) || defined(PLATFORM_WEB)) && _POSIX_C_SOURCE < 199309L
+ #undef _POSIX_C_SOURCE
+ #define _POSIX_C_SOURCE 199309L // Required for CLOCK_MONOTONIC if compiled with c99 without gnu ext.
+#endif
+
+#define RAYMATH_IMPLEMENTATION // Define external out-of-line implementation of raymath here
+#include "raymath.h" // Required for: Vector3 and Matrix functions
+
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2
#include "utils.h" // Required for: fopen() Android mapping
-#define RAYMATH_IMPLEMENTATION // Use raymath as a header-only library (includes implementation)
-#define RAYMATH_EXTERN_INLINE // Compile raymath functions as static inline (remember, it's a compiler hint)
-#include "raymath.h" // Required for: Vector3 and Matrix functions
-
#if defined(SUPPORT_GESTURES_SYSTEM)
#define GESTURES_IMPLEMENTATION
#include "gestures.h" // Gestures detection functionality
@@ -109,10 +111,6 @@
#include "external/rgif.h" // Support GIF recording
#endif
-#if defined(__linux__) || defined(PLATFORM_WEB)
- #define _POSIX_C_SOURCE 199309L // Required for CLOCK_MONOTONIC if compiled with c99 without gnu ext.
-#endif
-
#include // Standard input / output lib
#include // Required for: malloc(), free(), rand(), atexit()
#include // Required for: typedef unsigned long long int uint64_t, used by hi-res timer
@@ -120,8 +118,9 @@
#include // Required for: tan() [Used in Begin3dMode() to set perspective]
#include // Required for: strrchr(), strcmp()
//#include // Macros for reporting and retrieving error conditions through error codes
+#include // Required for: tolower() [Used in IsFileExtension()]
-#ifdef _WIN32
+#if defined(_WIN32)
#include // Required for: _getch(), _chdir()
#define GETCWD _getcwd // NOTE: MSDN recommends not to use getcwd(), chdir()
#define CHDIR _chdir
@@ -147,12 +146,11 @@
#include // which are required for hiding mouse
#endif
//#include // OpenGL functions (GLFW3 already includes gl.h)
- //#define GLFW_DLL // Using GLFW DLL on Windows -> No, we use static version!
-
+
#if !defined(SUPPORT_BUSY_WAIT_LOOP) && defined(_WIN32)
// NOTE: Those functions require linking with winmm library
- __stdcall unsigned int timeBeginPeriod(unsigned int uPeriod);
- __stdcall unsigned int timeEndPeriod(unsigned int uPeriod);
+ unsigned int __stdcall timeBeginPeriod(unsigned int uPeriod);
+ unsigned int __stdcall timeEndPeriod(unsigned int uPeriod);
#endif
#endif
@@ -183,6 +181,12 @@
#include "GLES2/gl2.h" // Khronos OpenGL ES 2.0 library
#endif
+#if defined(PLATFORM_UWP)
+ #include "EGL/egl.h" // Khronos EGL library - Native platform display device control functions
+ #include "EGL/eglext.h" // Khronos EGL library - Extensions
+ #include "GLES2/gl2.h" // Khronos OpenGL ES 2.0 library
+#endif
+
#if defined(PLATFORM_WEB)
#include
#include
@@ -222,16 +226,18 @@
//----------------------------------------------------------------------------------
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
static GLFWwindow *window; // Native window (graphic device)
-static bool windowMinimized = false;
#endif
+static bool windowReady = false; // Check if window has been initialized successfully
+static bool windowMinimized = false; // Check if window has been minimized
+static const char *windowTitle = NULL; // Window text title...
+
#if defined(PLATFORM_ANDROID)
-static struct android_app *app; // Android activity
+static struct android_app *androidApp; // Android activity
static struct android_poll_source *source; // Android events polling source
static int ident, events; // Android ALooper_pollAll() variables
static const char *internalDataPath; // Android internal data path to write data (/data/data//files)
-static bool windowReady = false; // Used to detect display initialization
static bool appEnabled = true; // Used to detec if app is active
static bool contextRebindRequired = false; // Used to know context rebind required
#endif
@@ -260,7 +266,7 @@ static pthread_t gamepadThreadId; // Gamepad reading thread id
static char gamepadName[64]; // Gamepad name holder
#endif
-#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
+#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_UWP)
static EGLDisplay display; // Native display device (physical screen connection)
static EGLSurface surface; // Surface to draw on, framebuffers (connected to context)
static EGLContext context; // Graphic context, mode in which drawing can be done
@@ -269,7 +275,11 @@ static uint64_t baseTime; // Base time measure for hi-res timer
static bool windowShouldClose = false; // Flag to set window for closing
#endif
-// Display size-related data
+#if defined(PLATFORM_UWP)
+extern EGLNativeWindowType uwpWindow; // Native EGL window handler for UWP (external, defined in UWP App)
+#endif
+
+// Screen related variables
static unsigned int displayWidth, displayHeight; // Display width and height (monitor, device-screen, LCD, ...)
static int screenWidth, screenHeight; // Screen width and height (used render area)
static int renderWidth, renderHeight; // Framebuffer width and height (render area, including black bars if required)
@@ -278,10 +288,10 @@ static int renderOffsetY = 0; // Offset Y from render area (must b
static bool fullscreen = false; // Fullscreen mode (useful only for PLATFORM_DESKTOP)
static Matrix downscaleView; // Matrix to downscale view (in case screen size bigger than display size)
-#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
-static const char *windowTitle; // Window text title...
-static bool cursorOnScreen = false; // Tracks if cursor is inside client area
static bool cursorHidden = false; // Track if cursor is hidden
+static bool cursorOnScreen = false; // Tracks if cursor is inside client area
+
+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB) || defined(PLATFORM_UWP)
static int screenshotCounter = 0; // Screenshots counter
// Register mouse states
@@ -309,6 +319,7 @@ static int lastGamepadButtonPressed = -1; // Register last gamepad button pres
static int gamepadAxisCount = 0; // Register number of available gamepad axis
static Vector2 mousePosition; // Mouse position on screen
+static float mouseScale = 1.0f; // Mouse default scale
#if defined(PLATFORM_WEB)
static bool toggleCursorLock = false; // Ask for cursor pointer lock on next click
@@ -321,12 +332,14 @@ static char **dropFilesPath; // Store dropped files paths as stri
static int dropFilesCount = 0; // Count stored strings
#endif
-static double currentTime, previousTime; // Used to track timmings
-static double updateTime, drawTime; // Time measures for update and draw
+static double currentTime = 0.0; // Current time measure
+static double previousTime = 0.0; // Previous time measure
+static double updateTime = 0.0; // Time measure for frame update
+static double drawTime = 0.0; // Time measure for frame draw
static double frameTime = 0.0; // Time measure for one frame
static double targetTime = 0.0; // Desired time for one frame, if 0 not applied
-static char configFlags = 0; // Configuration flags (bit based)
+static unsigned char configFlags = 0; // Configuration flags (bit based)
static bool showLogo = false; // Track if showing logo at init is enabled
#if defined(SUPPORT_GIF_RECORDING)
@@ -345,10 +358,9 @@ extern void UnloadDefaultFont(void); // [Module: text] Unloads default fo
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
//----------------------------------------------------------------------------------
-static void InitGraphicsDevice(int width, int height); // Initialize graphics device
+static bool InitGraphicsDevice(int width, int height); // Initialize graphics device
static void SetupFramebufferSize(int displayWidth, int displayHeight);
static void InitTimer(void); // Initialize timer
-static double GetTime(void); // Returns time since InitTimer() was run
static void Wait(float ms); // Wait for some milliseconds (stop program execution)
static bool GetKeyStatus(int key); // Returns if a key has been pressed
static bool GetMouseButtonStatus(int button); // Returns if a mouse button has been pressed
@@ -398,6 +410,10 @@ static void InitGamepad(void); // Init raw gamepad inpu
static void *GamepadThread(void *arg); // Mouse reading thread
#endif
+#if defined(PLATFORM_UWP)
+// TODO: Define functions required to manage inputs
+#endif
+
#if defined(_WIN32)
// NOTE: We include Sleep() function signature here to avoid windows.h inclusion
void __stdcall Sleep(unsigned long msTimeout); // Required for Wait()
@@ -406,17 +422,96 @@ static void *GamepadThread(void *arg); // Mouse reading thread
//----------------------------------------------------------------------------------
// Module Functions Definition - Window and OpenGL Context Functions
//----------------------------------------------------------------------------------
-#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
+
+#if defined(PLATFORM_ANDROID)
+// To allow easier porting to android, we allow the user to define a
+// main function which we call from android_main, defined by ourselves
+extern int main(int argc, char *argv[]);
+
+void android_main(struct android_app *app)
+{
+ char arg0[] = "raylib"; // NOTE: argv[] are mutable
+ androidApp = app;
+
+ // TODO: Should we maybe report != 0 return codes somewhere?
+ (void)main(1, (char*[]) { arg0, NULL });
+}
+
+// TODO: Add this to header (if apps really need it)
+struct android_app *GetAndroidApp(void)
+{
+ return androidApp;
+}
+#endif
+
// Initialize window and OpenGL context
+// NOTE: data parameter could be used to pass any kind of required data to the initialization
void InitWindow(int width, int height, const char *title)
{
- TraceLog(LOG_INFO, "Initializing raylib (v1.8.0)");
+ TraceLog(LOG_INFO, "Initializing raylib %s", RAYLIB_VERSION);
- // Store window title (could be useful...)
windowTitle = title;
+#if defined(PLATFORM_ANDROID)
+ screenWidth = width;
+ screenHeight = height;
+ // Input data is android app pointer
+ internalDataPath = androidApp->activity->internalDataPath;
+
+ // Set desired windows flags before initializing anything
+ ANativeActivity_setWindowFlags(androidApp->activity, AWINDOW_FLAG_FULLSCREEN, 0); //AWINDOW_FLAG_SCALED, AWINDOW_FLAG_DITHER
+ //ANativeActivity_setWindowFlags(androidApp->activity, AWINDOW_FLAG_FORCE_NOT_FULLSCREEN, AWINDOW_FLAG_FULLSCREEN);
+
+ int orientation = AConfiguration_getOrientation(androidApp->config);
+
+ if (orientation == ACONFIGURATION_ORIENTATION_PORT) TraceLog(LOG_INFO, "PORTRAIT window orientation");
+ else if (orientation == ACONFIGURATION_ORIENTATION_LAND) TraceLog(LOG_INFO, "LANDSCAPE window orientation");
+
+ // TODO: Automatic orientation doesn't seem to work
+ if (width <= height)
+ {
+ AConfiguration_setOrientation(androidApp->config, ACONFIGURATION_ORIENTATION_PORT);
+ TraceLog(LOG_WARNING, "Window set to portraid mode");
+ }
+ else
+ {
+ AConfiguration_setOrientation(androidApp->config, ACONFIGURATION_ORIENTATION_LAND);
+ TraceLog(LOG_WARNING, "Window set to landscape mode");
+ }
+
+ //AConfiguration_getDensity(androidApp->config);
+ //AConfiguration_getKeyboard(androidApp->config);
+ //AConfiguration_getScreenSize(androidApp->config);
+ //AConfiguration_getScreenLong(androidApp->config);
+
+ androidApp->onAppCmd = AndroidCommandCallback;
+ androidApp->onInputEvent = AndroidInputCallback;
+
+ InitAssetManager(androidApp->activity->assetManager);
+
+ TraceLog(LOG_INFO, "Android app initialized successfully");
+
+ // Wait for window to be initialized (display and context)
+ while (!windowReady)
+ {
+ // Process events loop
+ while ((ident = ALooper_pollAll(0, NULL, &events, (void**)&source)) >= 0)
+ {
+ // Process this event
+ if (source != NULL) source->process(androidApp, source);
+
+ // NOTE: Never close window, native activity is controlled by the system!
+ //if (androidApp->destroyRequested != 0) windowShouldClose = true;
+ }
+ }
+#else
// Init graphics device (display device and OpenGL context)
- InitGraphicsDevice(width, height);
+ // NOTE: returns true if window and graphic device has been initialized successfully
+ windowReady = InitGraphicsDevice(width, height);
+ if (!windowReady) return;
+
+ // Init hi-res timer
+ InitTimer();
#if defined(SUPPORT_DEFAULT_FONT)
// Load default font
@@ -424,9 +519,6 @@ void InitWindow(int width, int height, const char *title)
LoadDefaultFont();
#endif
- // Init hi-res timer
- InitTimer();
-
#if defined(PLATFORM_RPI)
// Init raw input system
InitMouse(); // Mouse init
@@ -466,70 +558,8 @@ void InitWindow(int width, int height, const char *title)
SetTargetFPS(60);
LogoAnimation();
}
+#endif // defined(PLATFORM_ANDROID)
}
-#endif
-
-#if defined(PLATFORM_ANDROID)
-// Initialize Android activity
-void InitWindow(int width, int height, void *state)
-{
- TraceLog(LOG_INFO, "Initializing raylib (v1.8.0)");
-
- screenWidth = width;
- screenHeight = height;
-
- app = (struct android_app *)state;
- internalDataPath = app->activity->internalDataPath;
-
- // Set desired windows flags before initializing anything
- ANativeActivity_setWindowFlags(app->activity, AWINDOW_FLAG_FULLSCREEN, 0); //AWINDOW_FLAG_SCALED, AWINDOW_FLAG_DITHER
- //ANativeActivity_setWindowFlags(app->activity, AWINDOW_FLAG_FORCE_NOT_FULLSCREEN, AWINDOW_FLAG_FULLSCREEN);
-
- int orientation = AConfiguration_getOrientation(app->config);
-
- if (orientation == ACONFIGURATION_ORIENTATION_PORT) TraceLog(LOG_INFO, "PORTRAIT window orientation");
- else if (orientation == ACONFIGURATION_ORIENTATION_LAND) TraceLog(LOG_INFO, "LANDSCAPE window orientation");
-
- // TODO: Automatic orientation doesn't seem to work
- if (width <= height)
- {
- AConfiguration_setOrientation(app->config, ACONFIGURATION_ORIENTATION_PORT);
- TraceLog(LOG_WARNING, "Window set to portraid mode");
- }
- else
- {
- AConfiguration_setOrientation(app->config, ACONFIGURATION_ORIENTATION_LAND);
- TraceLog(LOG_WARNING, "Window set to landscape mode");
- }
-
- //AConfiguration_getDensity(app->config);
- //AConfiguration_getKeyboard(app->config);
- //AConfiguration_getScreenSize(app->config);
- //AConfiguration_getScreenLong(app->config);
-
- //state->userData = &engine;
- app->onAppCmd = AndroidCommandCallback;
- app->onInputEvent = AndroidInputCallback;
-
- InitAssetManager(app->activity->assetManager);
-
- TraceLog(LOG_INFO, "Android app initialized successfully");
-
- // Wait for window to be initialized (display and context)
- while (!windowReady)
- {
- // Process events loop
- while ((ident = ALooper_pollAll(0, NULL, &events,(void**)&source)) >= 0)
- {
- // Process this event
- if (source != NULL) source->process(app, source);
-
- // NOTE: Never close window, native activity is controlled by the system!
- //if (app->destroyRequested != 0) windowShouldClose = true;
- }
- }
-}
-#endif
// Close window and unload OpenGL context
void CloseWindow(void)
@@ -557,7 +587,7 @@ void CloseWindow(void)
timeEndPeriod(1); // Restore time period
#endif
-#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
+#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_UWP)
// Close surface, context and display
if (display != EGL_NO_DISPLAY)
{
@@ -595,25 +625,36 @@ void CloseWindow(void)
TraceLog(LOG_INFO, "Window closed successfully");
}
+// Check if window has been initialized successfully
+bool IsWindowReady(void)
+{
+ return windowReady;
+}
+
// Check if KEY_ESCAPE pressed or Close icon pressed
bool WindowShouldClose(void)
{
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
- // While window minimized, stop loop execution
- while (windowMinimized) glfwWaitEvents();
+ if (windowReady)
+ {
+ // While window minimized, stop loop execution
+ while (windowMinimized) glfwWaitEvents();
- return (glfwWindowShouldClose(window));
+ return (glfwWindowShouldClose(window));
+ }
+ else return true;
#endif
-#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
- return windowShouldClose;
+#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_UWP)
+ if (windowReady) return windowShouldClose;
+ else return true;
#endif
}
// Check if window has been minimized (or lost focus)
bool IsWindowMinimized(void)
{
-#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) || defined(PLATFORM_UWP)
return windowMinimized;
#else
return false;
@@ -680,7 +721,7 @@ void SetWindowMonitor(int monitor)
if ((monitor >= 0) && (monitor < monitorCount))
{
- glfwSetWindowMonitor(window, monitors[monitor], 0, 0, screenWidth, screenHeight, GLFW_DONT_CARE);
+ //glfwSetWindowMonitor(window, monitors[monitor], 0, 0, screenWidth, screenHeight, GLFW_DONT_CARE);
TraceLog(LOG_INFO, "Selected fullscreen monitor: [%i] %s", monitor, glfwGetMonitorName(monitors[monitor]));
}
else TraceLog(LOG_WARNING, "Selected monitor not found");
@@ -696,6 +737,15 @@ void SetWindowMinSize(int width, int height)
#endif
}
+// Set window dimensions
+void SetWindowSize(int width, int height)
+{
+#if defined(PLATFORM_DESKTOP)
+ glfwSetWindowSize(window, width, height);
+#endif
+}
+
+
// Get current screen width
int GetScreenWidth(void)
{
@@ -708,16 +758,11 @@ int GetScreenHeight(void)
return screenHeight;
}
-#if !defined(PLATFORM_ANDROID)
// Show mouse cursor
void ShowCursor()
{
#if defined(PLATFORM_DESKTOP)
- #if defined(__linux__)
- XUndefineCursor(glfwGetX11Display(), glfwGetX11Window(window));
- #else
- glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
- #endif
+ glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
#endif
cursorHidden = false;
}
@@ -726,18 +771,7 @@ void ShowCursor()
void HideCursor()
{
#if defined(PLATFORM_DESKTOP)
- #if defined(__linux__)
- XColor col;
- const char nil[] = {0};
-
- Pixmap pix = XCreateBitmapFromData(glfwGetX11Display(), glfwGetX11Window(window), nil, 1, 1);
- Cursor cur = XCreatePixmapCursor(glfwGetX11Display(), pix, pix, &col, &col, 0, 0);
-
- XDefineCursor(glfwGetX11Display(), glfwGetX11Window(window), cur);
- XFreeCursor(glfwGetX11Display(), cur);
- #else
- glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
- #endif
+ glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
#endif
cursorHidden = true;
}
@@ -771,23 +805,21 @@ void DisableCursor()
#endif
cursorHidden = true;
}
-#endif // !defined(PLATFORM_ANDROID)
// Set background color (framebuffer clear color)
void ClearBackground(Color color)
{
- // Clear full framebuffer (not only render area) to color
- rlClearColor(color.r, color.g, color.b, color.a);
+ rlClearColor(color.r, color.g, color.b, color.a); // Set clear color
+ rlClearScreenBuffers(); // Clear current framebuffers
}
// Setup canvas (framebuffer) to start drawing
void BeginDrawing(void)
{
- currentTime = GetTime(); // Number of elapsed seconds since InitTimer() was called
+ currentTime = GetTime(); // Number of elapsed seconds since InitTimer()
updateTime = currentTime - previousTime;
previousTime = currentTime;
- rlClearScreenBuffers(); // Clear current framebuffers
rlLoadIdentity(); // Reset current matrix (MODELVIEW)
rlMultMatrixf(MatrixToFloat(downscaleView)); // If downscale required, apply it here
@@ -887,13 +919,26 @@ void Begin3dMode(Camera camera)
rlPushMatrix(); // Save previous matrix, which contains the settings for the 2d ortho projection
rlLoadIdentity(); // Reset current matrix (PROJECTION)
- // Setup perspective projection
float aspect = (float)screenWidth/(float)screenHeight;
- double top = 0.01*tan(camera.fovy*0.5*DEG2RAD);
- double right = top*aspect;
+
+ if (camera.type == CAMERA_PERSPECTIVE)
+ {
+ // Setup perspective projection
+ double top = 0.01*tan(camera.fovy*0.5*DEG2RAD);
+ double right = top*aspect;
+
+ rlFrustum(-right, right, -top, top, 0.01, 1000.0);
+ }
+ else if (camera.type == CAMERA_ORTHOGRAPHIC)
+ {
+ // Setup orthographic projection
+ double top = camera.fovy/2.0;
+ double right = top*aspect;
+
+ rlOrtho(-right,right,-top,top, 0.01, 1000.0);
+ }
// NOTE: zNear and zFar values are important when computing depth buffer values
- rlFrustum(-right, right, -top, top, 0.01, 1000.0);
rlMatrixMode(RL_MODELVIEW); // Switch back to modelview matrix
rlLoadIdentity(); // Reset current matrix (MODELVIEW)
@@ -925,7 +970,7 @@ void BeginTextureMode(RenderTexture2D target)
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2)
rlEnableRenderTexture(target.id); // Enable render target
-
+
rlClearScreenBuffers(); // Clear render texture buffers
// Set viewport to framebuffer size
@@ -981,22 +1026,41 @@ Ray GetMouseRay(Vector2 mousePosition, Camera camera)
TraceLog(LOG_DEBUG, "Device coordinates: (%f, %f, %f)", deviceCoords.x, deviceCoords.y, deviceCoords.z);
- // Calculate projection matrix from perspective
- Matrix matProj = MatrixPerspective(camera.fovy*DEG2RAD, ((double)GetScreenWidth()/(double)GetScreenHeight()), 0.01, 1000.0);
-
// Calculate view matrix from camera look at
Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up);
+ Matrix matProj;
+
+ if (camera.type == CAMERA_PERSPECTIVE)
+ {
+ // Calculate projection matrix from perspective
+ matProj = MatrixPerspective(camera.fovy*DEG2RAD, ((double)GetScreenWidth()/(double)GetScreenHeight()), 0.01, 1000.0);
+ }
+ else if (camera.type == CAMERA_ORTHOGRAPHIC)
+ {
+ float aspect = (float)screenWidth/(float)screenHeight;
+ double top = camera.fovy/2.0;
+ double right = top*aspect;
+ // Calculate projection matrix from orthographic
+ matProj = MatrixOrtho(-right, right, -top, top, 0.01, 1000.0);
+ }
+
// Unproject far/near points
Vector3 nearPoint = rlUnproject((Vector3){ deviceCoords.x, deviceCoords.y, 0.0f }, matProj, matView);
Vector3 farPoint = rlUnproject((Vector3){ deviceCoords.x, deviceCoords.y, 1.0f }, matProj, matView);
+ // Unproject the mouse cursor in the near plane.
+ // We need this as the source position because orthographic projects, compared to perspect doesn't have a
+ // convergence point, meaning that the "eye" of the camera is more like a plane than a point.
+ Vector3 cameraPlanePointerPos = rlUnproject((Vector3){ deviceCoords.x, deviceCoords.y, -1.0f }, matProj, matView);
+
// Calculate normalized direction vector
- Vector3 direction = Vector3Subtract(farPoint, nearPoint);
- Vector3Normalize(&direction);
+ Vector3 direction = Vector3Normalize(Vector3Subtract(farPoint, nearPoint));
+
+ if (camera.type == CAMERA_PERSPECTIVE) ray.position = camera.position;
+ else if (camera.type == CAMERA_ORTHOGRAPHIC) ray.position = cameraPlanePointerPos;
// Apply calculated vectors to ray
- ray.position = camera.position;
ray.direction = direction;
return ray;
@@ -1006,7 +1070,21 @@ Ray GetMouseRay(Vector2 mousePosition, Camera camera)
Vector2 GetWorldToScreen(Vector3 position, Camera camera)
{
// Calculate projection matrix (from perspective instead of frustum
- Matrix matProj = MatrixPerspective(camera.fovy*DEG2RAD, (double)GetScreenWidth()/(double)GetScreenHeight(), 0.01, 1000.0);
+ Matrix matProj;
+
+ if(camera.type == CAMERA_PERSPECTIVE)
+ {
+ // Calculate projection matrix from perspective
+ matProj = MatrixPerspective(camera.fovy*DEG2RAD, ((double)GetScreenWidth()/(double)GetScreenHeight()), 0.01, 1000.0);
+ }
+ else if(camera.type == CAMERA_ORTHOGRAPHIC)
+ {
+ float aspect = (float)screenWidth/(float)screenHeight;
+ double top = camera.fovy/2.0;
+ double right = top*aspect;
+ // Calculate projection matrix from orthographic
+ matProj = MatrixOrtho(-right, right, -top, top, 0.01, 1000.0);
+ }
// Calculate view matrix from camera look at (and transpose it)
Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up);
@@ -1015,10 +1093,10 @@ Vector2 GetWorldToScreen(Vector3 position, Camera camera)
Quaternion worldPos = { position.x, position.y, position.z, 1.0f };
// Transform world position to view
- QuaternionTransform(&worldPos, matView);
+ worldPos = QuaternionTransform(worldPos, matView);
// Transform result to projection (clip space position)
- QuaternionTransform(&worldPos, matProj);
+ worldPos = QuaternionTransform(worldPos, matProj);
// Calculate normalized device coordinates (inverted y)
Vector3 ndcPos = { worldPos.x/worldPos.w, -worldPos.y/worldPos.w, worldPos.z/worldPos.w };
@@ -1057,7 +1135,25 @@ float GetFrameTime(void)
return (float)frameTime;
}
-// Converts Color to float array and normalizes
+// Get elapsed time measure in seconds since InitTimer()
+// NOTE: On PLATFORM_DESKTOP InitTimer() is called on InitWindow()
+// NOTE: On PLATFORM_DESKTOP, timer is initialized on glfwInit()
+double GetTime(void)
+{
+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
+ return glfwGetTime(); // Elapsed time since glfwInit()
+#endif
+
+#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
+ struct timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ uint64_t time = (uint64_t)ts.tv_sec*1000000000LLU + (uint64_t)ts.tv_nsec;
+
+ return (double)(time - baseTime)*1e-9; // Elapsed time since InitTimer()
+#endif
+}
+
+// Returns normalized float array for a Color
float *ColorToFloat(Color color)
{
static float buffer[4];
@@ -1070,6 +1166,64 @@ float *ColorToFloat(Color color)
return buffer;
}
+// Returns hexadecimal value for a Color
+int ColorToInt(Color color)
+{
+ return (((int)color.r << 24) | ((int)color.g << 16) | ((int)color.b << 8) | (int)color.a);
+}
+
+// Returns HSV values for a Color
+// NOTE: Hue is returned as degrees [0..360]
+Vector3 ColorToHSV(Color color)
+{
+ Vector3 rgb = { (float)color.r/255.0f, (float)color.g/255.0f, (float)color.b/255.0f };
+ Vector3 hsv = { 0.0f, 0.0f, 0.0f };
+ float min, max, delta;
+
+ min = rgb.x < rgb.y ? rgb.x : rgb.y;
+ min = min < rgb.z ? min : rgb.z;
+
+ max = rgb.x > rgb.y ? rgb.x : rgb.y;
+ max = max > rgb.z ? max : rgb.z;
+
+ hsv.z = max; // Value
+ delta = max - min;
+
+ if (delta < 0.00001f)
+ {
+ hsv.y = 0.0f;
+ hsv.x = 0.0f; // Undefined, maybe NAN?
+ return hsv;
+ }
+
+ if (max > 0.0f)
+ {
+ // NOTE: If max is 0, this divide would cause a crash
+ hsv.y = (delta/max); // Saturation
+ }
+ else
+ {
+ // NOTE: If max is 0, then r = g = b = 0, s = 0, h is undefined
+ hsv.y = 0.0f;
+ hsv.x = NAN; // Undefined
+ return hsv;
+ }
+
+ // NOTE: Comparing float values could not work properly
+ if (rgb.x >= max) hsv.x = (rgb.y - rgb.z)/delta; // Between yellow & magenta
+ else
+ {
+ if (rgb.y >= max) hsv.x = 2.0f + (rgb.z - rgb.x)/delta; // Between cyan & yellow
+ else hsv.x = 4.0f + (rgb.x - rgb.y)/delta; // Between magenta & cyan
+ }
+
+ hsv.x *= 60.0f; // Convert to degrees
+
+ if (hsv.x < 0.0f) hsv.x += 360.0f;
+
+ return hsv;
+}
+
// Returns a Color struct from hexadecimal value
Color GetColor(int hexValue)
{
@@ -1083,11 +1237,7 @@ Color GetColor(int hexValue)
return color;
}
-// Returns hexadecimal value for a Color
-int GetHexValue(Color color)
-{
- return (((int)color.r << 24) | ((int)color.g << 16) | ((int)color.b << 8) | (int)color.a);
-}
+
// Returns a random value between min and max (both included)
int GetRandomValue(int min, int max)
@@ -1108,9 +1258,7 @@ Color Fade(Color color, float alpha)
if (alpha < 0.0f) alpha = 0.0f;
else if (alpha > 1.0f) alpha = 1.0f;
- float colorAlpha = (float)color.a*alpha;
-
- return (Color){color.r, color.g, color.b, (unsigned char)colorAlpha};
+ return (Color){color.r, color.g, color.b, (unsigned char)(255.0f*alpha)};
}
// Activate raylib logo at startup (can be done with flags)
@@ -1120,7 +1268,7 @@ void ShowLogo(void)
}
// Setup window configuration flags (view FLAGS)
-void SetConfigFlags(char flags)
+void SetConfigFlags(unsigned char flags)
{
configFlags = flags;
@@ -1147,25 +1295,53 @@ bool IsFileExtension(const char *fileName, const char *ext)
{
bool result = false;
const char *fileExt;
-
+
if ((fileExt = strrchr(fileName, '.')) != NULL)
{
+ #if defined(_WIN32)
+ result = true;
+ int extLen = strlen(ext);
+
+ if (strlen(fileExt) == extLen)
+ {
+ for (int i = 0; i < extLen; i++)
+ {
+ if (tolower(fileExt[i]) != tolower(ext[i]))
+ {
+ result = false;
+ break;
+ }
+ }
+ }
+ #else
if (strcmp(fileExt, ext) == 0) result = true;
+ #endif
}
return result;
}
-// Get the extension for a filename
+// Get pointer to extension for a filename string
const char *GetExtension(const char *fileName)
{
const char *dot = strrchr(fileName, '.');
- if (!dot || dot == fileName) return "";
+ if (!dot || dot == fileName) return NULL;
return (dot + 1);
}
+// Get pointer to filename for a path string
+const char *GetFileName(const char *filePath)
+{
+ const char *fileName = strrchr(filePath, '\\');
+
+ if (!fileName || fileName == filePath) return filePath;
+
+ return fileName + 1;
+}
+
+
// Get directory for a given fileName (with path)
const char *GetDirectoryPath(const char *fileName)
{
@@ -1545,7 +1721,7 @@ int GetMouseX(void)
#if defined(PLATFORM_ANDROID)
return (int)touchPosition[0].x;
#else
- return (int)mousePosition.x;
+ return (int)(mousePosition.x*mouseScale);
#endif
}
@@ -1555,7 +1731,7 @@ int GetMouseY(void)
#if defined(PLATFORM_ANDROID)
return (int)touchPosition[0].x;
#else
- return (int)mousePosition.y;
+ return (int)(mousePosition.y*mouseScale);
#endif
}
@@ -1565,7 +1741,7 @@ Vector2 GetMousePosition(void)
#if defined(PLATFORM_ANDROID)
return GetTouchPosition(0);
#else
- return mousePosition;
+ return (Vector2){ mousePosition.x*mouseScale, mousePosition.y*mouseScale };
#endif
}
@@ -1579,6 +1755,15 @@ void SetMousePosition(Vector2 position)
#endif
}
+// Set mouse scaling
+// NOTE: Useful when rendering to different size targets
+void SetMouseScale(float scale)
+{
+#if !defined(PLATFORM_ANDROID)
+ mouseScale = scale;
+#endif
+}
+
// Returns mouse wheel movement Y
int GetMouseWheelMove(void)
{
@@ -1646,7 +1831,8 @@ Vector2 GetTouchPosition(int index)
// Initialize display device and framebuffer
// NOTE: width and height represent the screen (framebuffer) desired size, not actual display size
// If width or height are 0, default display size will be used for framebuffer size
-static void InitGraphicsDevice(int width, int height)
+// NOTE: returns false in case graphic device could not be created
+static bool InitGraphicsDevice(int width, int height)
{
screenWidth = width; // User desired width
screenHeight = height; // User desired height
@@ -1660,12 +1846,22 @@ static void InitGraphicsDevice(int width, int height)
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
glfwSetErrorCallback(ErrorCallback);
- if (!glfwInit()) TraceLog(LOG_ERROR, "Failed to initialize GLFW");
+ if (!glfwInit())
+ {
+ TraceLog(LOG_WARNING, "Failed to initialize GLFW");
+ return false;
+ }
// NOTE: Getting video modes is not implemented in emscripten GLFW3 version
#if defined(PLATFORM_DESKTOP)
// Find monitor resolution
- const GLFWvidmode *mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
+ GLFWmonitor *monitor = glfwGetPrimaryMonitor();
+ if (!monitor)
+ {
+ TraceLog(LOG_WARNING, "Failed to get monitor");
+ return false;
+ }
+ const GLFWvidmode *mode = glfwGetVideoMode(monitor);
displayWidth = mode->width;
displayHeight = mode->height;
@@ -1771,24 +1967,28 @@ static void InitGraphicsDevice(int width, int height)
// No-fullscreen window creation
window = glfwCreateWindow(screenWidth, screenHeight, windowTitle, NULL, NULL);
+ if (window)
+ {
#if defined(PLATFORM_DESKTOP)
- // Center window on screen
- int windowPosX = displayWidth/2 - screenWidth/2;
- int windowPosY = displayHeight/2 - screenHeight/2;
+ // Center window on screen
+ int windowPosX = displayWidth/2 - screenWidth/2;
+ int windowPosY = displayHeight/2 - screenHeight/2;
- if (windowPosX < 0) windowPosX = 0;
- if (windowPosY < 0) windowPosY = 0;
+ if (windowPosX < 0) windowPosX = 0;
+ if (windowPosY < 0) windowPosY = 0;
- glfwSetWindowPos(window, windowPosX, windowPosY);
+ glfwSetWindowPos(window, windowPosX, windowPosY);
#endif
- renderWidth = screenWidth;
- renderHeight = screenHeight;
+ renderWidth = screenWidth;
+ renderHeight = screenHeight;
+ }
}
if (!window)
{
glfwTerminate();
- TraceLog(LOG_ERROR, "GLFW Failed to initialize Window");
+ TraceLog(LOG_WARNING, "GLFW Failed to initialize Window");
+ return false;
}
else
{
@@ -1834,7 +2034,7 @@ static void InitGraphicsDevice(int width, int height)
}
#endif // defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
-#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
+#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_UWP)
fullscreen = true;
// Screen size security check
@@ -1877,19 +2077,194 @@ static void InitGraphicsDevice(int width, int height)
EGL_NONE
};
- EGLint contextAttribs[] =
+ const EGLint contextAttribs[] =
{
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
+#if defined(PLATFORM_UWP)
+ const EGLint surfaceAttributes[] =
+ {
+ // EGL_ANGLE_SURFACE_RENDER_TO_BACK_BUFFER is part of the same optimization as EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER (see above).
+ // If you have compilation issues with it then please update your Visual Studio templates.
+ EGL_ANGLE_SURFACE_RENDER_TO_BACK_BUFFER, EGL_TRUE,
+ EGL_NONE
+ };
+
+ const EGLint defaultDisplayAttributes[] =
+ {
+ // These are the default display attributes, used to request ANGLE's D3D11 renderer.
+ // eglInitialize will only succeed with these attributes if the hardware supports D3D11 Feature Level 10_0+.
+ EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
+
+ // EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER is an optimization that can have large performance benefits on mobile devices.
+ // Its syntax is subject to change, though. Please update your Visual Studio templates if you experience compilation issues with it.
+ EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE,
+
+ // EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE is an option that enables ANGLE to automatically call
+ // the IDXGIDevice3::Trim method on behalf of the application when it gets suspended.
+ // Calling IDXGIDevice3::Trim when an application is suspended is a Windows Store application certification requirement.
+ EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE,
+ EGL_NONE,
+ };
+
+ const EGLint fl9_3DisplayAttributes[] =
+ {
+ // These can be used to request ANGLE's D3D11 renderer, with D3D11 Feature Level 9_3.
+ // These attributes are used if the call to eglInitialize fails with the default display attributes.
+ EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
+ EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, 9,
+ EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, 3,
+ EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE,
+ EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE,
+ EGL_NONE,
+ };
+
+ const EGLint warpDisplayAttributes[] =
+ {
+ // These attributes can be used to request D3D11 WARP.
+ // They are used if eglInitialize fails with both the default display attributes and the 9_3 display attributes.
+ EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
+ EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE,
+ EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE,
+ EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE,
+ EGL_NONE,
+ };
+
+ EGLConfig config = NULL;
+
+ // eglGetPlatformDisplayEXT is an alternative to eglGetDisplay. It allows us to pass in display attributes, used to configure D3D11.
+ PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)(eglGetProcAddress("eglGetPlatformDisplayEXT"));
+ if (!eglGetPlatformDisplayEXT)
+ {
+ TraceLog(LOG_WARNING, "Failed to get function eglGetPlatformDisplayEXT");
+ return false;
+ }
+
+ //
+ // To initialize the display, we make three sets of calls to eglGetPlatformDisplayEXT and eglInitialize, with varying
+ // parameters passed to eglGetPlatformDisplayEXT:
+ // 1) The first calls uses "defaultDisplayAttributes" as a parameter. This corresponds to D3D11 Feature Level 10_0+.
+ // 2) If eglInitialize fails for step 1 (e.g. because 10_0+ isn't supported by the default GPU), then we try again
+ // using "fl9_3DisplayAttributes". This corresponds to D3D11 Feature Level 9_3.
+ // 3) If eglInitialize fails for step 2 (e.g. because 9_3+ isn't supported by the default GPU), then we try again
+ // using "warpDisplayAttributes". This corresponds to D3D11 Feature Level 11_0 on WARP, a D3D11 software rasterizer.
+ //
+
+ // This tries to initialize EGL to D3D11 Feature Level 10_0+. See above comment for details.
+ display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, defaultDisplayAttributes);
+ if (display == EGL_NO_DISPLAY)
+ {
+ TraceLog(LOG_WARNING, "Failed to initialize EGL display");
+ return false;
+ }
+
+ if (eglInitialize(display, NULL, NULL) == EGL_FALSE)
+ {
+ // This tries to initialize EGL to D3D11 Feature Level 9_3, if 10_0+ is unavailable (e.g. on some mobile devices).
+ display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, fl9_3DisplayAttributes);
+ if (display == EGL_NO_DISPLAY)
+ {
+ TraceLog(LOG_WARNING, "Failed to initialize EGL display");
+ return false;
+ }
+
+ if (eglInitialize(display, NULL, NULL) == EGL_FALSE)
+ {
+ // This initializes EGL to D3D11 Feature Level 11_0 on WARP, if 9_3+ is unavailable on the default GPU.
+ display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, warpDisplayAttributes);
+ if (display == EGL_NO_DISPLAY)
+ {
+ TraceLog(LOG_WARNING, "Failed to initialize EGL display");
+ return false;
+ }
+
+ if (eglInitialize(display, NULL, NULL) == EGL_FALSE)
+ {
+ // If all of the calls to eglInitialize returned EGL_FALSE then an error has occurred.
+ TraceLog(LOG_WARNING, "Failed to initialize EGL");
+ return false;
+ }
+ }
+ }
+
+ //SetupFramebufferSize(displayWidth, displayHeight);
+
+ EGLint numConfigs = 0;
+ if ((eglChooseConfig(display, framebufferAttribs, &config, 1, &numConfigs) == EGL_FALSE) || (numConfigs == 0))
+ {
+ TraceLog(LOG_WARNING, "Failed to choose first EGLConfig");
+ return false;
+ }
+
+ // Create a PropertySet and initialize with the EGLNativeWindowType.
+ //PropertySet^ surfaceCreationProperties = ref new PropertySet();
+ //surfaceCreationProperties->Insert(ref new String(EGLNativeWindowTypeProperty), window); // CoreWindow^ window
+
+ // You can configure the surface to render at a lower resolution and be scaled up to
+ // the full window size. The scaling is often free on mobile hardware.
+ //
+ // One way to configure the SwapChainPanel is to specify precisely which resolution it should render at.
+ // Size customRenderSurfaceSize = Size(800, 600);
+ // surfaceCreationProperties->Insert(ref new String(EGLRenderSurfaceSizeProperty), PropertyValue::CreateSize(customRenderSurfaceSize));
+ //
+ // Another way is to tell the SwapChainPanel to render at a certain scale factor compared to its size.
+ // e.g. if the SwapChainPanel is 1920x1280 then setting a factor of 0.5f will make the app render at 960x640
+ // float customResolutionScale = 0.5f;
+ // surfaceCreationProperties->Insert(ref new String(EGLRenderResolutionScaleProperty), PropertyValue::CreateSingle(customResolutionScale));
+
+
+ // eglCreateWindowSurface() requires a EGLNativeWindowType parameter,
+ // In Windows platform: typedef HWND EGLNativeWindowType;
+
+
+ // Property: EGLNativeWindowTypeProperty
+ // Type: IInspectable
+ // Description: Set this property to specify the window type to use for creating a surface.
+ // If this property is missing, surface creation will fail.
+ //
+ //const wchar_t EGLNativeWindowTypeProperty[] = L"EGLNativeWindowTypeProperty";
+
+ //https://stackoverflow.com/questions/46550182/how-to-create-eglsurface-using-c-winrt-and-angle
+
+ //surface = eglCreateWindowSurface(display, config, reinterpret_cast(surfaceCreationProperties), surfaceAttributes);
+ surface = eglCreateWindowSurface(display, config, uwpWindow, surfaceAttributes);
+ if (surface == EGL_NO_SURFACE)
+ {
+ TraceLog(LOG_WARNING, "Failed to create EGL fullscreen surface");
+ return false;
+ }
+
+ context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);
+ if (context == EGL_NO_CONTEXT)
+ {
+ TraceLog(LOG_WARNING, "Failed to create EGL context");
+ return false;
+ }
+
+ // Get EGL display window size
+ eglQuerySurface(display, surface, EGL_WIDTH, &screenWidth);
+ eglQuerySurface(display, surface, EGL_HEIGHT, &screenHeight);
+
+#else // PLATFORM_ANDROID, PLATFORM_RPI
EGLint numConfigs;
// Get an EGL display connection
display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ if (display == EGL_NO_DISPLAY)
+ {
+ TraceLog(LOG_WARNING, "Failed to initialize EGL display");
+ return false;
+ }
// Initialize the EGL display connection
- eglInitialize(display, NULL, NULL);
+ if (eglInitialize(display, NULL, NULL) == EGL_FALSE)
+ {
+ // If all of the calls to eglInitialize returned EGL_FALSE then an error has occurred.
+ TraceLog(LOG_WARNING, "Failed to initialize EGL");
+ return false;
+ }
// Get an appropriate EGL framebuffer configuration
eglChooseConfig(display, framebufferAttribs, &config, 1, &numConfigs);
@@ -1899,14 +2274,20 @@ static void InitGraphicsDevice(int width, int height)
// Create an EGL rendering context
context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);
+ if (context == EGL_NO_CONTEXT)
+ {
+ TraceLog(LOG_WARNING, "Failed to create EGL context");
+ return false;
+ }
+#endif
// Create an EGL window surface
//---------------------------------------------------------------------------------
#if defined(PLATFORM_ANDROID)
EGLint displayFormat;
- displayWidth = ANativeWindow_getWidth(app->window);
- displayHeight = ANativeWindow_getHeight(app->window);
+ displayWidth = ANativeWindow_getWidth(androidApp->window);
+ displayHeight = ANativeWindow_getHeight(androidApp->window);
// EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is guaranteed to be accepted by ANativeWindow_setBuffersGeometry()
// As soon as we picked a EGLConfig, we can safely reconfigure the ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID
@@ -1916,10 +2297,10 @@ static void InitGraphicsDevice(int width, int height)
// NOTE: This function use and modify global module variables: screenWidth/screenHeight and renderWidth/renderHeight and downscaleView
SetupFramebufferSize(displayWidth, displayHeight);
- ANativeWindow_setBuffersGeometry(app->window, renderWidth, renderHeight, displayFormat);
- //ANativeWindow_setBuffersGeometry(app->window, 0, 0, displayFormat); // Force use of native display size
+ ANativeWindow_setBuffersGeometry(androidApp->window, renderWidth, renderHeight, displayFormat);
+ //ANativeWindow_setBuffersGeometry(androidApp->window, 0, 0, displayFormat); // Force use of native display size
- surface = eglCreateWindowSurface(display, config, app->window, NULL);
+ surface = eglCreateWindowSurface(display, config, androidApp->window, NULL);
#endif // defined(PLATFORM_ANDROID)
#if defined(PLATFORM_RPI)
@@ -1966,7 +2347,8 @@ static void InitGraphicsDevice(int width, int height)
if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE)
{
- TraceLog(LOG_ERROR, "Unable to attach EGL rendering context to EGL surface");
+ TraceLog(LOG_WARNING, "Unable to attach EGL rendering context to EGL surface");
+ return false;
}
else
{
@@ -1982,6 +2364,9 @@ static void InitGraphicsDevice(int width, int height)
}
#endif // defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
+ renderWidth = screenWidth;
+ renderHeight = screenHeight;
+
// Initialize OpenGL context (states and resources)
// NOTE: screenWidth and screenHeight not used, just stored as globals
rlglInit(screenWidth, screenHeight);
@@ -2002,6 +2387,7 @@ static void InitGraphicsDevice(int width, int height)
#if defined(PLATFORM_ANDROID)
windowReady = true; // IMPORTANT!
#endif
+ return true;
}
// Set viewport parameters
@@ -2117,22 +2503,6 @@ static void InitTimer(void)
previousTime = GetTime(); // Get time as double
}
-// Get current time measure (in seconds) since InitTimer()
-static double GetTime(void)
-{
-#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
- return glfwGetTime();
-#endif
-
-#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
- struct timespec ts;
- clock_gettime(CLOCK_MONOTONIC, &ts);
- uint64_t time = (uint64_t)ts.tv_sec*1000000000LLU + (uint64_t)ts.tv_nsec;
-
- return (double)(time - baseTime)*1e-9;
-#endif
-}
-
// Wait for some milliseconds (stop program execution)
// NOTE: Sleep() granularity could be around 10 ms, it means, Sleep() could
// take longer than expected... for that reason we use the busy wait loop
@@ -2336,14 +2706,14 @@ static void PollInputEvents(void)
while ((ident = ALooper_pollAll(appEnabled ? 0 : -1, NULL, &events,(void**)&source)) >= 0)
{
// Process this event
- if (source != NULL) source->process(app, source);
+ if (source != NULL) source->process(androidApp, source);
// NOTE: Never close window, native activity is controlled by the system!
- if (app->destroyRequested != 0)
+ if (androidApp->destroyRequested != 0)
{
//TraceLog(LOG_INFO, "Closing Window...");
//windowShouldClose = true;
- //ANativeActivity_finish(app->activity);
+ //ANativeActivity_finish(androidApp->activity);
}
}
#endif
@@ -2366,7 +2736,7 @@ static void SwapBuffers(void)
glfwSwapBuffers(window);
#endif
-#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
+#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_UWP)
eglSwapBuffers(display, surface);
#endif
}
@@ -2430,7 +2800,9 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i
else
{
currentKeyState[key] = action;
- if (action == GLFW_PRESS) lastKeyPressed = key;
+
+ // NOTE: lastKeyPressed already registered on CharCallback()
+ //if (action == GLFW_PRESS) lastKeyPressed = key;
}
}
@@ -2496,12 +2868,15 @@ static void MouseCursorPosCallback(GLFWwindow *window, double x, double y)
#endif
}
-// GLFW3 Char Key Callback, runs on key pressed (get char value)
+// GLFW3 Char Key Callback, runs on key down (get unicode char value)
static void CharCallback(GLFWwindow *window, unsigned int key)
-{
+{
+ // NOTE: Registers any key down considering OS keyboard layout but
+ // do not detects action events, those should be managed by user...
+ // https://github.com/glfw/glfw/issues/668#issuecomment-166794907
+ // http://www.glfw.org/docs/latest/input_guide.html#input_char
+
lastKeyPressed = key;
-
- //TraceLog(LOG_INFO, "Char Callback Key pressed: %i\n", key);
}
// GLFW3 CursorEnter Callback, when cursor enters the window
@@ -2525,6 +2900,8 @@ static void WindowSizeCallback(GLFWwindow *window, int width, int height)
rlClearScreenBuffers(); // Clear screen buffers (color and depth)
// Window size must be updated to be used on 3D mode to get new aspect ratio (Begin3dMode())
+ // NOTE: Be careful! GLFW3 will choose the closest fullscreen resolution supported by current monitor,
+ // for example, if reescaling back to 800x450 (desired), it could set 720x480 (closest fullscreen supported)
screenWidth = width;
screenHeight = height;
renderWidth = width;
@@ -2599,6 +2976,9 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
{
// Init graphics device (display device and OpenGL context)
InitGraphicsDevice(screenWidth, screenHeight);
+
+ // Init hi-res timer
+ InitTimer();
#if defined(SUPPORT_DEFAULT_FONT)
// Load default font
@@ -2621,9 +3001,6 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
}
*/
- // Init hi-res timer
- InitTimer();
-
// raylib logo appearing animation (if enabled)
if (showLogo)
{
@@ -2673,14 +3050,14 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
case APP_CMD_DESTROY:
{
// TODO: Finish activity?
- //ANativeActivity_finish(app->activity);
+ //ANativeActivity_finish(androidApp->activity);
TraceLog(LOG_INFO, "APP_CMD_DESTROY");
} break;
case APP_CMD_CONFIG_CHANGED:
{
- //AConfiguration_fromAssetManager(app->config, app->activity->assetManager);
- //print_cur_config(app);
+ //AConfiguration_fromAssetManager(androidApp->config, androidApp->activity->assetManager);
+ //print_cur_config(androidApp);
// Check screen orientation here!
@@ -2776,8 +3153,16 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
ProcessGestureEvent(gestureEvent);
#else
- // TODO: Support only simple touch position
-
+ // Support only simple touch position
+ if (flags == AMOTION_EVENT_ACTION_DOWN)
+ {
+ // Get first touch position
+ touchPosition[0].x = AMotionEvent_getX(event, 0);
+ touchPosition[0].y = AMotionEvent_getY(event, 0);
+
+ touchPosition[0].x /= (float)GetScreenWidth();
+ touchPosition[0].y /= (float)GetScreenHeight();
+ }
#endif
return 0;
diff --git a/src/external/ANGLE/EGL/egl.h b/src/external/ANGLE/EGL/egl.h
new file mode 100644
index 000000000..5a2729121
--- /dev/null
+++ b/src/external/ANGLE/EGL/egl.h
@@ -0,0 +1,303 @@
+#ifndef __egl_h_
+#define __egl_h_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright (c) 2013-2014 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+/*
+** This header is generated from the Khronos OpenGL / OpenGL ES XML
+** API Registry. The current version of the Registry, generator scripts
+** used to make the header, and the header can be found at
+** http://www.opengl.org/registry/
+**
+** Khronos $Revision: 29318 $ on $Date: 2015-01-02 03:16:10 -0800 (Fri, 02 Jan 2015) $
+*/
+
+#include
+
+/* Generated on date 20150102 */
+
+/* Generated C header for:
+ * API: egl
+ * Versions considered: .*
+ * Versions emitted: .*
+ * Default extensions included: None
+ * Additional extensions included: _nomatch_^
+ * Extensions removed: _nomatch_^
+ */
+
+#ifndef EGL_VERSION_1_0
+#define EGL_VERSION_1_0 1
+typedef unsigned int EGLBoolean;
+typedef void *EGLDisplay;
+#include
+#include
+typedef void *EGLConfig;
+typedef void *EGLSurface;
+typedef void *EGLContext;
+typedef void (*__eglMustCastToProperFunctionPointerType)(void);
+#define EGL_ALPHA_SIZE 0x3021
+#define EGL_BAD_ACCESS 0x3002
+#define EGL_BAD_ALLOC 0x3003
+#define EGL_BAD_ATTRIBUTE 0x3004
+#define EGL_BAD_CONFIG 0x3005
+#define EGL_BAD_CONTEXT 0x3006
+#define EGL_BAD_CURRENT_SURFACE 0x3007
+#define EGL_BAD_DISPLAY 0x3008
+#define EGL_BAD_MATCH 0x3009
+#define EGL_BAD_NATIVE_PIXMAP 0x300A
+#define EGL_BAD_NATIVE_WINDOW 0x300B
+#define EGL_BAD_PARAMETER 0x300C
+#define EGL_BAD_SURFACE 0x300D
+#define EGL_BLUE_SIZE 0x3022
+#define EGL_BUFFER_SIZE 0x3020
+#define EGL_CONFIG_CAVEAT 0x3027
+#define EGL_CONFIG_ID 0x3028
+#define EGL_CORE_NATIVE_ENGINE 0x305B
+#define EGL_DEPTH_SIZE 0x3025
+#define EGL_DONT_CARE ((EGLint)-1)
+#define EGL_DRAW 0x3059
+#define EGL_EXTENSIONS 0x3055
+#define EGL_FALSE 0
+#define EGL_GREEN_SIZE 0x3023
+#define EGL_HEIGHT 0x3056
+#define EGL_LARGEST_PBUFFER 0x3058
+#define EGL_LEVEL 0x3029
+#define EGL_MAX_PBUFFER_HEIGHT 0x302A
+#define EGL_MAX_PBUFFER_PIXELS 0x302B
+#define EGL_MAX_PBUFFER_WIDTH 0x302C
+#define EGL_NATIVE_RENDERABLE 0x302D
+#define EGL_NATIVE_VISUAL_ID 0x302E
+#define EGL_NATIVE_VISUAL_TYPE 0x302F
+#define EGL_NONE 0x3038
+#define EGL_NON_CONFORMANT_CONFIG 0x3051
+#define EGL_NOT_INITIALIZED 0x3001
+#define EGL_NO_CONTEXT ((EGLContext)0)
+#define EGL_NO_DISPLAY ((EGLDisplay)0)
+#define EGL_NO_SURFACE ((EGLSurface)0)
+#define EGL_PBUFFER_BIT 0x0001
+#define EGL_PIXMAP_BIT 0x0002
+#define EGL_READ 0x305A
+#define EGL_RED_SIZE 0x3024
+#define EGL_SAMPLES 0x3031
+#define EGL_SAMPLE_BUFFERS 0x3032
+#define EGL_SLOW_CONFIG 0x3050
+#define EGL_STENCIL_SIZE 0x3026
+#define EGL_SUCCESS 0x3000
+#define EGL_SURFACE_TYPE 0x3033
+#define EGL_TRANSPARENT_BLUE_VALUE 0x3035
+#define EGL_TRANSPARENT_GREEN_VALUE 0x3036
+#define EGL_TRANSPARENT_RED_VALUE 0x3037
+#define EGL_TRANSPARENT_RGB 0x3052
+#define EGL_TRANSPARENT_TYPE 0x3034
+#define EGL_TRUE 1
+#define EGL_VENDOR 0x3053
+#define EGL_VERSION 0x3054
+#define EGL_WIDTH 0x3057
+#define EGL_WINDOW_BIT 0x0004
+EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig (EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers (EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target);
+EGLAPI EGLContext EGLAPIENTRY eglCreateContext (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface (EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface (EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface (EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext (EGLDisplay dpy, EGLContext ctx);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface (EGLDisplay dpy, EGLSurface surface);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib (EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs (EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay (void);
+EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface (EGLint readdraw);
+EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay (EGLNativeDisplayType display_id);
+EGLAPI EGLint EGLAPIENTRY eglGetError (void);
+EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress (const char *procname);
+EGLAPI EGLBoolean EGLAPIENTRY eglInitialize (EGLDisplay dpy, EGLint *major, EGLint *minor);
+EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent (EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext (EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value);
+EGLAPI const char *EGLAPIENTRY eglQueryString (EGLDisplay dpy, EGLint name);
+EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers (EGLDisplay dpy, EGLSurface surface);
+EGLAPI EGLBoolean EGLAPIENTRY eglTerminate (EGLDisplay dpy);
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL (void);
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative (EGLint engine);
+#endif /* EGL_VERSION_1_0 */
+
+#ifndef EGL_VERSION_1_1
+#define EGL_VERSION_1_1 1
+#define EGL_BACK_BUFFER 0x3084
+#define EGL_BIND_TO_TEXTURE_RGB 0x3039
+#define EGL_BIND_TO_TEXTURE_RGBA 0x303A
+#define EGL_CONTEXT_LOST 0x300E
+#define EGL_MIN_SWAP_INTERVAL 0x303B
+#define EGL_MAX_SWAP_INTERVAL 0x303C
+#define EGL_MIPMAP_TEXTURE 0x3082
+#define EGL_MIPMAP_LEVEL 0x3083
+#define EGL_NO_TEXTURE 0x305C
+#define EGL_TEXTURE_2D 0x305F
+#define EGL_TEXTURE_FORMAT 0x3080
+#define EGL_TEXTURE_RGB 0x305D
+#define EGL_TEXTURE_RGBA 0x305E
+#define EGL_TEXTURE_TARGET 0x3081
+EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval (EGLDisplay dpy, EGLint interval);
+#endif /* EGL_VERSION_1_1 */
+
+#ifndef EGL_VERSION_1_2
+#define EGL_VERSION_1_2 1
+typedef unsigned int EGLenum;
+typedef void *EGLClientBuffer;
+#define EGL_ALPHA_FORMAT 0x3088
+#define EGL_ALPHA_FORMAT_NONPRE 0x308B
+#define EGL_ALPHA_FORMAT_PRE 0x308C
+#define EGL_ALPHA_MASK_SIZE 0x303E
+#define EGL_BUFFER_PRESERVED 0x3094
+#define EGL_BUFFER_DESTROYED 0x3095
+#define EGL_CLIENT_APIS 0x308D
+#define EGL_COLORSPACE 0x3087
+#define EGL_COLORSPACE_sRGB 0x3089
+#define EGL_COLORSPACE_LINEAR 0x308A
+#define EGL_COLOR_BUFFER_TYPE 0x303F
+#define EGL_CONTEXT_CLIENT_TYPE 0x3097
+#define EGL_DISPLAY_SCALING 10000
+#define EGL_HORIZONTAL_RESOLUTION 0x3090
+#define EGL_LUMINANCE_BUFFER 0x308F
+#define EGL_LUMINANCE_SIZE 0x303D
+#define EGL_OPENGL_ES_BIT 0x0001
+#define EGL_OPENVG_BIT 0x0002
+#define EGL_OPENGL_ES_API 0x30A0
+#define EGL_OPENVG_API 0x30A1
+#define EGL_OPENVG_IMAGE 0x3096
+#define EGL_PIXEL_ASPECT_RATIO 0x3092
+#define EGL_RENDERABLE_TYPE 0x3040
+#define EGL_RENDER_BUFFER 0x3086
+#define EGL_RGB_BUFFER 0x308E
+#define EGL_SINGLE_BUFFER 0x3085
+#define EGL_SWAP_BEHAVIOR 0x3093
+#define EGL_UNKNOWN ((EGLint)-1)
+#define EGL_VERTICAL_RESOLUTION 0x3091
+EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI (EGLenum api);
+EGLAPI EGLenum EGLAPIENTRY eglQueryAPI (void);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer (EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread (void);
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient (void);
+#endif /* EGL_VERSION_1_2 */
+
+#ifndef EGL_VERSION_1_3
+#define EGL_VERSION_1_3 1
+#define EGL_CONFORMANT 0x3042
+#define EGL_CONTEXT_CLIENT_VERSION 0x3098
+#define EGL_MATCH_NATIVE_PIXMAP 0x3041
+#define EGL_OPENGL_ES2_BIT 0x0004
+#define EGL_VG_ALPHA_FORMAT 0x3088
+#define EGL_VG_ALPHA_FORMAT_NONPRE 0x308B
+#define EGL_VG_ALPHA_FORMAT_PRE 0x308C
+#define EGL_VG_ALPHA_FORMAT_PRE_BIT 0x0040
+#define EGL_VG_COLORSPACE 0x3087
+#define EGL_VG_COLORSPACE_sRGB 0x3089
+#define EGL_VG_COLORSPACE_LINEAR 0x308A
+#define EGL_VG_COLORSPACE_LINEAR_BIT 0x0020
+#endif /* EGL_VERSION_1_3 */
+
+#ifndef EGL_VERSION_1_4
+#define EGL_VERSION_1_4 1
+#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0)
+#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200
+#define EGL_MULTISAMPLE_RESOLVE 0x3099
+#define EGL_MULTISAMPLE_RESOLVE_DEFAULT 0x309A
+#define EGL_MULTISAMPLE_RESOLVE_BOX 0x309B
+#define EGL_OPENGL_API 0x30A2
+#define EGL_OPENGL_BIT 0x0008
+#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400
+EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext (void);
+#endif /* EGL_VERSION_1_4 */
+
+#ifndef EGL_VERSION_1_5
+#define EGL_VERSION_1_5 1
+typedef void *EGLSync;
+typedef intptr_t EGLAttrib;
+typedef khronos_utime_nanoseconds_t EGLTime;
+typedef void *EGLImage;
+#define EGL_CONTEXT_MAJOR_VERSION 0x3098
+#define EGL_CONTEXT_MINOR_VERSION 0x30FB
+#define EGL_CONTEXT_OPENGL_PROFILE_MASK 0x30FD
+#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY 0x31BD
+#define EGL_NO_RESET_NOTIFICATION 0x31BE
+#define EGL_LOSE_CONTEXT_ON_RESET 0x31BF
+#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT 0x00000001
+#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT 0x00000002
+#define EGL_CONTEXT_OPENGL_DEBUG 0x31B0
+#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE 0x31B1
+#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS 0x31B2
+#define EGL_OPENGL_ES3_BIT 0x00000040
+#define EGL_CL_EVENT_HANDLE 0x309C
+#define EGL_SYNC_CL_EVENT 0x30FE
+#define EGL_SYNC_CL_EVENT_COMPLETE 0x30FF
+#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE 0x30F0
+#define EGL_SYNC_TYPE 0x30F7
+#define EGL_SYNC_STATUS 0x30F1
+#define EGL_SYNC_CONDITION 0x30F8
+#define EGL_SIGNALED 0x30F2
+#define EGL_UNSIGNALED 0x30F3
+#define EGL_SYNC_FLUSH_COMMANDS_BIT 0x0001
+#define EGL_FOREVER 0xFFFFFFFFFFFFFFFFull
+#define EGL_TIMEOUT_EXPIRED 0x30F5
+#define EGL_CONDITION_SATISFIED 0x30F6
+#define EGL_NO_SYNC ((EGLSync)0)
+#define EGL_SYNC_FENCE 0x30F9
+#define EGL_GL_COLORSPACE 0x309D
+#define EGL_GL_COLORSPACE_SRGB 0x3089
+#define EGL_GL_COLORSPACE_LINEAR 0x308A
+#define EGL_GL_RENDERBUFFER 0x30B9
+#define EGL_GL_TEXTURE_2D 0x30B1
+#define EGL_GL_TEXTURE_LEVEL 0x30BC
+#define EGL_GL_TEXTURE_3D 0x30B2
+#define EGL_GL_TEXTURE_ZOFFSET 0x30BD
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x30B3
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x30B4
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x30B5
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x30B6
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x30B7
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x30B8
+#define EGL_IMAGE_PRESERVED 0x30D2
+#define EGL_NO_IMAGE ((EGLImage)0)
+EGLAPI EGLSync EGLAPIENTRY eglCreateSync (EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySync (EGLDisplay dpy, EGLSync sync);
+EGLAPI EGLint EGLAPIENTRY eglClientWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttrib (EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value);
+EGLAPI EGLImage EGLAPIENTRY eglCreateImage (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImage (EGLDisplay dpy, EGLImage image);
+EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplay (EGLenum platform, void *native_display, const EGLAttrib *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurface (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurface (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags);
+#endif /* EGL_VERSION_1_5 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/external/ANGLE/EGL/eglext.h b/src/external/ANGLE/EGL/eglext.h
new file mode 100644
index 000000000..0325ef108
--- /dev/null
+++ b/src/external/ANGLE/EGL/eglext.h
@@ -0,0 +1,780 @@
+#ifndef __eglext_h_
+#define __eglext_h_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright (c) 2013-2014 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+/*
+** This header is generated from the Khronos OpenGL / OpenGL ES XML
+** API Registry. The current version of the Registry, generator scripts
+** used to make the header, and the header can be found at
+** http://www.opengl.org/registry/
+**
+** Khronos $Revision: 27018 $ on $Date: 2014-06-10 08:06:12 -0700 (Tue, 10 Jun 2014) $
+*/
+
+#include
+
+#define EGL_EGLEXT_VERSION 20140610
+
+/* Generated C header for:
+ * API: egl
+ * Versions considered: .*
+ * Versions emitted: _nomatch_^
+ * Default extensions included: egl
+ * Additional extensions included: _nomatch_^
+ * Extensions removed: _nomatch_^
+ */
+
+#ifndef EGL_KHR_cl_event
+#define EGL_KHR_cl_event 1
+#define EGL_CL_EVENT_HANDLE_KHR 0x309C
+#define EGL_SYNC_CL_EVENT_KHR 0x30FE
+#define EGL_SYNC_CL_EVENT_COMPLETE_KHR 0x30FF
+#endif /* EGL_KHR_cl_event */
+
+#ifndef EGL_KHR_cl_event2
+#define EGL_KHR_cl_event2 1
+typedef void *EGLSyncKHR;
+typedef intptr_t EGLAttribKHR;
+typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNC64KHRPROC) (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSync64KHR (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list);
+#endif
+#endif /* EGL_KHR_cl_event2 */
+
+#ifndef EGL_KHR_client_get_all_proc_addresses
+#define EGL_KHR_client_get_all_proc_addresses 1
+#endif /* EGL_KHR_client_get_all_proc_addresses */
+
+#ifndef EGL_KHR_config_attribs
+#define EGL_KHR_config_attribs 1
+#define EGL_CONFORMANT_KHR 0x3042
+#define EGL_VG_COLORSPACE_LINEAR_BIT_KHR 0x0020
+#define EGL_VG_ALPHA_FORMAT_PRE_BIT_KHR 0x0040
+#endif /* EGL_KHR_config_attribs */
+
+#ifndef EGL_KHR_create_context
+#define EGL_KHR_create_context 1
+#define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098
+#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB
+#define EGL_CONTEXT_FLAGS_KHR 0x30FC
+#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30FD
+#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31BD
+#define EGL_NO_RESET_NOTIFICATION_KHR 0x31BE
+#define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31BF
+#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001
+#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002
+#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004
+#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001
+#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002
+#define EGL_OPENGL_ES3_BIT_KHR 0x00000040
+#endif /* EGL_KHR_create_context */
+
+#ifndef EGL_KHR_fence_sync
+#define EGL_KHR_fence_sync 1
+#ifdef KHRONOS_SUPPORT_INT64
+#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR 0x30F0
+#define EGL_SYNC_CONDITION_KHR 0x30F8
+#define EGL_SYNC_FENCE_KHR 0x30F9
+#endif /* KHRONOS_SUPPORT_INT64 */
+#endif /* EGL_KHR_fence_sync */
+
+#ifndef EGL_KHR_get_all_proc_addresses
+#define EGL_KHR_get_all_proc_addresses 1
+#endif /* EGL_KHR_get_all_proc_addresses */
+
+#ifndef EGL_KHR_gl_colorspace
+#define EGL_KHR_gl_colorspace 1
+#define EGL_GL_COLORSPACE_KHR 0x309D
+#define EGL_GL_COLORSPACE_SRGB_KHR 0x3089
+#define EGL_GL_COLORSPACE_LINEAR_KHR 0x308A
+#endif /* EGL_KHR_gl_colorspace */
+
+#ifndef EGL_KHR_gl_renderbuffer_image
+#define EGL_KHR_gl_renderbuffer_image 1
+#define EGL_GL_RENDERBUFFER_KHR 0x30B9
+#endif /* EGL_KHR_gl_renderbuffer_image */
+
+#ifndef EGL_KHR_gl_texture_2D_image
+#define EGL_KHR_gl_texture_2D_image 1
+#define EGL_GL_TEXTURE_2D_KHR 0x30B1
+#define EGL_GL_TEXTURE_LEVEL_KHR 0x30BC
+#endif /* EGL_KHR_gl_texture_2D_image */
+
+#ifndef EGL_KHR_gl_texture_3D_image
+#define EGL_KHR_gl_texture_3D_image 1
+#define EGL_GL_TEXTURE_3D_KHR 0x30B2
+#define EGL_GL_TEXTURE_ZOFFSET_KHR 0x30BD
+#endif /* EGL_KHR_gl_texture_3D_image */
+
+#ifndef EGL_KHR_gl_texture_cubemap_image
+#define EGL_KHR_gl_texture_cubemap_image 1
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR 0x30B3
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR 0x30B4
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR 0x30B5
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR 0x30B6
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR 0x30B7
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR 0x30B8
+#endif /* EGL_KHR_gl_texture_cubemap_image */
+
+#ifndef EGL_KHR_image
+#define EGL_KHR_image 1
+typedef void *EGLImageKHR;
+#define EGL_NATIVE_PIXMAP_KHR 0x30B0
+#define EGL_NO_IMAGE_KHR ((EGLImageKHR)0)
+typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR (EGLDisplay dpy, EGLImageKHR image);
+#endif
+#endif /* EGL_KHR_image */
+
+#ifndef EGL_KHR_image_base
+#define EGL_KHR_image_base 1
+#define EGL_IMAGE_PRESERVED_KHR 0x30D2
+#endif /* EGL_KHR_image_base */
+
+#ifndef EGL_KHR_image_pixmap
+#define EGL_KHR_image_pixmap 1
+#endif /* EGL_KHR_image_pixmap */
+
+#ifndef EGL_KHR_lock_surface
+#define EGL_KHR_lock_surface 1
+#define EGL_READ_SURFACE_BIT_KHR 0x0001
+#define EGL_WRITE_SURFACE_BIT_KHR 0x0002
+#define EGL_LOCK_SURFACE_BIT_KHR 0x0080
+#define EGL_OPTIMAL_FORMAT_BIT_KHR 0x0100
+#define EGL_MATCH_FORMAT_KHR 0x3043
+#define EGL_FORMAT_RGB_565_EXACT_KHR 0x30C0
+#define EGL_FORMAT_RGB_565_KHR 0x30C1
+#define EGL_FORMAT_RGBA_8888_EXACT_KHR 0x30C2
+#define EGL_FORMAT_RGBA_8888_KHR 0x30C3
+#define EGL_MAP_PRESERVE_PIXELS_KHR 0x30C4
+#define EGL_LOCK_USAGE_HINT_KHR 0x30C5
+#define EGL_BITMAP_POINTER_KHR 0x30C6
+#define EGL_BITMAP_PITCH_KHR 0x30C7
+#define EGL_BITMAP_ORIGIN_KHR 0x30C8
+#define EGL_BITMAP_PIXEL_RED_OFFSET_KHR 0x30C9
+#define EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR 0x30CA
+#define EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR 0x30CB
+#define EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR 0x30CC
+#define EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR 0x30CD
+#define EGL_LOWER_LEFT_KHR 0x30CE
+#define EGL_UPPER_LEFT_KHR 0x30CF
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLLOCKSURFACEKHRPROC) (EGLDisplay dpy, EGLSurface surface, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNLOCKSURFACEKHRPROC) (EGLDisplay dpy, EGLSurface surface);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglLockSurfaceKHR (EGLDisplay dpy, EGLSurface surface, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglUnlockSurfaceKHR (EGLDisplay dpy, EGLSurface surface);
+#endif
+#endif /* EGL_KHR_lock_surface */
+
+#ifndef EGL_KHR_lock_surface2
+#define EGL_KHR_lock_surface2 1
+#define EGL_BITMAP_PIXEL_SIZE_KHR 0x3110
+#endif /* EGL_KHR_lock_surface2 */
+
+#ifndef EGL_KHR_lock_surface3
+#define EGL_KHR_lock_surface3 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACE64KHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLAttribKHR *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface64KHR (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLAttribKHR *value);
+#endif
+#endif /* EGL_KHR_lock_surface3 */
+
+#ifndef EGL_KHR_platform_android
+#define EGL_KHR_platform_android 1
+#define EGL_PLATFORM_ANDROID_KHR 0x3141
+#endif /* EGL_KHR_platform_android */
+
+#ifndef EGL_KHR_platform_gbm
+#define EGL_KHR_platform_gbm 1
+#define EGL_PLATFORM_GBM_KHR 0x31D7
+#endif /* EGL_KHR_platform_gbm */
+
+#ifndef EGL_KHR_platform_wayland
+#define EGL_KHR_platform_wayland 1
+#define EGL_PLATFORM_WAYLAND_KHR 0x31D8
+#endif /* EGL_KHR_platform_wayland */
+
+#ifndef EGL_KHR_platform_x11
+#define EGL_KHR_platform_x11 1
+#define EGL_PLATFORM_X11_KHR 0x31D5
+#define EGL_PLATFORM_X11_SCREEN_KHR 0x31D6
+#endif /* EGL_KHR_platform_x11 */
+
+#ifndef EGL_KHR_reusable_sync
+#define EGL_KHR_reusable_sync 1
+typedef khronos_utime_nanoseconds_t EGLTimeKHR;
+#ifdef KHRONOS_SUPPORT_INT64
+#define EGL_SYNC_STATUS_KHR 0x30F1
+#define EGL_SIGNALED_KHR 0x30F2
+#define EGL_UNSIGNALED_KHR 0x30F3
+#define EGL_TIMEOUT_EXPIRED_KHR 0x30F5
+#define EGL_CONDITION_SATISFIED_KHR 0x30F6
+#define EGL_SYNC_TYPE_KHR 0x30F7
+#define EGL_SYNC_REUSABLE_KHR 0x30FA
+#define EGL_SYNC_FLUSH_COMMANDS_BIT_KHR 0x0001
+#define EGL_FOREVER_KHR 0xFFFFFFFFFFFFFFFFull
+#define EGL_NO_SYNC_KHR ((EGLSyncKHR)0)
+typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNCKHRPROC) (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync);
+typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR (EGLDisplay dpy, EGLSyncKHR sync);
+EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
+EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
+#endif
+#endif /* KHRONOS_SUPPORT_INT64 */
+#endif /* EGL_KHR_reusable_sync */
+
+#ifndef EGL_KHR_stream
+#define EGL_KHR_stream 1
+typedef void *EGLStreamKHR;
+typedef khronos_uint64_t EGLuint64KHR;
+#ifdef KHRONOS_SUPPORT_INT64
+#define EGL_NO_STREAM_KHR ((EGLStreamKHR)0)
+#define EGL_CONSUMER_LATENCY_USEC_KHR 0x3210
+#define EGL_PRODUCER_FRAME_KHR 0x3212
+#define EGL_CONSUMER_FRAME_KHR 0x3213
+#define EGL_STREAM_STATE_KHR 0x3214
+#define EGL_STREAM_STATE_CREATED_KHR 0x3215
+#define EGL_STREAM_STATE_CONNECTING_KHR 0x3216
+#define EGL_STREAM_STATE_EMPTY_KHR 0x3217
+#define EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR 0x3218
+#define EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR 0x3219
+#define EGL_STREAM_STATE_DISCONNECTED_KHR 0x321A
+#define EGL_BAD_STREAM_KHR 0x321B
+#define EGL_BAD_STATE_KHR 0x321C
+typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMKHRPROC) (EGLDisplay dpy, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSTREAMKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMU64KHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamKHR (EGLDisplay dpy, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyStreamKHR (EGLDisplay dpy, EGLStreamKHR stream);
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamu64KHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value);
+#endif
+#endif /* KHRONOS_SUPPORT_INT64 */
+#endif /* EGL_KHR_stream */
+
+#ifndef EGL_KHR_stream_consumer_gltexture
+#define EGL_KHR_stream_consumer_gltexture 1
+#ifdef EGL_KHR_stream
+#define EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR 0x321E
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalKHR (EGLDisplay dpy, EGLStreamKHR stream);
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerAcquireKHR (EGLDisplay dpy, EGLStreamKHR stream);
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerReleaseKHR (EGLDisplay dpy, EGLStreamKHR stream);
+#endif
+#endif /* EGL_KHR_stream */
+#endif /* EGL_KHR_stream_consumer_gltexture */
+
+#ifndef EGL_KHR_stream_cross_process_fd
+#define EGL_KHR_stream_cross_process_fd 1
+typedef int EGLNativeFileDescriptorKHR;
+#ifdef EGL_KHR_stream
+#define EGL_NO_FILE_DESCRIPTOR_KHR ((EGLNativeFileDescriptorKHR)(-1))
+typedef EGLNativeFileDescriptorKHR (EGLAPIENTRYP PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLNativeFileDescriptorKHR EGLAPIENTRY eglGetStreamFileDescriptorKHR (EGLDisplay dpy, EGLStreamKHR stream);
+EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamFromFileDescriptorKHR (EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor);
+#endif
+#endif /* EGL_KHR_stream */
+#endif /* EGL_KHR_stream_cross_process_fd */
+
+#ifndef EGL_KHR_stream_fifo
+#define EGL_KHR_stream_fifo 1
+#ifdef EGL_KHR_stream
+#define EGL_STREAM_FIFO_LENGTH_KHR 0x31FC
+#define EGL_STREAM_TIME_NOW_KHR 0x31FD
+#define EGL_STREAM_TIME_CONSUMER_KHR 0x31FE
+#define EGL_STREAM_TIME_PRODUCER_KHR 0x31FF
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMTIMEKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamTimeKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value);
+#endif
+#endif /* EGL_KHR_stream */
+#endif /* EGL_KHR_stream_fifo */
+
+#ifndef EGL_KHR_stream_producer_aldatalocator
+#define EGL_KHR_stream_producer_aldatalocator 1
+#ifdef EGL_KHR_stream
+#endif /* EGL_KHR_stream */
+#endif /* EGL_KHR_stream_producer_aldatalocator */
+
+#ifndef EGL_KHR_stream_producer_eglsurface
+#define EGL_KHR_stream_producer_eglsurface 1
+#ifdef EGL_KHR_stream
+#define EGL_STREAM_BIT_KHR 0x0800
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC) (EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSurface EGLAPIENTRY eglCreateStreamProducerSurfaceKHR (EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list);
+#endif
+#endif /* EGL_KHR_stream */
+#endif /* EGL_KHR_stream_producer_eglsurface */
+
+#ifndef EGL_KHR_surfaceless_context
+#define EGL_KHR_surfaceless_context 1
+#endif /* EGL_KHR_surfaceless_context */
+
+#ifndef EGL_KHR_vg_parent_image
+#define EGL_KHR_vg_parent_image 1
+#define EGL_VG_PARENT_IMAGE_KHR 0x30BA
+#endif /* EGL_KHR_vg_parent_image */
+
+#ifndef EGL_KHR_wait_sync
+#define EGL_KHR_wait_sync 1
+typedef EGLint (EGLAPIENTRYP PFNEGLWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLint EGLAPIENTRY eglWaitSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags);
+#endif
+#endif /* EGL_KHR_wait_sync */
+
+#ifndef EGL_ANDROID_blob_cache
+#define EGL_ANDROID_blob_cache 1
+typedef khronos_ssize_t EGLsizeiANDROID;
+typedef void (*EGLSetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, const void *value, EGLsizeiANDROID valueSize);
+typedef EGLsizeiANDROID (*EGLGetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, void *value, EGLsizeiANDROID valueSize);
+typedef void (EGLAPIENTRYP PFNEGLSETBLOBCACHEFUNCSANDROIDPROC) (EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI void EGLAPIENTRY eglSetBlobCacheFuncsANDROID (EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get);
+#endif
+#endif /* EGL_ANDROID_blob_cache */
+
+#ifndef EGL_ANDROID_framebuffer_target
+#define EGL_ANDROID_framebuffer_target 1
+#define EGL_FRAMEBUFFER_TARGET_ANDROID 0x3147
+#endif /* EGL_ANDROID_framebuffer_target */
+
+#ifndef EGL_ANDROID_image_native_buffer
+#define EGL_ANDROID_image_native_buffer 1
+#define EGL_NATIVE_BUFFER_ANDROID 0x3140
+#endif /* EGL_ANDROID_image_native_buffer */
+
+#ifndef EGL_ANDROID_native_fence_sync
+#define EGL_ANDROID_native_fence_sync 1
+#define EGL_SYNC_NATIVE_FENCE_ANDROID 0x3144
+#define EGL_SYNC_NATIVE_FENCE_FD_ANDROID 0x3145
+#define EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID 0x3146
+#define EGL_NO_NATIVE_FENCE_FD_ANDROID -1
+typedef EGLint (EGLAPIENTRYP PFNEGLDUPNATIVEFENCEFDANDROIDPROC) (EGLDisplay dpy, EGLSyncKHR sync);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLint EGLAPIENTRY eglDupNativeFenceFDANDROID (EGLDisplay dpy, EGLSyncKHR sync);
+#endif
+#endif /* EGL_ANDROID_native_fence_sync */
+
+#ifndef EGL_ANDROID_recordable
+#define EGL_ANDROID_recordable 1
+#define EGL_RECORDABLE_ANDROID 0x3142
+#endif /* EGL_ANDROID_recordable */
+
+#ifndef EGL_ANGLE_d3d_share_handle_client_buffer
+#define EGL_ANGLE_d3d_share_handle_client_buffer 1
+#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200
+#endif /* EGL_ANGLE_d3d_share_handle_client_buffer */
+
+#ifndef EGL_ANGLE_window_fixed_size
+#define EGL_ANGLE_window_fixed_size 1
+#define EGL_FIXED_SIZE_ANGLE 0x3201
+#endif /* EGL_ANGLE_window_fixed_size */
+
+#ifndef EGL_ANGLE_query_surface_pointer
+#define EGL_ANGLE_query_surface_pointer 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
+#endif
+#endif /* EGL_ANGLE_query_surface_pointer */
+
+#ifndef EGL_ANGLE_software_display
+#define EGL_ANGLE_software_display 1
+#define EGL_SOFTWARE_DISPLAY_ANGLE ((EGLNativeDisplayType)-1)
+#endif /* EGL_ANGLE_software_display */
+
+#ifndef EGL_ANGLE_direct3d_display
+#define EGL_ANGLE_direct3d_display 1
+#define EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE ((EGLNativeDisplayType)-2)
+#define EGL_D3D11_ONLY_DISPLAY_ANGLE ((EGLNativeDisplayType)-3)
+#endif /* EGL_ANGLE_direct3d_display */
+
+#ifndef EGL_ANGLE_surface_d3d_texture_2d_share_handle
+#define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1
+#endif /* EGL_ANGLE_surface_d3d_texture_2d_share_handle */
+
+#ifndef EGL_ANGLE_surface_d3d_render_to_back_buffer
+#define EGL_ANGLE_surface_d3d_render_to_back_buffer 1
+#define EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER 0x320B
+#define EGL_ANGLE_SURFACE_RENDER_TO_BACK_BUFFER 0x320C
+#endif /* EGL_ANGLE_surface_d3d_render_to_back_buffer */
+
+#ifndef EGL_ANGLE_platform_angle
+#define EGL_ANGLE_platform_angle 1
+#define EGL_PLATFORM_ANGLE_ANGLE 0x3202
+#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3203
+#define EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE 0x3204
+#define EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE 0x3205
+#define EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE 0x3206
+#endif /* EGL_ANGLE_platform_angle */
+
+#ifndef EGL_ANGLE_platform_angle_d3d
+#define EGL_ANGLE_platform_angle_d3d 1
+#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3207
+#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208
+#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE 0x3209
+#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE 0x320A
+#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE 0x320B
+#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE 0x320C
+#define EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE 0x320F
+#endif /* EGL_ANGLE_platform_angle_d3d */
+
+#ifndef EGL_ANGLE_platform_angle_opengl
+#define EGL_ANGLE_platform_angle_opengl 1
+#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x320D
+#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320E
+#endif /* EGL_ANGLE_platform_angle_opengl */
+
+#ifndef EGL_ANGLE_device_d3d
+#define EGL_ANGLE_device_d3d 1
+#define EGL_D3D9_DEVICE_ANGLE 0x33A0
+#define EGL_D3D11_DEVICE_ANGLE 0x33A1
+#endif /* EGL_ANGLE_device_d3d */
+
+#ifndef EGL_ARM_pixmap_multisample_discard
+#define EGL_ARM_pixmap_multisample_discard 1
+#define EGL_DISCARD_SAMPLES_ARM 0x3286
+#endif /* EGL_ARM_pixmap_multisample_discard */
+
+#ifndef EGL_EXT_buffer_age
+#define EGL_EXT_buffer_age 1
+#define EGL_BUFFER_AGE_EXT 0x313D
+#endif /* EGL_EXT_buffer_age */
+
+#ifndef EGL_EXT_client_extensions
+#define EGL_EXT_client_extensions 1
+#endif /* EGL_EXT_client_extensions */
+
+#ifndef EGL_EXT_create_context_robustness
+#define EGL_EXT_create_context_robustness 1
+#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT 0x30BF
+#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT 0x3138
+#define EGL_NO_RESET_NOTIFICATION_EXT 0x31BE
+#define EGL_LOSE_CONTEXT_ON_RESET_EXT 0x31BF
+#endif /* EGL_EXT_create_context_robustness */
+
+#ifndef EGL_EXT_device_base
+#define EGL_EXT_device_base 1
+typedef void *EGLDeviceEXT;
+#define EGL_NO_DEVICE_EXT ((EGLDeviceEXT)(0))
+#define EGL_BAD_DEVICE_EXT 0x322B
+#define EGL_DEVICE_EXT 0x322C
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICEATTRIBEXTPROC) (EGLDeviceEXT device, EGLint attribute, EGLAttrib *value);
+typedef const char *(EGLAPIENTRYP PFNEGLQUERYDEVICESTRINGEXTPROC) (EGLDeviceEXT device, EGLint name);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICESEXTPROC) (EGLint max_devices, EGLDeviceEXT *devices, EGLint *num_devices);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDISPLAYATTRIBEXTPROC) (EGLDisplay dpy, EGLint attribute, EGLAttrib *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDeviceAttribEXT (EGLDeviceEXT device, EGLint attribute, EGLAttrib *value);
+EGLAPI const char *EGLAPIENTRY eglQueryDeviceStringEXT (EGLDeviceEXT device, EGLint name);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDevicesEXT (EGLint max_devices, EGLDeviceEXT *devices, EGLint *num_devices);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribEXT (EGLDisplay dpy, EGLint attribute, EGLAttrib *value);
+#endif
+#endif /* EGL_EXT_device_base */
+
+#ifndef EGL_EXT_device_query
+#define EGL_EXT_device_query 1
+#endif /* EGL_EXT_device_query */
+
+#ifndef EGL_EXT_image_dma_buf_import
+#define EGL_EXT_image_dma_buf_import 1
+#define EGL_LINUX_DMA_BUF_EXT 0x3270
+#define EGL_LINUX_DRM_FOURCC_EXT 0x3271
+#define EGL_DMA_BUF_PLANE0_FD_EXT 0x3272
+#define EGL_DMA_BUF_PLANE0_OFFSET_EXT 0x3273
+#define EGL_DMA_BUF_PLANE0_PITCH_EXT 0x3274
+#define EGL_DMA_BUF_PLANE1_FD_EXT 0x3275
+#define EGL_DMA_BUF_PLANE1_OFFSET_EXT 0x3276
+#define EGL_DMA_BUF_PLANE1_PITCH_EXT 0x3277
+#define EGL_DMA_BUF_PLANE2_FD_EXT 0x3278
+#define EGL_DMA_BUF_PLANE2_OFFSET_EXT 0x3279
+#define EGL_DMA_BUF_PLANE2_PITCH_EXT 0x327A
+#define EGL_YUV_COLOR_SPACE_HINT_EXT 0x327B
+#define EGL_SAMPLE_RANGE_HINT_EXT 0x327C
+#define EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT 0x327D
+#define EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT 0x327E
+#define EGL_ITU_REC601_EXT 0x327F
+#define EGL_ITU_REC709_EXT 0x3280
+#define EGL_ITU_REC2020_EXT 0x3281
+#define EGL_YUV_FULL_RANGE_EXT 0x3282
+#define EGL_YUV_NARROW_RANGE_EXT 0x3283
+#define EGL_YUV_CHROMA_SITING_0_EXT 0x3284
+#define EGL_YUV_CHROMA_SITING_0_5_EXT 0x3285
+#endif /* EGL_EXT_image_dma_buf_import */
+
+#ifndef EGL_EXT_multiview_window
+#define EGL_EXT_multiview_window 1
+#define EGL_MULTIVIEW_VIEW_COUNT_EXT 0x3134
+#endif /* EGL_EXT_multiview_window */
+
+#ifndef EGL_EXT_platform_base
+#define EGL_EXT_platform_base 1
+typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC) (EGLenum platform, void *native_display, const EGLint *attrib_list);
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list);
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplayEXT (EGLenum platform, void *native_display, const EGLint *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurfaceEXT (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurfaceEXT (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list);
+#endif
+#endif /* EGL_EXT_platform_base */
+
+#ifndef EGL_EXT_platform_device
+#define EGL_EXT_platform_device 1
+#define EGL_PLATFORM_DEVICE_EXT 0x313F
+#endif /* EGL_EXT_platform_device */
+
+#ifndef EGL_EXT_platform_wayland
+#define EGL_EXT_platform_wayland 1
+#define EGL_PLATFORM_WAYLAND_EXT 0x31D8
+#endif /* EGL_EXT_platform_wayland */
+
+#ifndef EGL_EXT_platform_x11
+#define EGL_EXT_platform_x11 1
+#define EGL_PLATFORM_X11_EXT 0x31D5
+#define EGL_PLATFORM_X11_SCREEN_EXT 0x31D6
+#endif /* EGL_EXT_platform_x11 */
+
+#ifndef EGL_EXT_protected_surface
+#define EGL_EXT_protected_surface 1
+#define EGL_PROTECTED_CONTENT_EXT 0x32C0
+#endif /* EGL_EXT_protected_surface */
+
+#ifndef EGL_EXT_swap_buffers_with_damage
+#define EGL_EXT_swap_buffers_with_damage 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageEXT (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
+#endif
+#endif /* EGL_EXT_swap_buffers_with_damage */
+
+#ifndef EGL_HI_clientpixmap
+#define EGL_HI_clientpixmap 1
+struct EGLClientPixmapHI {
+ void *pData;
+ EGLint iWidth;
+ EGLint iHeight;
+ EGLint iStride;
+};
+#define EGL_CLIENT_PIXMAP_POINTER_HI 0x8F74
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPIXMAPSURFACEHIPROC) (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI *pixmap);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurfaceHI (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI *pixmap);
+#endif
+#endif /* EGL_HI_clientpixmap */
+
+#ifndef EGL_HI_colorformats
+#define EGL_HI_colorformats 1
+#define EGL_COLOR_FORMAT_HI 0x8F70
+#define EGL_COLOR_RGB_HI 0x8F71
+#define EGL_COLOR_RGBA_HI 0x8F72
+#define EGL_COLOR_ARGB_HI 0x8F73
+#endif /* EGL_HI_colorformats */
+
+#ifndef EGL_IMG_context_priority
+#define EGL_IMG_context_priority 1
+#define EGL_CONTEXT_PRIORITY_LEVEL_IMG 0x3100
+#define EGL_CONTEXT_PRIORITY_HIGH_IMG 0x3101
+#define EGL_CONTEXT_PRIORITY_MEDIUM_IMG 0x3102
+#define EGL_CONTEXT_PRIORITY_LOW_IMG 0x3103
+#endif /* EGL_IMG_context_priority */
+
+#ifndef EGL_MESA_drm_image
+#define EGL_MESA_drm_image 1
+#define EGL_DRM_BUFFER_FORMAT_MESA 0x31D0
+#define EGL_DRM_BUFFER_USE_MESA 0x31D1
+#define EGL_DRM_BUFFER_FORMAT_ARGB32_MESA 0x31D2
+#define EGL_DRM_BUFFER_MESA 0x31D3
+#define EGL_DRM_BUFFER_STRIDE_MESA 0x31D4
+#define EGL_DRM_BUFFER_USE_SCANOUT_MESA 0x00000001
+#define EGL_DRM_BUFFER_USE_SHARE_MESA 0x00000002
+typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEDRMIMAGEMESAPROC) (EGLDisplay dpy, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDRMIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLImageKHR EGLAPIENTRY eglCreateDRMImageMESA (EGLDisplay dpy, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglExportDRMImageMESA (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride);
+#endif
+#endif /* EGL_MESA_drm_image */
+
+#ifndef EGL_MESA_platform_gbm
+#define EGL_MESA_platform_gbm 1
+#define EGL_PLATFORM_GBM_MESA 0x31D7
+#endif /* EGL_MESA_platform_gbm */
+
+#ifndef EGL_NOK_swap_region
+#define EGL_NOK_swap_region 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOKPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegionNOK (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects);
+#endif
+#endif /* EGL_NOK_swap_region */
+
+#ifndef EGL_NOK_swap_region2
+#define EGL_NOK_swap_region2 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGION2NOKPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegion2NOK (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects);
+#endif
+#endif /* EGL_NOK_swap_region2 */
+
+#ifndef EGL_NOK_texture_from_pixmap
+#define EGL_NOK_texture_from_pixmap 1
+#define EGL_Y_INVERTED_NOK 0x307F
+#endif /* EGL_NOK_texture_from_pixmap */
+
+#ifndef EGL_NV_3dvision_surface
+#define EGL_NV_3dvision_surface 1
+#define EGL_AUTO_STEREO_NV 0x3136
+#endif /* EGL_NV_3dvision_surface */
+
+#ifndef EGL_NV_coverage_sample
+#define EGL_NV_coverage_sample 1
+#define EGL_COVERAGE_BUFFERS_NV 0x30E0
+#define EGL_COVERAGE_SAMPLES_NV 0x30E1
+#endif /* EGL_NV_coverage_sample */
+
+#ifndef EGL_NV_coverage_sample_resolve
+#define EGL_NV_coverage_sample_resolve 1
+#define EGL_COVERAGE_SAMPLE_RESOLVE_NV 0x3131
+#define EGL_COVERAGE_SAMPLE_RESOLVE_DEFAULT_NV 0x3132
+#define EGL_COVERAGE_SAMPLE_RESOLVE_NONE_NV 0x3133
+#endif /* EGL_NV_coverage_sample_resolve */
+
+#ifndef EGL_NV_depth_nonlinear
+#define EGL_NV_depth_nonlinear 1
+#define EGL_DEPTH_ENCODING_NV 0x30E2
+#define EGL_DEPTH_ENCODING_NONE_NV 0
+#define EGL_DEPTH_ENCODING_NONLINEAR_NV 0x30E3
+#endif /* EGL_NV_depth_nonlinear */
+
+#ifndef EGL_NV_native_query
+#define EGL_NV_native_query 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEDISPLAYNVPROC) (EGLDisplay dpy, EGLNativeDisplayType *display_id);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEWINDOWNVPROC) (EGLDisplay dpy, EGLSurface surf, EGLNativeWindowType *window);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEPIXMAPNVPROC) (EGLDisplay dpy, EGLSurface surf, EGLNativePixmapType *pixmap);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativeDisplayNV (EGLDisplay dpy, EGLNativeDisplayType *display_id);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativeWindowNV (EGLDisplay dpy, EGLSurface surf, EGLNativeWindowType *window);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativePixmapNV (EGLDisplay dpy, EGLSurface surf, EGLNativePixmapType *pixmap);
+#endif
+#endif /* EGL_NV_native_query */
+
+#ifndef EGL_NV_post_convert_rounding
+#define EGL_NV_post_convert_rounding 1
+#endif /* EGL_NV_post_convert_rounding */
+
+#ifndef EGL_NV_post_sub_buffer
+#define EGL_NV_post_sub_buffer 1
+#define EGL_POST_SUB_BUFFER_SUPPORTED_NV 0x30BE
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLPOSTSUBBUFFERNVPROC) (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglPostSubBufferNV (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height);
+#endif
+#endif /* EGL_NV_post_sub_buffer */
+
+#ifndef EGL_NV_stream_sync
+#define EGL_NV_stream_sync 1
+#define EGL_SYNC_NEW_FRAME_NV 0x321F
+typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESTREAMSYNCNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum type, const EGLint *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateStreamSyncNV (EGLDisplay dpy, EGLStreamKHR stream, EGLenum type, const EGLint *attrib_list);
+#endif
+#endif /* EGL_NV_stream_sync */
+
+#ifndef EGL_NV_sync
+#define EGL_NV_sync 1
+typedef void *EGLSyncNV;
+typedef khronos_utime_nanoseconds_t EGLTimeNV;
+#ifdef KHRONOS_SUPPORT_INT64
+#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_NV 0x30E6
+#define EGL_SYNC_STATUS_NV 0x30E7
+#define EGL_SIGNALED_NV 0x30E8
+#define EGL_UNSIGNALED_NV 0x30E9
+#define EGL_SYNC_FLUSH_COMMANDS_BIT_NV 0x0001
+#define EGL_FOREVER_NV 0xFFFFFFFFFFFFFFFFull
+#define EGL_ALREADY_SIGNALED_NV 0x30EA
+#define EGL_TIMEOUT_EXPIRED_NV 0x30EB
+#define EGL_CONDITION_SATISFIED_NV 0x30EC
+#define EGL_SYNC_TYPE_NV 0x30ED
+#define EGL_SYNC_CONDITION_NV 0x30EE
+#define EGL_SYNC_FENCE_NV 0x30EF
+#define EGL_NO_SYNC_NV ((EGLSyncNV)0)
+typedef EGLSyncNV (EGLAPIENTRYP PFNEGLCREATEFENCESYNCNVPROC) (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCNVPROC) (EGLSyncNV sync);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLFENCENVPROC) (EGLSyncNV sync);
+typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCNVPROC) (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCNVPROC) (EGLSyncNV sync, EGLenum mode);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBNVPROC) (EGLSyncNV sync, EGLint attribute, EGLint *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSyncNV EGLAPIENTRY eglCreateFenceSyncNV (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncNV (EGLSyncNV sync);
+EGLAPI EGLBoolean EGLAPIENTRY eglFenceNV (EGLSyncNV sync);
+EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncNV (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
+EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncNV (EGLSyncNV sync, EGLenum mode);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribNV (EGLSyncNV sync, EGLint attribute, EGLint *value);
+#endif
+#endif /* KHRONOS_SUPPORT_INT64 */
+#endif /* EGL_NV_sync */
+
+#ifndef EGL_NV_system_time
+#define EGL_NV_system_time 1
+typedef khronos_utime_nanoseconds_t EGLuint64NV;
+#ifdef KHRONOS_SUPPORT_INT64
+typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC) (void);
+typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMENVPROC) (void);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeFrequencyNV (void);
+EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV (void);
+#endif
+#endif /* KHRONOS_SUPPORT_INT64 */
+#endif /* EGL_NV_system_time */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/external/ANGLE/EGL/eglplatform.h b/src/external/ANGLE/EGL/eglplatform.h
new file mode 100644
index 000000000..eb3ea70cc
--- /dev/null
+++ b/src/external/ANGLE/EGL/eglplatform.h
@@ -0,0 +1,151 @@
+#ifndef __eglplatform_h_
+#define __eglplatform_h_
+
+/*
+** Copyright (c) 2007-2013 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+/* Platform-specific types and definitions for egl.h
+ * $Revision: 23432 $ on $Date: 2013-10-09 00:57:24 -0700 (Wed, 09 Oct 2013) $
+ *
+ * Adopters may modify khrplatform.h and this file to suit their platform.
+ * You are encouraged to submit all modifications to the Khronos group so that
+ * they can be included in future versions of this file. Please submit changes
+ * by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla)
+ * by filing a bug against product "EGL" component "Registry".
+ */
+
+#include
+
+/* Macros used in EGL function prototype declarations.
+ *
+ * EGL functions should be prototyped as:
+ *
+ * EGLAPI return-type EGLAPIENTRY eglFunction(arguments);
+ * typedef return-type (EXPAPIENTRYP PFNEGLFUNCTIONPROC) (arguments);
+ *
+ * KHRONOS_APICALL and KHRONOS_APIENTRY are defined in KHR/khrplatform.h
+ */
+
+#ifndef EGLAPI
+#define EGLAPI KHRONOS_APICALL
+#endif
+
+#ifndef EGLAPIENTRY
+#define EGLAPIENTRY KHRONOS_APIENTRY
+#endif
+#define EGLAPIENTRYP EGLAPIENTRY*
+
+/* The types NativeDisplayType, NativeWindowType, and NativePixmapType
+ * are aliases of window-system-dependent types, such as X Display * or
+ * Windows Device Context. They must be defined in platform-specific
+ * code below. The EGL-prefixed versions of Native*Type are the same
+ * types, renamed in EGL 1.3 so all types in the API start with "EGL".
+ *
+ * Khronos STRONGLY RECOMMENDS that you use the default definitions
+ * provided below, since these changes affect both binary and source
+ * portability of applications using EGL running on different EGL
+ * implementations.
+ */
+
+#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif
+//#include
+
+// raylib edit!!!
+typedef void *PVOID; // PVOID is a pointer to any type. This type is declared in WinNT.h
+typedef PVOID HANDLE; // HANDLE is handle to an object. This type is declared in WinNT.h
+typedef HANDLE HWND; // HWND is a handle to a window. This type is declared in WinDef.h
+typedef HANDLE HDC; // HDC is a handle to a device context (DC). This type is declared in WinDef.h
+typedef HANDLE HBITMAP; // HBITMAP is a handle to a bitmap. This type is declared in WinDef.h
+
+// HDC, HBITMAP and HWND are actually pointers to void. You can cast a long to a HWND like this: HWND h = (HWND)my_long_var;
+// but very careful of what information is stored in my_long_var. You have to make sure that you have a pointer in there.
+
+
+
+typedef HDC EGLNativeDisplayType;
+typedef HBITMAP EGLNativePixmapType;
+
+#if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP) /* Windows Desktop */
+typedef HWND EGLNativeWindowType;
+#else /* Windows Store */
+#include
+typedef IInspectable* EGLNativeWindowType;
+#endif
+
+#elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */
+
+typedef int EGLNativeDisplayType;
+typedef void *EGLNativeWindowType;
+typedef void *EGLNativePixmapType;
+
+#elif defined(__ANDROID__) || defined(ANDROID)
+
+#include
+
+struct egl_native_pixmap_t;
+
+typedef struct ANativeWindow* EGLNativeWindowType;
+typedef struct egl_native_pixmap_t* EGLNativePixmapType;
+typedef void* EGLNativeDisplayType;
+
+#elif defined(__unix__)
+
+/* X11 (tentative) */
+#include
+#include
+
+typedef Display *EGLNativeDisplayType;
+typedef Pixmap EGLNativePixmapType;
+typedef Window EGLNativeWindowType;
+
+#elif defined(__GNUC__) && ( defined(__APPLE_CPP__) || defined(__APPLE_CC__) || defined(__MACOS_CLASSIC__) )
+
+// TODO(jmadill): native implementation for OSX
+
+typedef void *EGLNativeDisplayType;
+typedef void *EGLNativePixmapType;
+typedef void *EGLNativeWindowType;
+
+#else
+#error "Platform not recognized"
+#endif
+
+/* EGL 1.2 types, renamed for consistency in EGL 1.3 */
+typedef EGLNativeDisplayType NativeDisplayType;
+typedef EGLNativePixmapType NativePixmapType;
+typedef EGLNativeWindowType NativeWindowType;
+
+
+/* Define EGLint. This must be a signed integral type large enough to contain
+ * all legal attribute names and values passed into and out of EGL, whether
+ * their type is boolean, bitmask, enumerant (symbolic constant), integer,
+ * handle, or other. While in general a 32-bit integer will suffice, if
+ * handles are 64 bit types, then EGLint should be defined as a signed 64-bit
+ * integer type.
+ */
+typedef khronos_int32_t EGLint;
+
+#endif /* __eglplatform_h */
diff --git a/src/external/ANGLE/GLES2/gl2.h b/src/external/ANGLE/GLES2/gl2.h
new file mode 100644
index 000000000..c2d835726
--- /dev/null
+++ b/src/external/ANGLE/GLES2/gl2.h
@@ -0,0 +1,620 @@
+#ifndef __gl2_h_
+#define __gl2_h_
+
+/* $Revision: 20555 $ on $Date:: 2013-02-12 14:32:47 -0800 #$ */
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This document is licensed under the SGI Free Software B License Version
+ * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ .
+ */
+
+/*-------------------------------------------------------------------------
+ * Data type definitions
+ *-----------------------------------------------------------------------*/
+
+typedef void GLvoid;
+typedef char GLchar;
+typedef unsigned int GLenum;
+typedef unsigned char GLboolean;
+typedef unsigned int GLbitfield;
+typedef khronos_int8_t GLbyte;
+typedef short GLshort;
+typedef int GLint;
+typedef int GLsizei;
+typedef khronos_uint8_t GLubyte;
+typedef unsigned short GLushort;
+typedef unsigned int GLuint;
+typedef khronos_float_t GLfloat;
+typedef khronos_float_t GLclampf;
+typedef khronos_int32_t GLfixed;
+
+/* GL types for handling large vertex buffer objects */
+typedef khronos_intptr_t GLintptr;
+typedef khronos_ssize_t GLsizeiptr;
+
+/* OpenGL ES core versions */
+#define GL_ES_VERSION_2_0 1
+
+/* ClearBufferMask */
+#define GL_DEPTH_BUFFER_BIT 0x00000100
+#define GL_STENCIL_BUFFER_BIT 0x00000400
+#define GL_COLOR_BUFFER_BIT 0x00004000
+
+/* Boolean */
+#define GL_FALSE 0
+#define GL_TRUE 1
+
+/* BeginMode */
+#define GL_POINTS 0x0000
+#define GL_LINES 0x0001
+#define GL_LINE_LOOP 0x0002
+#define GL_LINE_STRIP 0x0003
+#define GL_TRIANGLES 0x0004
+#define GL_TRIANGLE_STRIP 0x0005
+#define GL_TRIANGLE_FAN 0x0006
+
+/* AlphaFunction (not supported in ES20) */
+/* GL_NEVER */
+/* GL_LESS */
+/* GL_EQUAL */
+/* GL_LEQUAL */
+/* GL_GREATER */
+/* GL_NOTEQUAL */
+/* GL_GEQUAL */
+/* GL_ALWAYS */
+
+/* BlendingFactorDest */
+#define GL_ZERO 0
+#define GL_ONE 1
+#define GL_SRC_COLOR 0x0300
+#define GL_ONE_MINUS_SRC_COLOR 0x0301
+#define GL_SRC_ALPHA 0x0302
+#define GL_ONE_MINUS_SRC_ALPHA 0x0303
+#define GL_DST_ALPHA 0x0304
+#define GL_ONE_MINUS_DST_ALPHA 0x0305
+
+/* BlendingFactorSrc */
+/* GL_ZERO */
+/* GL_ONE */
+#define GL_DST_COLOR 0x0306
+#define GL_ONE_MINUS_DST_COLOR 0x0307
+#define GL_SRC_ALPHA_SATURATE 0x0308
+/* GL_SRC_ALPHA */
+/* GL_ONE_MINUS_SRC_ALPHA */
+/* GL_DST_ALPHA */
+/* GL_ONE_MINUS_DST_ALPHA */
+
+/* BlendEquationSeparate */
+#define GL_FUNC_ADD 0x8006
+#define GL_BLEND_EQUATION 0x8009
+#define GL_BLEND_EQUATION_RGB 0x8009 /* same as BLEND_EQUATION */
+#define GL_BLEND_EQUATION_ALPHA 0x883D
+
+/* BlendSubtract */
+#define GL_FUNC_SUBTRACT 0x800A
+#define GL_FUNC_REVERSE_SUBTRACT 0x800B
+
+/* Separate Blend Functions */
+#define GL_BLEND_DST_RGB 0x80C8
+#define GL_BLEND_SRC_RGB 0x80C9
+#define GL_BLEND_DST_ALPHA 0x80CA
+#define GL_BLEND_SRC_ALPHA 0x80CB
+#define GL_CONSTANT_COLOR 0x8001
+#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
+#define GL_CONSTANT_ALPHA 0x8003
+#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
+#define GL_BLEND_COLOR 0x8005
+
+/* Buffer Objects */
+#define GL_ARRAY_BUFFER 0x8892
+#define GL_ELEMENT_ARRAY_BUFFER 0x8893
+#define GL_ARRAY_BUFFER_BINDING 0x8894
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
+
+#define GL_STREAM_DRAW 0x88E0
+#define GL_STATIC_DRAW 0x88E4
+#define GL_DYNAMIC_DRAW 0x88E8
+
+#define GL_BUFFER_SIZE 0x8764
+#define GL_BUFFER_USAGE 0x8765
+
+#define GL_CURRENT_VERTEX_ATTRIB 0x8626
+
+/* CullFaceMode */
+#define GL_FRONT 0x0404
+#define GL_BACK 0x0405
+#define GL_FRONT_AND_BACK 0x0408
+
+/* DepthFunction */
+/* GL_NEVER */
+/* GL_LESS */
+/* GL_EQUAL */
+/* GL_LEQUAL */
+/* GL_GREATER */
+/* GL_NOTEQUAL */
+/* GL_GEQUAL */
+/* GL_ALWAYS */
+
+/* EnableCap */
+#define GL_TEXTURE_2D 0x0DE1
+#define GL_CULL_FACE 0x0B44
+#define GL_BLEND 0x0BE2
+#define GL_DITHER 0x0BD0
+#define GL_STENCIL_TEST 0x0B90
+#define GL_DEPTH_TEST 0x0B71
+#define GL_SCISSOR_TEST 0x0C11
+#define GL_POLYGON_OFFSET_FILL 0x8037
+#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
+#define GL_SAMPLE_COVERAGE 0x80A0
+
+/* ErrorCode */
+#define GL_NO_ERROR 0
+#define GL_INVALID_ENUM 0x0500
+#define GL_INVALID_VALUE 0x0501
+#define GL_INVALID_OPERATION 0x0502
+#define GL_OUT_OF_MEMORY 0x0505
+
+/* FrontFaceDirection */
+#define GL_CW 0x0900
+#define GL_CCW 0x0901
+
+/* GetPName */
+#define GL_LINE_WIDTH 0x0B21
+#define GL_ALIASED_POINT_SIZE_RANGE 0x846D
+#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
+#define GL_CULL_FACE_MODE 0x0B45
+#define GL_FRONT_FACE 0x0B46
+#define GL_DEPTH_RANGE 0x0B70
+#define GL_DEPTH_WRITEMASK 0x0B72
+#define GL_DEPTH_CLEAR_VALUE 0x0B73
+#define GL_DEPTH_FUNC 0x0B74
+#define GL_STENCIL_CLEAR_VALUE 0x0B91
+#define GL_STENCIL_FUNC 0x0B92
+#define GL_STENCIL_FAIL 0x0B94
+#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95
+#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96
+#define GL_STENCIL_REF 0x0B97
+#define GL_STENCIL_VALUE_MASK 0x0B93
+#define GL_STENCIL_WRITEMASK 0x0B98
+#define GL_STENCIL_BACK_FUNC 0x8800
+#define GL_STENCIL_BACK_FAIL 0x8801
+#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802
+#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803
+#define GL_STENCIL_BACK_REF 0x8CA3
+#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4
+#define GL_STENCIL_BACK_WRITEMASK 0x8CA5
+#define GL_VIEWPORT 0x0BA2
+#define GL_SCISSOR_BOX 0x0C10
+/* GL_SCISSOR_TEST */
+#define GL_COLOR_CLEAR_VALUE 0x0C22
+#define GL_COLOR_WRITEMASK 0x0C23
+#define GL_UNPACK_ALIGNMENT 0x0CF5
+#define GL_PACK_ALIGNMENT 0x0D05
+#define GL_MAX_TEXTURE_SIZE 0x0D33
+#define GL_MAX_VIEWPORT_DIMS 0x0D3A
+#define GL_SUBPIXEL_BITS 0x0D50
+#define GL_RED_BITS 0x0D52
+#define GL_GREEN_BITS 0x0D53
+#define GL_BLUE_BITS 0x0D54
+#define GL_ALPHA_BITS 0x0D55
+#define GL_DEPTH_BITS 0x0D56
+#define GL_STENCIL_BITS 0x0D57
+#define GL_POLYGON_OFFSET_UNITS 0x2A00
+/* GL_POLYGON_OFFSET_FILL */
+#define GL_POLYGON_OFFSET_FACTOR 0x8038
+#define GL_TEXTURE_BINDING_2D 0x8069
+#define GL_SAMPLE_BUFFERS 0x80A8
+#define GL_SAMPLES 0x80A9
+#define GL_SAMPLE_COVERAGE_VALUE 0x80AA
+#define GL_SAMPLE_COVERAGE_INVERT 0x80AB
+
+/* GetTextureParameter */
+/* GL_TEXTURE_MAG_FILTER */
+/* GL_TEXTURE_MIN_FILTER */
+/* GL_TEXTURE_WRAP_S */
+/* GL_TEXTURE_WRAP_T */
+
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
+#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
+
+/* HintMode */
+#define GL_DONT_CARE 0x1100
+#define GL_FASTEST 0x1101
+#define GL_NICEST 0x1102
+
+/* HintTarget */
+#define GL_GENERATE_MIPMAP_HINT 0x8192
+
+/* DataType */
+#define GL_BYTE 0x1400
+#define GL_UNSIGNED_BYTE 0x1401
+#define GL_SHORT 0x1402
+#define GL_UNSIGNED_SHORT 0x1403
+#define GL_INT 0x1404
+#define GL_UNSIGNED_INT 0x1405
+#define GL_FLOAT 0x1406
+#define GL_FIXED 0x140C
+
+/* PixelFormat */
+#define GL_DEPTH_COMPONENT 0x1902
+#define GL_ALPHA 0x1906
+#define GL_RGB 0x1907
+#define GL_RGBA 0x1908
+#define GL_LUMINANCE 0x1909
+#define GL_LUMINANCE_ALPHA 0x190A
+
+/* PixelType */
+/* GL_UNSIGNED_BYTE */
+#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
+#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
+#define GL_UNSIGNED_SHORT_5_6_5 0x8363
+
+/* Shaders */
+#define GL_FRAGMENT_SHADER 0x8B30
+#define GL_VERTEX_SHADER 0x8B31
+#define GL_MAX_VERTEX_ATTRIBS 0x8869
+#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
+#define GL_MAX_VARYING_VECTORS 0x8DFC
+#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
+#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
+#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
+#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
+#define GL_SHADER_TYPE 0x8B4F
+#define GL_DELETE_STATUS 0x8B80
+#define GL_LINK_STATUS 0x8B82
+#define GL_VALIDATE_STATUS 0x8B83
+#define GL_ATTACHED_SHADERS 0x8B85
+#define GL_ACTIVE_UNIFORMS 0x8B86
+#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
+#define GL_ACTIVE_ATTRIBUTES 0x8B89
+#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
+#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
+#define GL_CURRENT_PROGRAM 0x8B8D
+
+/* StencilFunction */
+#define GL_NEVER 0x0200
+#define GL_LESS 0x0201
+#define GL_EQUAL 0x0202
+#define GL_LEQUAL 0x0203
+#define GL_GREATER 0x0204
+#define GL_NOTEQUAL 0x0205
+#define GL_GEQUAL 0x0206
+#define GL_ALWAYS 0x0207
+
+/* StencilOp */
+/* GL_ZERO */
+#define GL_KEEP 0x1E00
+#define GL_REPLACE 0x1E01
+#define GL_INCR 0x1E02
+#define GL_DECR 0x1E03
+#define GL_INVERT 0x150A
+#define GL_INCR_WRAP 0x8507
+#define GL_DECR_WRAP 0x8508
+
+/* StringName */
+#define GL_VENDOR 0x1F00
+#define GL_RENDERER 0x1F01
+#define GL_VERSION 0x1F02
+#define GL_EXTENSIONS 0x1F03
+
+/* TextureMagFilter */
+#define GL_NEAREST 0x2600
+#define GL_LINEAR 0x2601
+
+/* TextureMinFilter */
+/* GL_NEAREST */
+/* GL_LINEAR */
+#define GL_NEAREST_MIPMAP_NEAREST 0x2700
+#define GL_LINEAR_MIPMAP_NEAREST 0x2701
+#define GL_NEAREST_MIPMAP_LINEAR 0x2702
+#define GL_LINEAR_MIPMAP_LINEAR 0x2703
+
+/* TextureParameterName */
+#define GL_TEXTURE_MAG_FILTER 0x2800
+#define GL_TEXTURE_MIN_FILTER 0x2801
+#define GL_TEXTURE_WRAP_S 0x2802
+#define GL_TEXTURE_WRAP_T 0x2803
+
+/* TextureTarget */
+/* GL_TEXTURE_2D */
+#define GL_TEXTURE 0x1702
+
+#define GL_TEXTURE_CUBE_MAP 0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C
+
+/* TextureUnit */
+#define GL_TEXTURE0 0x84C0
+#define GL_TEXTURE1 0x84C1
+#define GL_TEXTURE2 0x84C2
+#define GL_TEXTURE3 0x84C3
+#define GL_TEXTURE4 0x84C4
+#define GL_TEXTURE5 0x84C5
+#define GL_TEXTURE6 0x84C6
+#define GL_TEXTURE7 0x84C7
+#define GL_TEXTURE8 0x84C8
+#define GL_TEXTURE9 0x84C9
+#define GL_TEXTURE10 0x84CA
+#define GL_TEXTURE11 0x84CB
+#define GL_TEXTURE12 0x84CC
+#define GL_TEXTURE13 0x84CD
+#define GL_TEXTURE14 0x84CE
+#define GL_TEXTURE15 0x84CF
+#define GL_TEXTURE16 0x84D0
+#define GL_TEXTURE17 0x84D1
+#define GL_TEXTURE18 0x84D2
+#define GL_TEXTURE19 0x84D3
+#define GL_TEXTURE20 0x84D4
+#define GL_TEXTURE21 0x84D5
+#define GL_TEXTURE22 0x84D6
+#define GL_TEXTURE23 0x84D7
+#define GL_TEXTURE24 0x84D8
+#define GL_TEXTURE25 0x84D9
+#define GL_TEXTURE26 0x84DA
+#define GL_TEXTURE27 0x84DB
+#define GL_TEXTURE28 0x84DC
+#define GL_TEXTURE29 0x84DD
+#define GL_TEXTURE30 0x84DE
+#define GL_TEXTURE31 0x84DF
+#define GL_ACTIVE_TEXTURE 0x84E0
+
+/* TextureWrapMode */
+#define GL_REPEAT 0x2901
+#define GL_CLAMP_TO_EDGE 0x812F
+#define GL_MIRRORED_REPEAT 0x8370
+
+/* Uniform Types */
+#define GL_FLOAT_VEC2 0x8B50
+#define GL_FLOAT_VEC3 0x8B51
+#define GL_FLOAT_VEC4 0x8B52
+#define GL_INT_VEC2 0x8B53
+#define GL_INT_VEC3 0x8B54
+#define GL_INT_VEC4 0x8B55
+#define GL_BOOL 0x8B56
+#define GL_BOOL_VEC2 0x8B57
+#define GL_BOOL_VEC3 0x8B58
+#define GL_BOOL_VEC4 0x8B59
+#define GL_FLOAT_MAT2 0x8B5A
+#define GL_FLOAT_MAT3 0x8B5B
+#define GL_FLOAT_MAT4 0x8B5C
+#define GL_SAMPLER_2D 0x8B5E
+#define GL_SAMPLER_CUBE 0x8B60
+
+/* Vertex Arrays */
+#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
+#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
+#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
+#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
+#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
+#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
+#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
+
+/* Read Format */
+#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A
+#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B
+
+/* Shader Source */
+#define GL_COMPILE_STATUS 0x8B81
+#define GL_INFO_LOG_LENGTH 0x8B84
+#define GL_SHADER_SOURCE_LENGTH 0x8B88
+#define GL_SHADER_COMPILER 0x8DFA
+
+/* Shader Binary */
+#define GL_SHADER_BINARY_FORMATS 0x8DF8
+#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9
+
+/* Shader Precision-Specified Types */
+#define GL_LOW_FLOAT 0x8DF0
+#define GL_MEDIUM_FLOAT 0x8DF1
+#define GL_HIGH_FLOAT 0x8DF2
+#define GL_LOW_INT 0x8DF3
+#define GL_MEDIUM_INT 0x8DF4
+#define GL_HIGH_INT 0x8DF5
+
+/* Framebuffer Object. */
+#define GL_FRAMEBUFFER 0x8D40
+#define GL_RENDERBUFFER 0x8D41
+
+#define GL_RGBA4 0x8056
+#define GL_RGB5_A1 0x8057
+#define GL_RGB565 0x8D62
+#define GL_DEPTH_COMPONENT16 0x81A5
+#define GL_STENCIL_INDEX8 0x8D48
+
+#define GL_RENDERBUFFER_WIDTH 0x8D42
+#define GL_RENDERBUFFER_HEIGHT 0x8D43
+#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44
+#define GL_RENDERBUFFER_RED_SIZE 0x8D50
+#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51
+#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52
+#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53
+#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54
+#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
+
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
+
+#define GL_COLOR_ATTACHMENT0 0x8CE0
+#define GL_DEPTH_ATTACHMENT 0x8D00
+#define GL_STENCIL_ATTACHMENT 0x8D20
+
+#define GL_NONE 0
+
+#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
+#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9
+#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
+
+#define GL_FRAMEBUFFER_BINDING 0x8CA6
+#define GL_RENDERBUFFER_BINDING 0x8CA7
+#define GL_MAX_RENDERBUFFER_SIZE 0x84E8
+
+#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
+
+/*-------------------------------------------------------------------------
+ * GL core functions.
+ *-----------------------------------------------------------------------*/
+
+GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture);
+GL_APICALL void GL_APIENTRY glAttachShader (GLuint program, GLuint shader);
+GL_APICALL void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar* name);
+GL_APICALL void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer);
+GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer);
+GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer);
+GL_APICALL void GL_APIENTRY glBindTexture (GLenum target, GLuint texture);
+GL_APICALL void GL_APIENTRY glBlendColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+GL_APICALL void GL_APIENTRY glBlendEquation ( GLenum mode );
+GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha);
+GL_APICALL void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor);
+GL_APICALL void GL_APIENTRY glBlendFuncSeparate (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);
+GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);
+GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target);
+GL_APICALL void GL_APIENTRY glClear (GLbitfield mask);
+GL_APICALL void GL_APIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+GL_APICALL void GL_APIENTRY glClearDepthf (GLclampf depth);
+GL_APICALL void GL_APIENTRY glClearStencil (GLint s);
+GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader);
+GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data);
+GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data);
+GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL GLuint GL_APIENTRY glCreateProgram (void);
+GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenum type);
+GL_APICALL void GL_APIENTRY glCullFace (GLenum mode);
+GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint* buffers);
+GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint* framebuffers);
+GL_APICALL void GL_APIENTRY glDeleteProgram (GLuint program);
+GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint* renderbuffers);
+GL_APICALL void GL_APIENTRY glDeleteShader (GLuint shader);
+GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint* textures);
+GL_APICALL void GL_APIENTRY glDepthFunc (GLenum func);
+GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag);
+GL_APICALL void GL_APIENTRY glDepthRangef (GLclampf zNear, GLclampf zFar);
+GL_APICALL void GL_APIENTRY glDetachShader (GLuint program, GLuint shader);
+GL_APICALL void GL_APIENTRY glDisable (GLenum cap);
+GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index);
+GL_APICALL void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count);
+GL_APICALL void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices);
+GL_APICALL void GL_APIENTRY glEnable (GLenum cap);
+GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index);
+GL_APICALL void GL_APIENTRY glFinish (void);
+GL_APICALL void GL_APIENTRY glFlush (void);
+GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GL_APICALL void GL_APIENTRY glFrontFace (GLenum mode);
+GL_APICALL void GL_APIENTRY glGenBuffers (GLsizei n, GLuint* buffers);
+GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenum target);
+GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint* framebuffers);
+GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint* renderbuffers);
+GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint* textures);
+GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
+GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
+GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders);
+GL_APICALL GLint GL_APIENTRY glGetAttribLocation (GLuint program, const GLchar* name);
+GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean* params);
+GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint* params);
+GL_APICALL GLenum GL_APIENTRY glGetError (void);
+GL_APICALL void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat* params);
+GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint* params);
+GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint* params);
+GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint* params);
+GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog);
+GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint* params);
+GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint* params);
+GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog);
+GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
+GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source);
+GL_APICALL const GLubyte* GL_APIENTRY glGetString (GLenum name);
+GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat* params);
+GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint* params);
+GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat* params);
+GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint* params);
+GL_APICALL GLint GL_APIENTRY glGetUniformLocation (GLuint program, const GLchar* name);
+GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat* params);
+GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint* params);
+GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, GLvoid** pointer);
+GL_APICALL void GL_APIENTRY glHint (GLenum target, GLenum mode);
+GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLuint buffer);
+GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenum cap);
+GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLuint framebuffer);
+GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLuint program);
+GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLuint renderbuffer);
+GL_APICALL GLboolean GL_APIENTRY glIsShader (GLuint shader);
+GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLuint texture);
+GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width);
+GL_APICALL void GL_APIENTRY glLinkProgram (GLuint program);
+GL_APICALL void GL_APIENTRY glPixelStorei (GLenum pname, GLint param);
+GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units);
+GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels);
+GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void);
+GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glSampleCoverage (GLclampf value, GLboolean invert);
+GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length);
+GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length);
+GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass);
+GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
+GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param);
+GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat* params);
+GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param);
+GL_APICALL void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint* params);
+GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels);
+GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat x);
+GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat* v);
+GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint x);
+GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint* v);
+GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat x, GLfloat y);
+GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat* v);
+GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint x, GLint y);
+GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint* v);
+GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat x, GLfloat y, GLfloat z);
+GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat* v);
+GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint x, GLint y, GLint z);
+GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint* v);
+GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat* v);
+GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint x, GLint y, GLint z, GLint w);
+GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint* v);
+GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void GL_APIENTRY glUseProgram (GLuint program);
+GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program);
+GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint indx, GLfloat x);
+GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint indx, const GLfloat* values);
+GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint indx, GLfloat x, GLfloat y);
+GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint indx, const GLfloat* values);
+GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint indx, GLfloat x, GLfloat y, GLfloat z);
+GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint indx, const GLfloat* values);
+GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint indx, const GLfloat* values);
+GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr);
+GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gl2_h_ */
diff --git a/src/external/ANGLE/GLES2/gl2ext.h b/src/external/ANGLE/GLES2/gl2ext.h
new file mode 100644
index 000000000..d77fdbaeb
--- /dev/null
+++ b/src/external/ANGLE/GLES2/gl2ext.h
@@ -0,0 +1,2013 @@
+#ifndef __gl2ext_h_
+#define __gl2ext_h_
+
+/* $Revision: 20795 $ on $Date:: 2013-03-07 01:01:58 -0800 #$ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This document is licensed under the SGI Free Software B License Version
+ * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ .
+ */
+
+#ifndef GL_APIENTRYP
+# define GL_APIENTRYP GL_APIENTRY*
+#endif
+
+/*------------------------------------------------------------------------*
+ * OES extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_OES_compressed_ETC1_RGB8_texture */
+#ifndef GL_OES_compressed_ETC1_RGB8_texture
+#define GL_ETC1_RGB8_OES 0x8D64
+#endif
+
+/* GL_OES_compressed_paletted_texture */
+#ifndef GL_OES_compressed_paletted_texture
+#define GL_PALETTE4_RGB8_OES 0x8B90
+#define GL_PALETTE4_RGBA8_OES 0x8B91
+#define GL_PALETTE4_R5_G6_B5_OES 0x8B92
+#define GL_PALETTE4_RGBA4_OES 0x8B93
+#define GL_PALETTE4_RGB5_A1_OES 0x8B94
+#define GL_PALETTE8_RGB8_OES 0x8B95
+#define GL_PALETTE8_RGBA8_OES 0x8B96
+#define GL_PALETTE8_R5_G6_B5_OES 0x8B97
+#define GL_PALETTE8_RGBA4_OES 0x8B98
+#define GL_PALETTE8_RGB5_A1_OES 0x8B99
+#endif
+
+/* GL_OES_depth24 */
+#ifndef GL_OES_depth24
+#define GL_DEPTH_COMPONENT24_OES 0x81A6
+#endif
+
+/* GL_OES_depth32 */
+#ifndef GL_OES_depth32
+#define GL_DEPTH_COMPONENT32_OES 0x81A7
+#endif
+
+/* GL_OES_depth_texture */
+/* No new tokens introduced by this extension. */
+
+/* GL_OES_EGL_image */
+#ifndef GL_OES_EGL_image
+typedef void* GLeglImageOES;
+#endif
+
+/* GL_OES_EGL_image_external */
+#ifndef GL_OES_EGL_image_external
+/* GLeglImageOES defined in GL_OES_EGL_image already. */
+#define GL_TEXTURE_EXTERNAL_OES 0x8D65
+#define GL_SAMPLER_EXTERNAL_OES 0x8D66
+#define GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67
+#define GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES 0x8D68
+#endif
+
+/* GL_OES_element_index_uint */
+#ifndef GL_OES_element_index_uint
+#define GL_UNSIGNED_INT 0x1405
+#endif
+
+/* GL_OES_get_program_binary */
+#ifndef GL_OES_get_program_binary
+#define GL_PROGRAM_BINARY_LENGTH_OES 0x8741
+#define GL_NUM_PROGRAM_BINARY_FORMATS_OES 0x87FE
+#define GL_PROGRAM_BINARY_FORMATS_OES 0x87FF
+#endif
+
+/* GL_OES_mapbuffer */
+#ifndef GL_OES_mapbuffer
+#define GL_WRITE_ONLY_OES 0x88B9
+#define GL_BUFFER_ACCESS_OES 0x88BB
+#define GL_BUFFER_MAPPED_OES 0x88BC
+#define GL_BUFFER_MAP_POINTER_OES 0x88BD
+#endif
+
+/* GL_OES_packed_depth_stencil */
+#ifndef GL_OES_packed_depth_stencil
+#define GL_DEPTH_STENCIL_OES 0x84F9
+#define GL_UNSIGNED_INT_24_8_OES 0x84FA
+#define GL_DEPTH24_STENCIL8_OES 0x88F0
+#endif
+
+/* GL_OES_required_internalformat */
+#ifndef GL_OES_required_internalformat
+#define GL_ALPHA8_OES 0x803C
+#define GL_DEPTH_COMPONENT16_OES 0x81A5
+/* reuse GL_DEPTH_COMPONENT24_OES */
+/* reuse GL_DEPTH24_STENCIL8_OES */
+/* reuse GL_DEPTH_COMPONENT32_OES */
+#define GL_LUMINANCE4_ALPHA4_OES 0x8043
+#define GL_LUMINANCE8_ALPHA8_OES 0x8045
+#define GL_LUMINANCE8_OES 0x8040
+#define GL_RGBA4_OES 0x8056
+#define GL_RGB5_A1_OES 0x8057
+#define GL_RGB565_OES 0x8D62
+/* reuse GL_RGB8_OES */
+/* reuse GL_RGBA8_OES */
+/* reuse GL_RGB10_EXT */
+/* reuse GL_RGB10_A2_EXT */
+#endif
+
+/* GL_OES_rgb8_rgba8 */
+#ifndef GL_OES_rgb8_rgba8
+#define GL_RGB8_OES 0x8051
+#define GL_RGBA8_OES 0x8058
+#endif
+
+/* GL_OES_standard_derivatives */
+#ifndef GL_OES_standard_derivatives
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES 0x8B8B
+#endif
+
+/* GL_OES_stencil1 */
+#ifndef GL_OES_stencil1
+#define GL_STENCIL_INDEX1_OES 0x8D46
+#endif
+
+/* GL_OES_stencil4 */
+#ifndef GL_OES_stencil4
+#define GL_STENCIL_INDEX4_OES 0x8D47
+#endif
+
+#ifndef GL_OES_surfaceless_context
+#define GL_FRAMEBUFFER_UNDEFINED_OES 0x8219
+#endif
+
+/* GL_OES_texture_3D */
+#ifndef GL_OES_texture_3D
+#define GL_TEXTURE_WRAP_R_OES 0x8072
+#define GL_TEXTURE_3D_OES 0x806F
+#define GL_TEXTURE_BINDING_3D_OES 0x806A
+#define GL_MAX_3D_TEXTURE_SIZE_OES 0x8073
+#define GL_SAMPLER_3D_OES 0x8B5F
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES 0x8CD4
+#endif
+
+/* GL_OES_texture_float */
+/* No new tokens introduced by this extension. */
+
+/* GL_OES_texture_float_linear */
+/* No new tokens introduced by this extension. */
+
+/* GL_OES_texture_half_float */
+#ifndef GL_OES_texture_half_float
+#define GL_HALF_FLOAT_OES 0x8D61
+#endif
+
+/* GL_OES_texture_half_float_linear */
+/* No new tokens introduced by this extension. */
+
+/* GL_OES_texture_npot */
+/* No new tokens introduced by this extension. */
+
+/* GL_OES_vertex_array_object */
+#ifndef GL_OES_vertex_array_object
+#define GL_VERTEX_ARRAY_BINDING_OES 0x85B5
+#endif
+
+/* GL_OES_vertex_half_float */
+/* GL_HALF_FLOAT_OES defined in GL_OES_texture_half_float already. */
+
+/* GL_OES_vertex_type_10_10_10_2 */
+#ifndef GL_OES_vertex_type_10_10_10_2
+#define GL_UNSIGNED_INT_10_10_10_2_OES 0x8DF6
+#define GL_INT_10_10_10_2_OES 0x8DF7
+#endif
+
+/*------------------------------------------------------------------------*
+ * KHR extension tokens
+ *------------------------------------------------------------------------*/
+
+#ifndef GL_KHR_debug
+typedef void (GL_APIENTRYP GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
+#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242
+#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243
+#define GL_DEBUG_CALLBACK_FUNCTION 0x8244
+#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245
+#define GL_DEBUG_SOURCE_API 0x8246
+#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247
+#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248
+#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249
+#define GL_DEBUG_SOURCE_APPLICATION 0x824A
+#define GL_DEBUG_SOURCE_OTHER 0x824B
+#define GL_DEBUG_TYPE_ERROR 0x824C
+#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D
+#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E
+#define GL_DEBUG_TYPE_PORTABILITY 0x824F
+#define GL_DEBUG_TYPE_PERFORMANCE 0x8250
+#define GL_DEBUG_TYPE_OTHER 0x8251
+#define GL_DEBUG_TYPE_MARKER 0x8268
+#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269
+#define GL_DEBUG_TYPE_POP_GROUP 0x826A
+#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B
+#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C
+#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D
+#define GL_BUFFER 0x82E0
+#define GL_SHADER 0x82E1
+#define GL_PROGRAM 0x82E2
+#define GL_QUERY 0x82E3
+/* PROGRAM_PIPELINE only in GL */
+#define GL_SAMPLER 0x82E6
+/* DISPLAY_LIST only in GL */
+#define GL_MAX_LABEL_LENGTH 0x82E8
+#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143
+#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144
+#define GL_DEBUG_LOGGED_MESSAGES 0x9145
+#define GL_DEBUG_SEVERITY_HIGH 0x9146
+#define GL_DEBUG_SEVERITY_MEDIUM 0x9147
+#define GL_DEBUG_SEVERITY_LOW 0x9148
+#define GL_DEBUG_OUTPUT 0x92E0
+#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002
+#define GL_STACK_OVERFLOW 0x0503
+#define GL_STACK_UNDERFLOW 0x0504
+#endif
+
+#ifndef GL_KHR_texture_compression_astc_ldr
+#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0
+#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1
+#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2
+#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3
+#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4
+#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5
+#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6
+#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7
+#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8
+#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9
+#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA
+#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB
+#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC
+#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD
+#endif
+
+/*------------------------------------------------------------------------*
+ * AMD extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_AMD_compressed_3DC_texture */
+#ifndef GL_AMD_compressed_3DC_texture
+#define GL_3DC_X_AMD 0x87F9
+#define GL_3DC_XY_AMD 0x87FA
+#endif
+
+/* GL_AMD_compressed_ATC_texture */
+#ifndef GL_AMD_compressed_ATC_texture
+#define GL_ATC_RGB_AMD 0x8C92
+#define GL_ATC_RGBA_EXPLICIT_ALPHA_AMD 0x8C93
+#define GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE
+#endif
+
+/* GL_AMD_performance_monitor */
+#ifndef GL_AMD_performance_monitor
+#define GL_COUNTER_TYPE_AMD 0x8BC0
+#define GL_COUNTER_RANGE_AMD 0x8BC1
+#define GL_UNSIGNED_INT64_AMD 0x8BC2
+#define GL_PERCENTAGE_AMD 0x8BC3
+#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4
+#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5
+#define GL_PERFMON_RESULT_AMD 0x8BC6
+#endif
+
+/* GL_AMD_program_binary_Z400 */
+#ifndef GL_AMD_program_binary_Z400
+#define GL_Z400_BINARY_AMD 0x8740
+#endif
+
+/*------------------------------------------------------------------------*
+ * ANGLE extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_ANGLE_depth_texture */
+#ifndef GL_ANGLE_depth_texture
+#define GL_DEPTH_COMPONENT 0x1902
+#define GL_DEPTH_STENCIL_OES 0x84F9
+#define GL_UNSIGNED_SHORT 0x1403
+#define GL_UNSIGNED_INT 0x1405
+#define GL_UNSIGNED_INT_24_8_OES 0x84FA
+#define GL_DEPTH_COMPONENT16 0x81A5
+#define GL_DEPTH_COMPONENT32_OES 0x81A7
+#define GL_DEPTH24_STENCIL8_OES 0x88F0
+#endif
+
+/* GL_ANGLE_framebuffer_blit */
+#ifndef GL_ANGLE_framebuffer_blit
+#define GL_READ_FRAMEBUFFER_ANGLE 0x8CA8
+#define GL_DRAW_FRAMEBUFFER_ANGLE 0x8CA9
+#define GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 0x8CA6
+#define GL_READ_FRAMEBUFFER_BINDING_ANGLE 0x8CAA
+#endif
+
+/* GL_ANGLE_framebuffer_multisample */
+#ifndef GL_ANGLE_framebuffer_multisample
+#define GL_RENDERBUFFER_SAMPLES_ANGLE 0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56
+#define GL_MAX_SAMPLES_ANGLE 0x8D57
+#endif
+
+/* GL_ANGLE_instanced_arrays */
+#ifndef GL_ANGLE_instanced_arrays
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE
+#endif
+
+/* GL_ANGLE_pack_reverse_row_order */
+#ifndef GL_ANGLE_pack_reverse_row_order
+#define GL_PACK_REVERSE_ROW_ORDER_ANGLE 0x93A4
+#endif
+
+/* GL_ANGLE_program_binary */
+#ifndef GL_ANGLE_program_binary
+#define GL_PROGRAM_BINARY_ANGLE 0x93A6
+#endif
+
+/* GL_ANGLE_texture_compression_dxt3 */
+#ifndef GL_ANGLE_texture_compression_dxt3
+#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2
+#endif
+
+/* GL_ANGLE_texture_compression_dxt5 */
+#ifndef GL_ANGLE_texture_compression_dxt5
+#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3
+#endif
+
+/* GL_ANGLE_texture_usage */
+#ifndef GL_ANGLE_texture_usage
+#define GL_TEXTURE_USAGE_ANGLE 0x93A2
+#define GL_FRAMEBUFFER_ATTACHMENT_ANGLE 0x93A3
+#endif
+
+/* GL_ANGLE_translated_shader_source */
+#ifndef GL_ANGLE_translated_shader_source
+#define GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE 0x93A0
+#endif
+
+/*------------------------------------------------------------------------*
+ * APPLE extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_APPLE_copy_texture_levels */
+/* No new tokens introduced by this extension. */
+
+/* GL_APPLE_framebuffer_multisample */
+#ifndef GL_APPLE_framebuffer_multisample
+#define GL_RENDERBUFFER_SAMPLES_APPLE 0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE 0x8D56
+#define GL_MAX_SAMPLES_APPLE 0x8D57
+#define GL_READ_FRAMEBUFFER_APPLE 0x8CA8
+#define GL_DRAW_FRAMEBUFFER_APPLE 0x8CA9
+#define GL_DRAW_FRAMEBUFFER_BINDING_APPLE 0x8CA6
+#define GL_READ_FRAMEBUFFER_BINDING_APPLE 0x8CAA
+#endif
+
+/* GL_APPLE_rgb_422 */
+#ifndef GL_APPLE_rgb_422
+#define GL_RGB_422_APPLE 0x8A1F
+#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA
+#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB
+#endif
+
+/* GL_APPLE_sync */
+#ifndef GL_APPLE_sync
+
+#ifndef __gl3_h_
+/* These types are defined with reference to
+ * in the Apple extension spec, but here we use the Khronos
+ * portable types in khrplatform.h, and assume those types
+ * are always defined.
+ * If any other extensions using these types are defined,
+ * the typedefs must move out of this block and be shared.
+ */
+typedef khronos_int64_t GLint64;
+typedef khronos_uint64_t GLuint64;
+typedef struct __GLsync *GLsync;
+#endif
+
+#define GL_SYNC_OBJECT_APPLE 0x8A53
+#define GL_MAX_SERVER_WAIT_TIMEOUT_APPLE 0x9111
+#define GL_OBJECT_TYPE_APPLE 0x9112
+#define GL_SYNC_CONDITION_APPLE 0x9113
+#define GL_SYNC_STATUS_APPLE 0x9114
+#define GL_SYNC_FLAGS_APPLE 0x9115
+#define GL_SYNC_FENCE_APPLE 0x9116
+#define GL_SYNC_GPU_COMMANDS_COMPLETE_APPLE 0x9117
+#define GL_UNSIGNALED_APPLE 0x9118
+#define GL_SIGNALED_APPLE 0x9119
+#define GL_ALREADY_SIGNALED_APPLE 0x911A
+#define GL_TIMEOUT_EXPIRED_APPLE 0x911B
+#define GL_CONDITION_SATISFIED_APPLE 0x911C
+#define GL_WAIT_FAILED_APPLE 0x911D
+#define GL_SYNC_FLUSH_COMMANDS_BIT_APPLE 0x00000001
+#define GL_TIMEOUT_IGNORED_APPLE 0xFFFFFFFFFFFFFFFFull
+#endif
+
+/* GL_APPLE_texture_format_BGRA8888 */
+#ifndef GL_APPLE_texture_format_BGRA8888
+#define GL_BGRA_EXT 0x80E1
+#endif
+
+/* GL_APPLE_texture_max_level */
+#ifndef GL_APPLE_texture_max_level
+#define GL_TEXTURE_MAX_LEVEL_APPLE 0x813D
+#endif
+
+/*------------------------------------------------------------------------*
+ * ARM extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_ARM_mali_program_binary */
+#ifndef GL_ARM_mali_program_binary
+#define GL_MALI_PROGRAM_BINARY_ARM 0x8F61
+#endif
+
+/* GL_ARM_mali_shader_binary */
+#ifndef GL_ARM_mali_shader_binary
+#define GL_MALI_SHADER_BINARY_ARM 0x8F60
+#endif
+
+/* GL_ARM_rgba8 */
+/* No new tokens introduced by this extension. */
+
+/*------------------------------------------------------------------------*
+ * EXT extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_EXT_blend_minmax */
+#ifndef GL_EXT_blend_minmax
+#define GL_MIN_EXT 0x8007
+#define GL_MAX_EXT 0x8008
+#endif
+
+/* GL_EXT_color_buffer_half_float */
+#ifndef GL_EXT_color_buffer_half_float
+#define GL_RGBA16F_EXT 0x881A
+#define GL_RGB16F_EXT 0x881B
+#define GL_RG16F_EXT 0x822F
+#define GL_R16F_EXT 0x822D
+#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT 0x8211
+#define GL_UNSIGNED_NORMALIZED_EXT 0x8C17
+#endif
+
+/* GL_EXT_debug_label */
+#ifndef GL_EXT_debug_label
+#define GL_PROGRAM_PIPELINE_OBJECT_EXT 0x8A4F
+#define GL_PROGRAM_OBJECT_EXT 0x8B40
+#define GL_SHADER_OBJECT_EXT 0x8B48
+#define GL_BUFFER_OBJECT_EXT 0x9151
+#define GL_QUERY_OBJECT_EXT 0x9153
+#define GL_VERTEX_ARRAY_OBJECT_EXT 0x9154
+#endif
+
+/* GL_EXT_debug_marker */
+/* No new tokens introduced by this extension. */
+
+/* GL_EXT_discard_framebuffer */
+#ifndef GL_EXT_discard_framebuffer
+#define GL_COLOR_EXT 0x1800
+#define GL_DEPTH_EXT 0x1801
+#define GL_STENCIL_EXT 0x1802
+#endif
+
+/* GL_EXT_map_buffer_range */
+#ifndef GL_EXT_map_buffer_range
+#define GL_MAP_READ_BIT_EXT 0x0001
+#define GL_MAP_WRITE_BIT_EXT 0x0002
+#define GL_MAP_INVALIDATE_RANGE_BIT_EXT 0x0004
+#define GL_MAP_INVALIDATE_BUFFER_BIT_EXT 0x0008
+#define GL_MAP_FLUSH_EXPLICIT_BIT_EXT 0x0010
+#define GL_MAP_UNSYNCHRONIZED_BIT_EXT 0x0020
+#endif
+
+/* GL_EXT_multisampled_render_to_texture */
+#ifndef GL_EXT_multisampled_render_to_texture
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT 0x8D6C
+/* reuse values from GL_EXT_framebuffer_multisample (desktop extension) */
+#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56
+#define GL_MAX_SAMPLES_EXT 0x8D57
+#endif
+
+/* GL_EXT_multiview_draw_buffers */
+#ifndef GL_EXT_multiview_draw_buffers
+#define GL_COLOR_ATTACHMENT_EXT 0x90F0
+#define GL_MULTIVIEW_EXT 0x90F1
+#define GL_DRAW_BUFFER_EXT 0x0C01
+#define GL_READ_BUFFER_EXT 0x0C02
+#define GL_MAX_MULTIVIEW_BUFFERS_EXT 0x90F2
+#endif
+
+/* GL_EXT_multi_draw_arrays */
+/* No new tokens introduced by this extension. */
+
+/* GL_EXT_occlusion_query_boolean */
+#ifndef GL_EXT_occlusion_query_boolean
+#define GL_ANY_SAMPLES_PASSED_EXT 0x8C2F
+#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT 0x8D6A
+#define GL_CURRENT_QUERY_EXT 0x8865
+#define GL_QUERY_RESULT_EXT 0x8866
+#define GL_QUERY_RESULT_AVAILABLE_EXT 0x8867
+#endif
+
+/* GL_EXT_read_format_bgra */
+#ifndef GL_EXT_read_format_bgra
+#define GL_BGRA_EXT 0x80E1
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT 0x8365
+#define GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT 0x8366
+#endif
+
+/* GL_EXT_robustness */
+#ifndef GL_EXT_robustness
+/* reuse GL_NO_ERROR */
+#define GL_GUILTY_CONTEXT_RESET_EXT 0x8253
+#define GL_INNOCENT_CONTEXT_RESET_EXT 0x8254
+#define GL_UNKNOWN_CONTEXT_RESET_EXT 0x8255
+#define GL_CONTEXT_ROBUST_ACCESS_EXT 0x90F3
+#define GL_RESET_NOTIFICATION_STRATEGY_EXT 0x8256
+#define GL_LOSE_CONTEXT_ON_RESET_EXT 0x8252
+#define GL_NO_RESET_NOTIFICATION_EXT 0x8261
+#endif
+
+/* GL_EXT_separate_shader_objects */
+#ifndef GL_EXT_separate_shader_objects
+#define GL_VERTEX_SHADER_BIT_EXT 0x00000001
+#define GL_FRAGMENT_SHADER_BIT_EXT 0x00000002
+#define GL_ALL_SHADER_BITS_EXT 0xFFFFFFFF
+#define GL_PROGRAM_SEPARABLE_EXT 0x8258
+#define GL_ACTIVE_PROGRAM_EXT 0x8259
+#define GL_PROGRAM_PIPELINE_BINDING_EXT 0x825A
+#endif
+
+/* GL_EXT_shader_framebuffer_fetch */
+#ifndef GL_EXT_shader_framebuffer_fetch
+#define GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52
+#endif
+
+/* GL_EXT_shader_texture_lod */
+/* No new tokens introduced by this extension. */
+
+/* GL_EXT_shadow_samplers */
+#ifndef GL_EXT_shadow_samplers
+#define GL_TEXTURE_COMPARE_MODE_EXT 0x884C
+#define GL_TEXTURE_COMPARE_FUNC_EXT 0x884D
+#define GL_COMPARE_REF_TO_TEXTURE_EXT 0x884E
+#define GL_SAMPLER_2D_SHADOW_EXT 0x8B62
+#endif
+
+/* GL_EXT_sRGB */
+#ifndef GL_EXT_sRGB
+#define GL_SRGB_EXT 0x8C40
+#define GL_SRGB_ALPHA_EXT 0x8C42
+#define GL_SRGB8_ALPHA8_EXT 0x8C43
+#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT 0x8210
+#endif
+
+/* GL_EXT_texture_compression_dxt1 */
+#ifndef GL_EXT_texture_compression_dxt1
+#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
+#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
+#endif
+
+/* GL_EXT_texture_filter_anisotropic */
+#ifndef GL_EXT_texture_filter_anisotropic
+#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
+#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
+#endif
+
+/* GL_EXT_texture_format_BGRA8888 */
+#ifndef GL_EXT_texture_format_BGRA8888
+#define GL_BGRA_EXT 0x80E1
+#endif
+
+/* GL_EXT_texture_rg */
+#ifndef GL_EXT_texture_rg
+#define GL_RED_EXT 0x1903
+#define GL_RG_EXT 0x8227
+#define GL_R8_EXT 0x8229
+#define GL_RG8_EXT 0x822B
+#endif
+
+/* GL_EXT_texture_storage */
+#ifndef GL_EXT_texture_storage
+#define GL_TEXTURE_IMMUTABLE_FORMAT_EXT 0x912F
+#define GL_ALPHA8_EXT 0x803C
+#define GL_LUMINANCE8_EXT 0x8040
+#define GL_LUMINANCE8_ALPHA8_EXT 0x8045
+#define GL_RGBA32F_EXT 0x8814
+#define GL_RGB32F_EXT 0x8815
+#define GL_ALPHA32F_EXT 0x8816
+#define GL_LUMINANCE32F_EXT 0x8818
+#define GL_LUMINANCE_ALPHA32F_EXT 0x8819
+/* reuse GL_RGBA16F_EXT */
+/* reuse GL_RGB16F_EXT */
+#define GL_ALPHA16F_EXT 0x881C
+#define GL_LUMINANCE16F_EXT 0x881E
+#define GL_LUMINANCE_ALPHA16F_EXT 0x881F
+#define GL_RGB10_A2_EXT 0x8059
+#define GL_RGB10_EXT 0x8052
+#define GL_BGRA8_EXT 0x93A1
+#define GL_R8_EXT 0x8229
+#define GL_RG8_EXT 0x822B
+#define GL_R32F_EXT 0x822E
+#define GL_RG32F_EXT 0x8230
+#define GL_R16F_EXT 0x822D
+#define GL_RG16F_EXT 0x822F
+#endif
+
+/* GL_EXT_texture_type_2_10_10_10_REV */
+#ifndef GL_EXT_texture_type_2_10_10_10_REV
+#define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368
+#endif
+
+/* GL_EXT_unpack_subimage */
+#ifndef GL_EXT_unpack_subimage
+#define GL_UNPACK_ROW_LENGTH_EXT 0x0CF2
+#define GL_UNPACK_SKIP_ROWS_EXT 0x0CF3
+#define GL_UNPACK_SKIP_PIXELS_EXT 0x0CF4
+#endif
+
+/*------------------------------------------------------------------------*
+ * DMP extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_DMP_shader_binary */
+#ifndef GL_DMP_shader_binary
+#define GL_SHADER_BINARY_DMP 0x9250
+#endif
+
+/*------------------------------------------------------------------------*
+ * FJ extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_FJ_shader_binary_GCCSO */
+#ifndef GL_FJ_shader_binary_GCCSO
+#define GL_GCCSO_SHADER_BINARY_F 0x9260
+#endif
+
+/*------------------------------------------------------------------------*
+ * IMG extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_IMG_program_binary */
+#ifndef GL_IMG_program_binary
+#define GL_SGX_PROGRAM_BINARY_IMG 0x9130
+#endif
+
+/* GL_IMG_read_format */
+#ifndef GL_IMG_read_format
+#define GL_BGRA_IMG 0x80E1
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV_IMG 0x8365
+#endif
+
+/* GL_IMG_shader_binary */
+#ifndef GL_IMG_shader_binary
+#define GL_SGX_BINARY_IMG 0x8C0A
+#endif
+
+/* GL_IMG_texture_compression_pvrtc */
+#ifndef GL_IMG_texture_compression_pvrtc
+#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00
+#define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01
+#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02
+#define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03
+#endif
+
+/* GL_IMG_texture_compression_pvrtc2 */
+#ifndef GL_IMG_texture_compression_pvrtc2
+#define GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG 0x9137
+#define GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG 0x9138
+#endif
+
+/* GL_IMG_multisampled_render_to_texture */
+#ifndef GL_IMG_multisampled_render_to_texture
+#define GL_RENDERBUFFER_SAMPLES_IMG 0x9133
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG 0x9134
+#define GL_MAX_SAMPLES_IMG 0x9135
+#define GL_TEXTURE_SAMPLES_IMG 0x9136
+#endif
+
+/*------------------------------------------------------------------------*
+ * NV extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_NV_coverage_sample */
+#ifndef GL_NV_coverage_sample
+#define GL_COVERAGE_COMPONENT_NV 0x8ED0
+#define GL_COVERAGE_COMPONENT4_NV 0x8ED1
+#define GL_COVERAGE_ATTACHMENT_NV 0x8ED2
+#define GL_COVERAGE_BUFFERS_NV 0x8ED3
+#define GL_COVERAGE_SAMPLES_NV 0x8ED4
+#define GL_COVERAGE_ALL_FRAGMENTS_NV 0x8ED5
+#define GL_COVERAGE_EDGE_FRAGMENTS_NV 0x8ED6
+#define GL_COVERAGE_AUTOMATIC_NV 0x8ED7
+#define GL_COVERAGE_BUFFER_BIT_NV 0x8000
+#endif
+
+/* GL_NV_depth_nonlinear */
+#ifndef GL_NV_depth_nonlinear
+#define GL_DEPTH_COMPONENT16_NONLINEAR_NV 0x8E2C
+#endif
+
+/* GL_NV_draw_buffers */
+#ifndef GL_NV_draw_buffers
+#define GL_MAX_DRAW_BUFFERS_NV 0x8824
+#define GL_DRAW_BUFFER0_NV 0x8825
+#define GL_DRAW_BUFFER1_NV 0x8826
+#define GL_DRAW_BUFFER2_NV 0x8827
+#define GL_DRAW_BUFFER3_NV 0x8828
+#define GL_DRAW_BUFFER4_NV 0x8829
+#define GL_DRAW_BUFFER5_NV 0x882A
+#define GL_DRAW_BUFFER6_NV 0x882B
+#define GL_DRAW_BUFFER7_NV 0x882C
+#define GL_DRAW_BUFFER8_NV 0x882D
+#define GL_DRAW_BUFFER9_NV 0x882E
+#define GL_DRAW_BUFFER10_NV 0x882F
+#define GL_DRAW_BUFFER11_NV 0x8830
+#define GL_DRAW_BUFFER12_NV 0x8831
+#define GL_DRAW_BUFFER13_NV 0x8832
+#define GL_DRAW_BUFFER14_NV 0x8833
+#define GL_DRAW_BUFFER15_NV 0x8834
+#define GL_COLOR_ATTACHMENT0_NV 0x8CE0
+#define GL_COLOR_ATTACHMENT1_NV 0x8CE1
+#define GL_COLOR_ATTACHMENT2_NV 0x8CE2
+#define GL_COLOR_ATTACHMENT3_NV 0x8CE3
+#define GL_COLOR_ATTACHMENT4_NV 0x8CE4
+#define GL_COLOR_ATTACHMENT5_NV 0x8CE5
+#define GL_COLOR_ATTACHMENT6_NV 0x8CE6
+#define GL_COLOR_ATTACHMENT7_NV 0x8CE7
+#define GL_COLOR_ATTACHMENT8_NV 0x8CE8
+#define GL_COLOR_ATTACHMENT9_NV 0x8CE9
+#define GL_COLOR_ATTACHMENT10_NV 0x8CEA
+#define GL_COLOR_ATTACHMENT11_NV 0x8CEB
+#define GL_COLOR_ATTACHMENT12_NV 0x8CEC
+#define GL_COLOR_ATTACHMENT13_NV 0x8CED
+#define GL_COLOR_ATTACHMENT14_NV 0x8CEE
+#define GL_COLOR_ATTACHMENT15_NV 0x8CEF
+#endif
+
+/* GL_EXT_draw_buffers */
+#ifndef GL_EXT_draw_buffers
+#define GL_MAX_DRAW_BUFFERS_EXT 0x8824
+#define GL_DRAW_BUFFER0_EXT 0x8825
+#define GL_DRAW_BUFFER1_EXT 0x8826
+#define GL_DRAW_BUFFER2_EXT 0x8827
+#define GL_DRAW_BUFFER3_EXT 0x8828
+#define GL_DRAW_BUFFER4_EXT 0x8829
+#define GL_DRAW_BUFFER5_EXT 0x882A
+#define GL_DRAW_BUFFER6_EXT 0x882B
+#define GL_DRAW_BUFFER7_EXT 0x882C
+#define GL_DRAW_BUFFER8_EXT 0x882D
+#define GL_DRAW_BUFFER9_EXT 0x882E
+#define GL_DRAW_BUFFER10_EXT 0x882F
+#define GL_DRAW_BUFFER11_EXT 0x8830
+#define GL_DRAW_BUFFER12_EXT 0x8831
+#define GL_DRAW_BUFFER13_EXT 0x8832
+#define GL_DRAW_BUFFER14_EXT 0x8833
+#define GL_DRAW_BUFFER15_EXT 0x8834
+#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0
+#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1
+#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2
+#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3
+#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4
+#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5
+#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6
+#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7
+#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8
+#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9
+#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA
+#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB
+#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC
+#define GL_COLOR_ATTACHMENT13_EXT 0x8CED
+#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE
+#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF
+#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF
+#endif
+
+/* GL_NV_draw_instanced */
+/* No new tokens introduced by this extension. */
+
+/* GL_NV_fbo_color_attachments */
+#ifndef GL_NV_fbo_color_attachments
+#define GL_MAX_COLOR_ATTACHMENTS_NV 0x8CDF
+/* GL_COLOR_ATTACHMENT{0-15}_NV defined in GL_NV_draw_buffers already. */
+#endif
+
+/* GL_NV_fence */
+#ifndef GL_NV_fence
+#define GL_ALL_COMPLETED_NV 0x84F2
+#define GL_FENCE_STATUS_NV 0x84F3
+#define GL_FENCE_CONDITION_NV 0x84F4
+#endif
+
+/* GL_NV_framebuffer_blit */
+#ifndef GL_NV_framebuffer_blit
+#define GL_READ_FRAMEBUFFER_NV 0x8CA8
+#define GL_DRAW_FRAMEBUFFER_NV 0x8CA9
+#define GL_DRAW_FRAMEBUFFER_BINDING_NV 0x8CA6
+#define GL_READ_FRAMEBUFFER_BINDING_NV 0x8CAA
+#endif
+
+/* GL_NV_framebuffer_multisample */
+#ifndef GL_NV_framebuffer_multisample
+#define GL_RENDERBUFFER_SAMPLES_NV 0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_NV 0x8D56
+#define GL_MAX_SAMPLES_NV 0x8D57
+#endif
+
+/* GL_NV_generate_mipmap_sRGB */
+/* No new tokens introduced by this extension. */
+
+/* GL_NV_instanced_arrays */
+#ifndef GL_NV_instanced_arrays
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_NV 0x88FE
+#endif
+
+/* GL_NV_read_buffer */
+#ifndef GL_NV_read_buffer
+#define GL_READ_BUFFER_NV 0x0C02
+#endif
+
+/* GL_NV_read_buffer_front */
+/* No new tokens introduced by this extension. */
+
+/* GL_NV_read_depth */
+/* No new tokens introduced by this extension. */
+
+/* GL_NV_read_depth_stencil */
+/* No new tokens introduced by this extension. */
+
+/* GL_NV_read_stencil */
+/* No new tokens introduced by this extension. */
+
+/* GL_NV_shadow_samplers_array */
+#ifndef GL_NV_shadow_samplers_array
+#define GL_SAMPLER_2D_ARRAY_SHADOW_NV 0x8DC4
+#endif
+
+/* GL_NV_shadow_samplers_cube */
+#ifndef GL_NV_shadow_samplers_cube
+#define GL_SAMPLER_CUBE_SHADOW_NV 0x8DC5
+#endif
+
+/* GL_NV_sRGB_formats */
+#ifndef GL_NV_sRGB_formats
+#define GL_SLUMINANCE_NV 0x8C46
+#define GL_SLUMINANCE_ALPHA_NV 0x8C44
+#define GL_SRGB8_NV 0x8C41
+#define GL_SLUMINANCE8_NV 0x8C47
+#define GL_SLUMINANCE8_ALPHA8_NV 0x8C45
+#define GL_COMPRESSED_SRGB_S3TC_DXT1_NV 0x8C4C
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV 0x8C4D
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV 0x8C4E
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV 0x8C4F
+#define GL_ETC1_SRGB8_NV 0x88EE
+#endif
+
+/* GL_NV_texture_border_clamp */
+#ifndef GL_NV_texture_border_clamp
+#define GL_TEXTURE_BORDER_COLOR_NV 0x1004
+#define GL_CLAMP_TO_BORDER_NV 0x812D
+#endif
+
+/* GL_NV_texture_compression_s3tc_update */
+/* No new tokens introduced by this extension. */
+
+/* GL_NV_texture_npot_2D_mipmap */
+/* No new tokens introduced by this extension. */
+
+/*------------------------------------------------------------------------*
+ * QCOM extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_QCOM_alpha_test */
+#ifndef GL_QCOM_alpha_test
+#define GL_ALPHA_TEST_QCOM 0x0BC0
+#define GL_ALPHA_TEST_FUNC_QCOM 0x0BC1
+#define GL_ALPHA_TEST_REF_QCOM 0x0BC2
+#endif
+
+/* GL_QCOM_binning_control */
+#ifndef GL_QCOM_binning_control
+#define GL_BINNING_CONTROL_HINT_QCOM 0x8FB0
+#define GL_CPU_OPTIMIZED_QCOM 0x8FB1
+#define GL_GPU_OPTIMIZED_QCOM 0x8FB2
+#define GL_RENDER_DIRECT_TO_FRAMEBUFFER_QCOM 0x8FB3
+#endif
+
+/* GL_QCOM_driver_control */
+/* No new tokens introduced by this extension. */
+
+/* GL_QCOM_extended_get */
+#ifndef GL_QCOM_extended_get
+#define GL_TEXTURE_WIDTH_QCOM 0x8BD2
+#define GL_TEXTURE_HEIGHT_QCOM 0x8BD3
+#define GL_TEXTURE_DEPTH_QCOM 0x8BD4
+#define GL_TEXTURE_INTERNAL_FORMAT_QCOM 0x8BD5
+#define GL_TEXTURE_FORMAT_QCOM 0x8BD6
+#define GL_TEXTURE_TYPE_QCOM 0x8BD7
+#define GL_TEXTURE_IMAGE_VALID_QCOM 0x8BD8
+#define GL_TEXTURE_NUM_LEVELS_QCOM 0x8BD9
+#define GL_TEXTURE_TARGET_QCOM 0x8BDA
+#define GL_TEXTURE_OBJECT_VALID_QCOM 0x8BDB
+#define GL_STATE_RESTORE 0x8BDC
+#endif
+
+/* GL_QCOM_extended_get2 */
+/* No new tokens introduced by this extension. */
+
+/* GL_QCOM_perfmon_global_mode */
+#ifndef GL_QCOM_perfmon_global_mode
+#define GL_PERFMON_GLOBAL_MODE_QCOM 0x8FA0
+#endif
+
+/* GL_QCOM_writeonly_rendering */
+#ifndef GL_QCOM_writeonly_rendering
+#define GL_WRITEONLY_RENDERING_QCOM 0x8823
+#endif
+
+/* GL_QCOM_tiled_rendering */
+#ifndef GL_QCOM_tiled_rendering
+#define GL_COLOR_BUFFER_BIT0_QCOM 0x00000001
+#define GL_COLOR_BUFFER_BIT1_QCOM 0x00000002
+#define GL_COLOR_BUFFER_BIT2_QCOM 0x00000004
+#define GL_COLOR_BUFFER_BIT3_QCOM 0x00000008
+#define GL_COLOR_BUFFER_BIT4_QCOM 0x00000010
+#define GL_COLOR_BUFFER_BIT5_QCOM 0x00000020
+#define GL_COLOR_BUFFER_BIT6_QCOM 0x00000040
+#define GL_COLOR_BUFFER_BIT7_QCOM 0x00000080
+#define GL_DEPTH_BUFFER_BIT0_QCOM 0x00000100
+#define GL_DEPTH_BUFFER_BIT1_QCOM 0x00000200
+#define GL_DEPTH_BUFFER_BIT2_QCOM 0x00000400
+#define GL_DEPTH_BUFFER_BIT3_QCOM 0x00000800
+#define GL_DEPTH_BUFFER_BIT4_QCOM 0x00001000
+#define GL_DEPTH_BUFFER_BIT5_QCOM 0x00002000
+#define GL_DEPTH_BUFFER_BIT6_QCOM 0x00004000
+#define GL_DEPTH_BUFFER_BIT7_QCOM 0x00008000
+#define GL_STENCIL_BUFFER_BIT0_QCOM 0x00010000
+#define GL_STENCIL_BUFFER_BIT1_QCOM 0x00020000
+#define GL_STENCIL_BUFFER_BIT2_QCOM 0x00040000
+#define GL_STENCIL_BUFFER_BIT3_QCOM 0x00080000
+#define GL_STENCIL_BUFFER_BIT4_QCOM 0x00100000
+#define GL_STENCIL_BUFFER_BIT5_QCOM 0x00200000
+#define GL_STENCIL_BUFFER_BIT6_QCOM 0x00400000
+#define GL_STENCIL_BUFFER_BIT7_QCOM 0x00800000
+#define GL_MULTISAMPLE_BUFFER_BIT0_QCOM 0x01000000
+#define GL_MULTISAMPLE_BUFFER_BIT1_QCOM 0x02000000
+#define GL_MULTISAMPLE_BUFFER_BIT2_QCOM 0x04000000
+#define GL_MULTISAMPLE_BUFFER_BIT3_QCOM 0x08000000
+#define GL_MULTISAMPLE_BUFFER_BIT4_QCOM 0x10000000
+#define GL_MULTISAMPLE_BUFFER_BIT5_QCOM 0x20000000
+#define GL_MULTISAMPLE_BUFFER_BIT6_QCOM 0x40000000
+#define GL_MULTISAMPLE_BUFFER_BIT7_QCOM 0x80000000
+#endif
+
+/*------------------------------------------------------------------------*
+ * VIV extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_VIV_shader_binary */
+#ifndef GL_VIV_shader_binary
+#define GL_SHADER_BINARY_VIV 0x8FC4
+#endif
+
+/*------------------------------------------------------------------------*
+ * End of extension tokens, start of corresponding extension functions
+ *------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------*
+ * OES extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_OES_compressed_ETC1_RGB8_texture */
+#ifndef GL_OES_compressed_ETC1_RGB8_texture
+#define GL_OES_compressed_ETC1_RGB8_texture 1
+#endif
+
+/* GL_OES_compressed_paletted_texture */
+#ifndef GL_OES_compressed_paletted_texture
+#define GL_OES_compressed_paletted_texture 1
+#endif
+
+/* GL_OES_depth24 */
+#ifndef GL_OES_depth24
+#define GL_OES_depth24 1
+#endif
+
+/* GL_OES_depth32 */
+#ifndef GL_OES_depth32
+#define GL_OES_depth32 1
+#endif
+
+/* GL_OES_depth_texture */
+#ifndef GL_OES_depth_texture
+#define GL_OES_depth_texture 1
+#endif
+
+/* GL_OES_EGL_image */
+#ifndef GL_OES_EGL_image
+#define GL_OES_EGL_image 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glEGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image);
+GL_APICALL void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image);
+#endif
+typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image);
+typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image);
+#endif
+
+/* GL_OES_EGL_image_external */
+#ifndef GL_OES_EGL_image_external
+#define GL_OES_EGL_image_external 1
+/* glEGLImageTargetTexture2DOES defined in GL_OES_EGL_image already. */
+#endif
+
+/* GL_OES_element_index_uint */
+#ifndef GL_OES_element_index_uint
+#define GL_OES_element_index_uint 1
+#endif
+
+/* GL_OES_fbo_render_mipmap */
+#ifndef GL_OES_fbo_render_mipmap
+#define GL_OES_fbo_render_mipmap 1
+#endif
+
+/* GL_OES_fragment_precision_high */
+#ifndef GL_OES_fragment_precision_high
+#define GL_OES_fragment_precision_high 1
+#endif
+
+/* GL_OES_get_program_binary */
+#ifndef GL_OES_get_program_binary
+#define GL_OES_get_program_binary 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGetProgramBinaryOES (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary);
+GL_APICALL void GL_APIENTRY glProgramBinaryOES (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length);
+#endif
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMBINARYOESPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary);
+typedef void (GL_APIENTRYP PFNGLPROGRAMBINARYOESPROC) (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length);
+#endif
+
+/* GL_OES_mapbuffer */
+#ifndef GL_OES_mapbuffer
+#define GL_OES_mapbuffer 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void* GL_APIENTRY glMapBufferOES (GLenum target, GLenum access);
+GL_APICALL GLboolean GL_APIENTRY glUnmapBufferOES (GLenum target);
+GL_APICALL void GL_APIENTRY glGetBufferPointervOES (GLenum target, GLenum pname, GLvoid** params);
+#endif
+typedef void* (GL_APIENTRYP PFNGLMAPBUFFEROESPROC) (GLenum target, GLenum access);
+typedef GLboolean (GL_APIENTRYP PFNGLUNMAPBUFFEROESPROC) (GLenum target);
+typedef void (GL_APIENTRYP PFNGLGETBUFFERPOINTERVOESPROC) (GLenum target, GLenum pname, GLvoid** params);
+#endif
+
+/* GL_OES_packed_depth_stencil */
+#ifndef GL_OES_packed_depth_stencil
+#define GL_OES_packed_depth_stencil 1
+#endif
+
+/* GL_OES_required_internalformat */
+#ifndef GL_OES_required_internalformat
+#define GL_OES_required_internalformat 1
+#endif
+
+/* GL_OES_rgb8_rgba8 */
+#ifndef GL_OES_rgb8_rgba8
+#define GL_OES_rgb8_rgba8 1
+#endif
+
+/* GL_OES_standard_derivatives */
+#ifndef GL_OES_standard_derivatives
+#define GL_OES_standard_derivatives 1
+#endif
+
+/* GL_OES_stencil1 */
+#ifndef GL_OES_stencil1
+#define GL_OES_stencil1 1
+#endif
+
+/* GL_OES_stencil4 */
+#ifndef GL_OES_stencil4
+#define GL_OES_stencil4 1
+#endif
+
+#ifndef GL_OES_surfaceless_context
+#define GL_OES_surfaceless_context 1
+#endif
+
+/* GL_OES_texture_3D */
+#ifndef GL_OES_texture_3D
+#define GL_OES_texture_3D 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTexImage3DOES (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+GL_APICALL void GL_APIENTRY glTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels);
+GL_APICALL void GL_APIENTRY glCopyTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glCompressedTexImage3DOES (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data);
+GL_APICALL void GL_APIENTRY glCompressedTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data);
+GL_APICALL void GL_APIENTRY glFramebufferTexture3DOES (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+#endif
+typedef void (GL_APIENTRYP PFNGLTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels);
+typedef void (GL_APIENTRYP PFNGLCOPYTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data);
+typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DOES) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+#endif
+
+/* GL_OES_texture_float */
+#ifndef GL_OES_texture_float
+#define GL_OES_texture_float 1
+#endif
+
+/* GL_OES_texture_float_linear */
+#ifndef GL_OES_texture_float_linear
+#define GL_OES_texture_float_linear 1
+#endif
+
+/* GL_OES_texture_half_float */
+#ifndef GL_OES_texture_half_float
+#define GL_OES_texture_half_float 1
+#endif
+
+/* GL_OES_texture_half_float_linear */
+#ifndef GL_OES_texture_half_float_linear
+#define GL_OES_texture_half_float_linear 1
+#endif
+
+/* GL_OES_texture_npot */
+#ifndef GL_OES_texture_npot
+#define GL_OES_texture_npot 1
+#endif
+
+/* GL_OES_vertex_array_object */
+#ifndef GL_OES_vertex_array_object
+#define GL_OES_vertex_array_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBindVertexArrayOES (GLuint array);
+GL_APICALL void GL_APIENTRY glDeleteVertexArraysOES (GLsizei n, const GLuint *arrays);
+GL_APICALL void GL_APIENTRY glGenVertexArraysOES (GLsizei n, GLuint *arrays);
+GL_APICALL GLboolean GL_APIENTRY glIsVertexArrayOES (GLuint array);
+#endif
+typedef void (GL_APIENTRYP PFNGLBINDVERTEXARRAYOESPROC) (GLuint array);
+typedef void (GL_APIENTRYP PFNGLDELETEVERTEXARRAYSOESPROC) (GLsizei n, const GLuint *arrays);
+typedef void (GL_APIENTRYP PFNGLGENVERTEXARRAYSOESPROC) (GLsizei n, GLuint *arrays);
+typedef GLboolean (GL_APIENTRYP PFNGLISVERTEXARRAYOESPROC) (GLuint array);
+#endif
+
+/* GL_OES_vertex_half_float */
+#ifndef GL_OES_vertex_half_float
+#define GL_OES_vertex_half_float 1
+#endif
+
+/* GL_OES_vertex_type_10_10_10_2 */
+#ifndef GL_OES_vertex_type_10_10_10_2
+#define GL_OES_vertex_type_10_10_10_2 1
+#endif
+
+/*------------------------------------------------------------------------*
+ * KHR extension functions
+ *------------------------------------------------------------------------*/
+
+#ifndef GL_KHR_debug
+#define GL_KHR_debug 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDebugMessageControl (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
+GL_APICALL void GL_APIENTRY glDebugMessageInsert (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);
+GL_APICALL void GL_APIENTRY glDebugMessageCallback (GLDEBUGPROC callback, const void *userParam);
+GL_APICALL GLuint GL_APIENTRY glGetDebugMessageLog (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);
+GL_APICALL void GL_APIENTRY glPushDebugGroup (GLenum source, GLuint id, GLsizei length, const GLchar *message);
+GL_APICALL void GL_APIENTRY glPopDebugGroup (void);
+GL_APICALL void GL_APIENTRY glObjectLabel (GLenum identifier, GLuint name, GLsizei length, const GLchar *label);
+GL_APICALL void GL_APIENTRY glGetObjectLabel (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label);
+GL_APICALL void GL_APIENTRY glObjectPtrLabel (const void *ptr, GLsizei length, const GLchar *label);
+GL_APICALL void GL_APIENTRY glGetObjectPtrLabel (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label);
+GL_APICALL void GL_APIENTRY glGetPointerv (GLenum pname, void **params);
+#endif
+typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
+typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGEINSERTPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);
+typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const void *userParam);
+typedef GLuint (GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGPROC) (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);
+typedef void (GL_APIENTRYP PFNGLPUSHDEBUGGROUPPROC) (GLenum source, GLuint id, GLsizei length, const GLchar *message);
+typedef void (GL_APIENTRYP PFNGLPOPDEBUGGROUPPROC) (void);
+typedef void (GL_APIENTRYP PFNGLOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label);
+typedef void (GL_APIENTRYP PFNGLGETOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label);
+typedef void (GL_APIENTRYP PFNGLOBJECTPTRLABELPROC) (const void *ptr, GLsizei length, const GLchar *label);
+typedef void (GL_APIENTRYP PFNGLGETOBJECTPTRLABELPROC) (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label);
+typedef void (GL_APIENTRYP PFNGLGETPOINTERVPROC) (GLenum pname, void **params);
+#endif
+
+#ifndef GL_KHR_texture_compression_astc_ldr
+#define GL_KHR_texture_compression_astc_ldr 1
+#endif
+
+
+/*------------------------------------------------------------------------*
+ * AMD extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_AMD_compressed_3DC_texture */
+#ifndef GL_AMD_compressed_3DC_texture
+#define GL_AMD_compressed_3DC_texture 1
+#endif
+
+/* GL_AMD_compressed_ATC_texture */
+#ifndef GL_AMD_compressed_ATC_texture
+#define GL_AMD_compressed_ATC_texture 1
+#endif
+
+/* AMD_performance_monitor */
+#ifndef GL_AMD_performance_monitor
+#define GL_AMD_performance_monitor 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGetPerfMonitorGroupsAMD (GLint *numGroups, GLsizei groupsSize, GLuint *groups);
+GL_APICALL void GL_APIENTRY glGetPerfMonitorCountersAMD (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters);
+GL_APICALL void GL_APIENTRY glGetPerfMonitorGroupStringAMD (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString);
+GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterStringAMD (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString);
+GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterInfoAMD (GLuint group, GLuint counter, GLenum pname, GLvoid *data);
+GL_APICALL void GL_APIENTRY glGenPerfMonitorsAMD (GLsizei n, GLuint *monitors);
+GL_APICALL void GL_APIENTRY glDeletePerfMonitorsAMD (GLsizei n, GLuint *monitors);
+GL_APICALL void GL_APIENTRY glSelectPerfMonitorCountersAMD (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList);
+GL_APICALL void GL_APIENTRY glBeginPerfMonitorAMD (GLuint monitor);
+GL_APICALL void GL_APIENTRY glEndPerfMonitorAMD (GLuint monitor);
+GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterDataAMD (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten);
+#endif
+typedef void (GL_APIENTRYP PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint *numGroups, GLsizei groupsSize, GLuint *groups);
+typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters);
+typedef void (GL_APIENTRYP PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString);
+typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString);
+typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, GLvoid *data);
+typedef void (GL_APIENTRYP PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors);
+typedef void (GL_APIENTRYP PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors);
+typedef void (GL_APIENTRYP PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList);
+typedef void (GL_APIENTRYP PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor);
+typedef void (GL_APIENTRYP PFNGLENDPERFMONITORAMDPROC) (GLuint monitor);
+typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten);
+#endif
+
+/* GL_AMD_program_binary_Z400 */
+#ifndef GL_AMD_program_binary_Z400
+#define GL_AMD_program_binary_Z400 1
+#endif
+
+/*------------------------------------------------------------------------*
+ * ANGLE extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_ANGLE_depth_texture */
+#ifndef GL_ANGLE_depth_texture
+#define GL_ANGLE_depth_texture 1
+#endif
+
+/* GL_ANGLE_framebuffer_blit */
+#ifndef GL_ANGLE_framebuffer_blit
+#define GL_ANGLE_framebuffer_blit 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBlitFramebufferANGLE (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#endif
+typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERANGLEPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#endif
+
+/* GL_ANGLE_framebuffer_multisample */
+#ifndef GL_ANGLE_framebuffer_multisample
+#define GL_ANGLE_framebuffer_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleANGLE (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif
+
+#ifndef GL_ANGLE_instanced_arrays
+#define GL_ANGLE_instanced_arrays 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDrawArraysInstancedANGLE (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+GL_APICALL void GL_APIENTRY glDrawElementsInstancedANGLE (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);
+GL_APICALL void GL_APIENTRY glVertexAttribDivisorANGLE (GLuint index, GLuint divisor);
+#endif
+typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDANGLEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDANGLEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISORANGLEPROC) (GLuint index, GLuint divisor);
+#endif
+
+/* GL_ANGLE_pack_reverse_row_order */
+#ifndef GL_ANGLE_pack_reverse_row_order
+#define GL_ANGLE_pack_reverse_row_order 1
+#endif
+
+/* GL_ANGLE_program_binary */
+#ifndef GL_ANGLE_program_binary
+#define GL_ANGLE_program_binary 1
+#endif
+
+/* GL_ANGLE_texture_compression_dxt3 */
+#ifndef GL_ANGLE_texture_compression_dxt3
+#define GL_ANGLE_texture_compression_dxt3 1
+#endif
+
+/* GL_ANGLE_texture_compression_dxt5 */
+#ifndef GL_ANGLE_texture_compression_dxt5
+#define GL_ANGLE_texture_compression_dxt5 1
+#endif
+
+/* GL_ANGLE_texture_usage */
+#ifndef GL_ANGLE_texture_usage
+#define GL_ANGLE_texture_usage 1
+#endif
+
+#ifndef GL_ANGLE_translated_shader_source
+#define GL_ANGLE_translated_shader_source 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGetTranslatedShaderSourceANGLE (GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source);
+#endif
+typedef void (GL_APIENTRYP PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC) (GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source);
+#endif
+
+/*------------------------------------------------------------------------*
+ * APPLE extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_APPLE_copy_texture_levels */
+#ifndef GL_APPLE_copy_texture_levels
+#define GL_APPLE_copy_texture_levels 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glCopyTextureLevelsAPPLE (GLuint destinationTexture, GLuint sourceTexture, GLint sourceBaseLevel, GLsizei sourceLevelCount);
+#endif
+typedef void (GL_APIENTRYP PFNGLCOPYTEXTURELEVELSAPPLEPROC) (GLuint destinationTexture, GLuint sourceTexture, GLint sourceBaseLevel, GLsizei sourceLevelCount);
+#endif
+
+/* GL_APPLE_framebuffer_multisample */
+#ifndef GL_APPLE_framebuffer_multisample
+#define GL_APPLE_framebuffer_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleAPPLE (GLenum, GLsizei, GLenum, GLsizei, GLsizei);
+GL_APICALL void GL_APIENTRY glResolveMultisampleFramebufferAPPLE (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEAPPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLRESOLVEMULTISAMPLEFRAMEBUFFERAPPLEPROC) (void);
+#endif
+
+/* GL_APPLE_rgb_422 */
+#ifndef GL_APPLE_rgb_422
+#define GL_APPLE_rgb_422 1
+#endif
+
+/* GL_APPLE_sync */
+#ifndef GL_APPLE_sync
+#define GL_APPLE_sync 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL GLsync GL_APIENTRY glFenceSyncAPPLE (GLenum condition, GLbitfield flags);
+GL_APICALL GLboolean GL_APIENTRY glIsSyncAPPLE (GLsync sync);
+GL_APICALL void GL_APIENTRY glDeleteSyncAPPLE (GLsync sync);
+GL_APICALL GLenum GL_APIENTRY glClientWaitSyncAPPLE (GLsync sync, GLbitfield flags, GLuint64 timeout);
+GL_APICALL void GL_APIENTRY glWaitSyncAPPLE (GLsync sync, GLbitfield flags, GLuint64 timeout);
+GL_APICALL void GL_APIENTRY glGetInteger64vAPPLE (GLenum pname, GLint64 *params);
+GL_APICALL void GL_APIENTRY glGetSyncivAPPLE (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
+#endif
+typedef GLsync (GL_APIENTRYP PFNGLFENCESYNCAPPLEPROC) (GLenum condition, GLbitfield flags);
+typedef GLboolean (GL_APIENTRYP PFNGLISSYNCAPPLEPROC) (GLsync sync);
+typedef void (GL_APIENTRYP PFNGLDELETESYNCAPPLEPROC) (GLsync sync);
+typedef GLenum (GL_APIENTRYP PFNGLCLIENTWAITSYNCAPPLEPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+typedef void (GL_APIENTRYP PFNGLWAITSYNCAPPLEPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+typedef void (GL_APIENTRYP PFNGLGETINTEGER64VAPPLEPROC) (GLenum pname, GLint64 *params);
+typedef void (GL_APIENTRYP PFNGLGETSYNCIVAPPLEPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
+#endif
+
+/* GL_APPLE_texture_format_BGRA8888 */
+#ifndef GL_APPLE_texture_format_BGRA8888
+#define GL_APPLE_texture_format_BGRA8888 1
+#endif
+
+/* GL_APPLE_texture_max_level */
+#ifndef GL_APPLE_texture_max_level
+#define GL_APPLE_texture_max_level 1
+#endif
+
+/*------------------------------------------------------------------------*
+ * ARM extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_ARM_mali_program_binary */
+#ifndef GL_ARM_mali_program_binary
+#define GL_ARM_mali_program_binary 1
+#endif
+
+/* GL_ARM_mali_shader_binary */
+#ifndef GL_ARM_mali_shader_binary
+#define GL_ARM_mali_shader_binary 1
+#endif
+
+/* GL_ARM_rgba8 */
+#ifndef GL_ARM_rgba8
+#define GL_ARM_rgba8 1
+#endif
+
+/*------------------------------------------------------------------------*
+ * EXT extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_EXT_blend_minmax */
+#ifndef GL_EXT_blend_minmax
+#define GL_EXT_blend_minmax 1
+#endif
+
+/* GL_EXT_color_buffer_half_float */
+#ifndef GL_EXT_color_buffer_half_float
+#define GL_EXT_color_buffer_half_float 1
+#endif
+
+/* GL_EXT_debug_label */
+#ifndef GL_EXT_debug_label
+#define GL_EXT_debug_label 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glLabelObjectEXT (GLenum type, GLuint object, GLsizei length, const GLchar *label);
+GL_APICALL void GL_APIENTRY glGetObjectLabelEXT (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label);
+#endif
+typedef void (GL_APIENTRYP PFNGLLABELOBJECTEXTPROC) (GLenum type, GLuint object, GLsizei length, const GLchar *label);
+typedef void (GL_APIENTRYP PFNGLGETOBJECTLABELEXTPROC) (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label);
+#endif
+
+/* GL_EXT_debug_marker */
+#ifndef GL_EXT_debug_marker
+#define GL_EXT_debug_marker 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glInsertEventMarkerEXT (GLsizei length, const GLchar *marker);
+GL_APICALL void GL_APIENTRY glPushGroupMarkerEXT (GLsizei length, const GLchar *marker);
+GL_APICALL void GL_APIENTRY glPopGroupMarkerEXT (void);
+#endif
+typedef void (GL_APIENTRYP PFNGLINSERTEVENTMARKEREXTPROC) (GLsizei length, const GLchar *marker);
+typedef void (GL_APIENTRYP PFNGLPUSHGROUPMARKEREXTPROC) (GLsizei length, const GLchar *marker);
+typedef void (GL_APIENTRYP PFNGLPOPGROUPMARKEREXTPROC) (void);
+#endif
+
+/* GL_EXT_discard_framebuffer */
+#ifndef GL_EXT_discard_framebuffer
+#define GL_EXT_discard_framebuffer 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDiscardFramebufferEXT (GLenum target, GLsizei numAttachments, const GLenum *attachments);
+#endif
+typedef void (GL_APIENTRYP PFNGLDISCARDFRAMEBUFFEREXTPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments);
+#endif
+
+/* GL_EXT_map_buffer_range */
+#ifndef GL_EXT_map_buffer_range
+#define GL_EXT_map_buffer_range 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void* GL_APIENTRY glMapBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+GL_APICALL void GL_APIENTRY glFlushMappedBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length);
+#endif
+typedef void* (GL_APIENTRYP PFNGLMAPBUFFERRANGEEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+typedef void (GL_APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr length);
+#endif
+
+/* GL_EXT_multisampled_render_to_texture */
+#ifndef GL_EXT_multisampled_render_to_texture
+#define GL_EXT_multisampled_render_to_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleEXT (GLenum, GLsizei, GLenum, GLsizei, GLsizei);
+GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleEXT (GLenum, GLenum, GLenum, GLuint, GLint, GLsizei);
+#endif
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+#endif
+
+/* GL_EXT_multiview_draw_buffers */
+#ifndef GL_EXT_multiview_draw_buffers
+#define GL_EXT_multiview_draw_buffers 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glReadBufferIndexedEXT (GLenum src, GLint index);
+GL_APICALL void GL_APIENTRY glDrawBuffersIndexedEXT (GLint n, const GLenum *location, const GLint *indices);
+GL_APICALL void GL_APIENTRY glGetIntegeri_vEXT (GLenum target, GLuint index, GLint *data);
+#endif
+typedef void (GL_APIENTRYP PFNGLREADBUFFERINDEXEDEXTPROC) (GLenum src, GLint index);
+typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSINDEXEDEXTPROC) (GLint n, const GLenum *location, const GLint *indices);
+typedef void (GL_APIENTRYP PFNGLGETINTEGERI_VEXTPROC) (GLenum target, GLuint index, GLint *data);
+#endif
+
+#ifndef GL_EXT_multi_draw_arrays
+#define GL_EXT_multi_draw_arrays 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glMultiDrawArraysEXT (GLenum, const GLint *, const GLsizei *, GLsizei);
+GL_APICALL void GL_APIENTRY glMultiDrawElementsEXT (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (GL_APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount);
+typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
+#endif
+
+/* GL_EXT_occlusion_query_boolean */
+#ifndef GL_EXT_occlusion_query_boolean
+#define GL_EXT_occlusion_query_boolean 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGenQueriesEXT (GLsizei n, GLuint *ids);
+GL_APICALL void GL_APIENTRY glDeleteQueriesEXT (GLsizei n, const GLuint *ids);
+GL_APICALL GLboolean GL_APIENTRY glIsQueryEXT (GLuint id);
+GL_APICALL void GL_APIENTRY glBeginQueryEXT (GLenum target, GLuint id);
+GL_APICALL void GL_APIENTRY glEndQueryEXT (GLenum target);
+GL_APICALL void GL_APIENTRY glGetQueryivEXT (GLenum target, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetQueryObjectuivEXT (GLuint id, GLenum pname, GLuint *params);
+#endif
+typedef void (GL_APIENTRYP PFNGLGENQUERIESEXTPROC) (GLsizei n, GLuint *ids);
+typedef void (GL_APIENTRYP PFNGLDELETEQUERIESEXTPROC) (GLsizei n, const GLuint *ids);
+typedef GLboolean (GL_APIENTRYP PFNGLISQUERYEXTPROC) (GLuint id);
+typedef void (GL_APIENTRYP PFNGLBEGINQUERYEXTPROC) (GLenum target, GLuint id);
+typedef void (GL_APIENTRYP PFNGLENDQUERYEXTPROC) (GLenum target);
+typedef void (GL_APIENTRYP PFNGLGETQUERYIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUIVEXTPROC) (GLuint id, GLenum pname, GLuint *params);
+#endif
+
+/* GL_EXT_read_format_bgra */
+#ifndef GL_EXT_read_format_bgra
+#define GL_EXT_read_format_bgra 1
+#endif
+
+/* GL_EXT_robustness */
+#ifndef GL_EXT_robustness
+#define GL_EXT_robustness 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL GLenum GL_APIENTRY glGetGraphicsResetStatusEXT (void);
+GL_APICALL void GL_APIENTRY glReadnPixelsEXT (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data);
+GL_APICALL void GL_APIENTRY glGetnUniformfvEXT (GLuint program, GLint location, GLsizei bufSize, float *params);
+GL_APICALL void GL_APIENTRY glGetnUniformivEXT (GLuint program, GLint location, GLsizei bufSize, GLint *params);
+#endif
+typedef GLenum (GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSEXTPROC) (void);
+typedef void (GL_APIENTRYP PFNGLREADNPIXELSEXTPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data);
+typedef void (GL_APIENTRYP PFNGLGETNUNIFORMFVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, float *params);
+typedef void (GL_APIENTRYP PFNGLGETNUNIFORMIVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params);
+#endif
+
+/* GL_EXT_separate_shader_objects */
+#ifndef GL_EXT_separate_shader_objects
+#define GL_EXT_separate_shader_objects 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glUseProgramStagesEXT (GLuint pipeline, GLbitfield stages, GLuint program);
+GL_APICALL void GL_APIENTRY glActiveShaderProgramEXT (GLuint pipeline, GLuint program);
+GL_APICALL GLuint GL_APIENTRY glCreateShaderProgramvEXT (GLenum type, GLsizei count, const GLchar **strings);
+GL_APICALL void GL_APIENTRY glBindProgramPipelineEXT (GLuint pipeline);
+GL_APICALL void GL_APIENTRY glDeleteProgramPipelinesEXT (GLsizei n, const GLuint *pipelines);
+GL_APICALL void GL_APIENTRY glGenProgramPipelinesEXT (GLsizei n, GLuint *pipelines);
+GL_APICALL GLboolean GL_APIENTRY glIsProgramPipelineEXT (GLuint pipeline);
+GL_APICALL void GL_APIENTRY glProgramParameteriEXT (GLuint program, GLenum pname, GLint value);
+GL_APICALL void GL_APIENTRY glGetProgramPipelineivEXT (GLuint pipeline, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glProgramUniform1iEXT (GLuint program, GLint location, GLint x);
+GL_APICALL void GL_APIENTRY glProgramUniform2iEXT (GLuint program, GLint location, GLint x, GLint y);
+GL_APICALL void GL_APIENTRY glProgramUniform3iEXT (GLuint program, GLint location, GLint x, GLint y, GLint z);
+GL_APICALL void GL_APIENTRY glProgramUniform4iEXT (GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w);
+GL_APICALL void GL_APIENTRY glProgramUniform1fEXT (GLuint program, GLint location, GLfloat x);
+GL_APICALL void GL_APIENTRY glProgramUniform2fEXT (GLuint program, GLint location, GLfloat x, GLfloat y);
+GL_APICALL void GL_APIENTRY glProgramUniform3fEXT (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z);
+GL_APICALL void GL_APIENTRY glProgramUniform4fEXT (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GL_APICALL void GL_APIENTRY glProgramUniform1ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform2ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform3ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform4ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform1fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniform2fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniform3fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniform4fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glValidateProgramPipelineEXT (GLuint pipeline);
+GL_APICALL void GL_APIENTRY glGetProgramPipelineInfoLogEXT (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+#endif
+typedef void (GL_APIENTRYP PFNGLUSEPROGRAMSTAGESEXTPROC) (GLuint pipeline, GLbitfield stages, GLuint program);
+typedef void (GL_APIENTRYP PFNGLACTIVESHADERPROGRAMEXTPROC) (GLuint pipeline, GLuint program);
+typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROGRAMVEXTPROC) (GLenum type, GLsizei count, const GLchar **strings);
+typedef void (GL_APIENTRYP PFNGLBINDPROGRAMPIPELINEEXTPROC) (GLuint pipeline);
+typedef void (GL_APIENTRYP PFNGLDELETEPROGRAMPIPELINESEXTPROC) (GLsizei n, const GLuint *pipelines);
+typedef void (GL_APIENTRYP PFNGLGENPROGRAMPIPELINESEXTPROC) (GLsizei n, GLuint *pipelines);
+typedef GLboolean (GL_APIENTRYP PFNGLISPROGRAMPIPELINEEXTPROC) (GLuint pipeline);
+typedef void (GL_APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEIVEXTPROC) (GLuint pipeline, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint x);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint x, GLint y);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint x, GLint y, GLint z);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat x);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat x, GLfloat y);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLVALIDATEPROGRAMPIPELINEEXTPROC) (GLuint pipeline);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGEXTPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+#endif
+
+/* GL_EXT_shader_framebuffer_fetch */
+#ifndef GL_EXT_shader_framebuffer_fetch
+#define GL_EXT_shader_framebuffer_fetch 1
+#endif
+
+/* GL_EXT_shader_texture_lod */
+#ifndef GL_EXT_shader_texture_lod
+#define GL_EXT_shader_texture_lod 1
+#endif
+
+/* GL_EXT_shadow_samplers */
+#ifndef GL_EXT_shadow_samplers
+#define GL_EXT_shadow_samplers 1
+#endif
+
+/* GL_EXT_sRGB */
+#ifndef GL_EXT_sRGB
+#define GL_EXT_sRGB 1
+#endif
+
+/* GL_EXT_texture_compression_dxt1 */
+#ifndef GL_EXT_texture_compression_dxt1
+#define GL_EXT_texture_compression_dxt1 1
+#endif
+
+/* GL_EXT_texture_filter_anisotropic */
+#ifndef GL_EXT_texture_filter_anisotropic
+#define GL_EXT_texture_filter_anisotropic 1
+#endif
+
+/* GL_EXT_texture_format_BGRA8888 */
+#ifndef GL_EXT_texture_format_BGRA8888
+#define GL_EXT_texture_format_BGRA8888 1
+#endif
+
+/* GL_EXT_texture_rg */
+#ifndef GL_EXT_texture_rg
+#define GL_EXT_texture_rg 1
+#endif
+
+/* GL_EXT_texture_storage */
+#ifndef GL_EXT_texture_storage
+#define GL_EXT_texture_storage 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTexStorage1DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+GL_APICALL void GL_APIENTRY glTexStorage2DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glTexStorage3DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+GL_APICALL void GL_APIENTRY glTextureStorage1DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+GL_APICALL void GL_APIENTRY glTextureStorage2DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glTextureStorage3DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+#endif
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGE1DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGE2DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGE3DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE1DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+#endif
+
+/* GL_EXT_texture_type_2_10_10_10_REV */
+#ifndef GL_EXT_texture_type_2_10_10_10_REV
+#define GL_EXT_texture_type_2_10_10_10_REV 1
+#endif
+
+/* GL_EXT_unpack_subimage */
+#ifndef GL_EXT_unpack_subimage
+#define GL_EXT_unpack_subimage 1
+#endif
+
+/*------------------------------------------------------------------------*
+ * DMP extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_DMP_shader_binary */
+#ifndef GL_DMP_shader_binary
+#define GL_DMP_shader_binary 1
+#endif
+
+/*------------------------------------------------------------------------*
+ * FJ extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_FJ_shader_binary_GCCSO */
+#ifndef GL_FJ_shader_binary_GCCSO
+#define GL_FJ_shader_binary_GCCSO 1
+#endif
+
+/*------------------------------------------------------------------------*
+ * IMG extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_IMG_program_binary */
+#ifndef GL_IMG_program_binary
+#define GL_IMG_program_binary 1
+#endif
+
+/* GL_IMG_read_format */
+#ifndef GL_IMG_read_format
+#define GL_IMG_read_format 1
+#endif
+
+/* GL_IMG_shader_binary */
+#ifndef GL_IMG_shader_binary
+#define GL_IMG_shader_binary 1
+#endif
+
+/* GL_IMG_texture_compression_pvrtc */
+#ifndef GL_IMG_texture_compression_pvrtc
+#define GL_IMG_texture_compression_pvrtc 1
+#endif
+
+/* GL_IMG_texture_compression_pvrtc2 */
+#ifndef GL_IMG_texture_compression_pvrtc2
+#define GL_IMG_texture_compression_pvrtc2 1
+#endif
+
+/* GL_IMG_multisampled_render_to_texture */
+#ifndef GL_IMG_multisampled_render_to_texture
+#define GL_IMG_multisampled_render_to_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleIMG (GLenum, GLsizei, GLenum, GLsizei, GLsizei);
+GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleIMG (GLenum, GLenum, GLenum, GLuint, GLint, GLsizei);
+#endif
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMGPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMGPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+#endif
+
+/*------------------------------------------------------------------------*
+ * NV extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_NV_coverage_sample */
+#ifndef GL_NV_coverage_sample
+#define GL_NV_coverage_sample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glCoverageMaskNV (GLboolean mask);
+GL_APICALL void GL_APIENTRY glCoverageOperationNV (GLenum operation);
+#endif
+typedef void (GL_APIENTRYP PFNGLCOVERAGEMASKNVPROC) (GLboolean mask);
+typedef void (GL_APIENTRYP PFNGLCOVERAGEOPERATIONNVPROC) (GLenum operation);
+#endif
+
+/* GL_NV_depth_nonlinear */
+#ifndef GL_NV_depth_nonlinear
+#define GL_NV_depth_nonlinear 1
+#endif
+
+/* GL_NV_draw_buffers */
+#ifndef GL_NV_draw_buffers
+#define GL_NV_draw_buffers 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDrawBuffersNV (GLsizei n, const GLenum *bufs);
+#endif
+typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSNVPROC) (GLsizei n, const GLenum *bufs);
+#endif
+
+/* GL_EXT_draw_buffers */
+#ifndef GL_EXT_draw_buffers
+#define GL_EXT_draw_buffers 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDrawBuffersEXT (GLsizei n, const GLenum *bufs);
+#endif
+typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSEXTPROC) (GLsizei n, const GLenum *bufs);
+#endif
+
+/* GL_NV_draw_instanced */
+#ifndef GL_NV_draw_instanced
+#define GL_NV_draw_instanced 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDrawArraysInstancedNV (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+GL_APICALL void GL_APIENTRY glDrawElementsInstancedNV (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
+#endif
+typedef void (GL_APIENTRYP PFNDRAWARRAYSINSTANCEDNVPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+typedef void (GL_APIENTRYP PFNDRAWELEMENTSINSTANCEDNVPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
+#endif
+
+/* GL_NV_fbo_color_attachments */
+#ifndef GL_NV_fbo_color_attachments
+#define GL_NV_fbo_color_attachments 1
+#endif
+
+/* GL_NV_fence */
+#ifndef GL_NV_fence
+#define GL_NV_fence 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDeleteFencesNV (GLsizei, const GLuint *);
+GL_APICALL void GL_APIENTRY glGenFencesNV (GLsizei, GLuint *);
+GL_APICALL GLboolean GL_APIENTRY glIsFenceNV (GLuint);
+GL_APICALL GLboolean GL_APIENTRY glTestFenceNV (GLuint);
+GL_APICALL void GL_APIENTRY glGetFenceivNV (GLuint, GLenum, GLint *);
+GL_APICALL void GL_APIENTRY glFinishFenceNV (GLuint);
+GL_APICALL void GL_APIENTRY glSetFenceNV (GLuint, GLenum);
+#endif
+typedef void (GL_APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences);
+typedef void (GL_APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences);
+typedef GLboolean (GL_APIENTRYP PFNGLISFENCENVPROC) (GLuint fence);
+typedef GLboolean (GL_APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence);
+typedef void (GL_APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence);
+typedef void (GL_APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition);
+#endif
+
+/* GL_NV_framebuffer_blit */
+#ifndef GL_NV_framebuffer_blit
+#define GL_NV_framebuffer_blit 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBlitFramebufferNV (int srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#endif
+typedef void (GL_APIENTRYP PFNBLITFRAMEBUFFERNVPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#endif
+
+/* GL_NV_framebuffer_multisample */
+#ifndef GL_NV_framebuffer_multisample
+#define GL_NV_framebuffer_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleNV ( GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif
+typedef void (GL_APIENTRYP PFNRENDERBUFFERSTORAGEMULTISAMPLENVPROC) ( GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif
+
+/* GL_NV_generate_mipmap_sRGB */
+#ifndef GL_NV_generate_mipmap_sRGB
+#define GL_NV_generate_mipmap_sRGB 1
+#endif
+
+/* GL_NV_instanced_arrays */
+#ifndef GL_NV_instanced_arrays
+#define GL_NV_instanced_arrays 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glVertexAttribDivisorNV (GLuint index, GLuint divisor);
+#endif
+typedef void (GL_APIENTRYP PFNVERTEXATTRIBDIVISORNVPROC) (GLuint index, GLuint divisor);
+#endif
+
+/* GL_NV_read_buffer */
+#ifndef GL_NV_read_buffer
+#define GL_NV_read_buffer 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glReadBufferNV (GLenum mode);
+#endif
+typedef void (GL_APIENTRYP PFNGLREADBUFFERNVPROC) (GLenum mode);
+#endif
+
+/* GL_NV_read_buffer_front */
+#ifndef GL_NV_read_buffer_front
+#define GL_NV_read_buffer_front 1
+#endif
+
+/* GL_NV_read_depth */
+#ifndef GL_NV_read_depth
+#define GL_NV_read_depth 1
+#endif
+
+/* GL_NV_read_depth_stencil */
+#ifndef GL_NV_read_depth_stencil
+#define GL_NV_read_depth_stencil 1
+#endif
+
+/* GL_NV_read_stencil */
+#ifndef GL_NV_read_stencil
+#define GL_NV_read_stencil 1
+#endif
+
+/* GL_NV_shadow_samplers_array */
+#ifndef GL_NV_shadow_samplers_array
+#define GL_NV_shadow_samplers_array 1
+#endif
+
+/* GL_NV_shadow_samplers_cube */
+#ifndef GL_NV_shadow_samplers_cube
+#define GL_NV_shadow_samplers_cube 1
+#endif
+
+/* GL_NV_sRGB_formats */
+#ifndef GL_NV_sRGB_formats
+#define GL_NV_sRGB_formats 1
+#endif
+
+/* GL_NV_texture_border_clamp */
+#ifndef GL_NV_texture_border_clamp
+#define GL_NV_texture_border_clamp 1
+#endif
+
+/* GL_NV_texture_compression_s3tc_update */
+#ifndef GL_NV_texture_compression_s3tc_update
+#define GL_NV_texture_compression_s3tc_update 1
+#endif
+
+/* GL_NV_texture_npot_2D_mipmap */
+#ifndef GL_NV_texture_npot_2D_mipmap
+#define GL_NV_texture_npot_2D_mipmap 1
+#endif
+
+/*------------------------------------------------------------------------*
+ * QCOM extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_QCOM_alpha_test */
+#ifndef GL_QCOM_alpha_test
+#define GL_QCOM_alpha_test 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glAlphaFuncQCOM (GLenum func, GLclampf ref);
+#endif
+typedef void (GL_APIENTRYP PFNGLALPHAFUNCQCOMPROC) (GLenum func, GLclampf ref);
+#endif
+
+/* GL_QCOM_binning_control */
+#ifndef GL_QCOM_binning_control
+#define GL_QCOM_binning_control 1
+#endif
+
+/* GL_QCOM_driver_control */
+#ifndef GL_QCOM_driver_control
+#define GL_QCOM_driver_control 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGetDriverControlsQCOM (GLint *num, GLsizei size, GLuint *driverControls);
+GL_APICALL void GL_APIENTRY glGetDriverControlStringQCOM (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString);
+GL_APICALL void GL_APIENTRY glEnableDriverControlQCOM (GLuint driverControl);
+GL_APICALL void GL_APIENTRY glDisableDriverControlQCOM (GLuint driverControl);
+#endif
+typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSQCOMPROC) (GLint *num, GLsizei size, GLuint *driverControls);
+typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSTRINGQCOMPROC) (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString);
+typedef void (GL_APIENTRYP PFNGLENABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl);
+typedef void (GL_APIENTRYP PFNGLDISABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl);
+#endif
+
+/* GL_QCOM_extended_get */
+#ifndef GL_QCOM_extended_get
+#define GL_QCOM_extended_get 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glExtGetTexturesQCOM (GLuint *textures, GLint maxTextures, GLint *numTextures);
+GL_APICALL void GL_APIENTRY glExtGetBuffersQCOM (GLuint *buffers, GLint maxBuffers, GLint *numBuffers);
+GL_APICALL void GL_APIENTRY glExtGetRenderbuffersQCOM (GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers);
+GL_APICALL void GL_APIENTRY glExtGetFramebuffersQCOM (GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers);
+GL_APICALL void GL_APIENTRY glExtGetTexLevelParameterivQCOM (GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glExtTexObjectStateOverrideiQCOM (GLenum target, GLenum pname, GLint param);
+GL_APICALL void GL_APIENTRY glExtGetTexSubImageQCOM (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels);
+GL_APICALL void GL_APIENTRY glExtGetBufferPointervQCOM (GLenum target, GLvoid **params);
+#endif
+typedef void (GL_APIENTRYP PFNGLEXTGETTEXTURESQCOMPROC) (GLuint *textures, GLint maxTextures, GLint *numTextures);
+typedef void (GL_APIENTRYP PFNGLEXTGETBUFFERSQCOMPROC) (GLuint *buffers, GLint maxBuffers, GLint *numBuffers);
+typedef void (GL_APIENTRYP PFNGLEXTGETRENDERBUFFERSQCOMPROC) (GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers);
+typedef void (GL_APIENTRYP PFNGLEXTGETFRAMEBUFFERSQCOMPROC) (GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers);
+typedef void (GL_APIENTRYP PFNGLEXTGETTEXLEVELPARAMETERIVQCOMPROC) (GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLEXTTEXOBJECTSTATEOVERRIDEIQCOMPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (GL_APIENTRYP PFNGLEXTGETTEXSUBIMAGEQCOMPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels);
+typedef void (GL_APIENTRYP PFNGLEXTGETBUFFERPOINTERVQCOMPROC) (GLenum target, GLvoid **params);
+#endif
+
+/* GL_QCOM_extended_get2 */
+#ifndef GL_QCOM_extended_get2
+#define GL_QCOM_extended_get2 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glExtGetShadersQCOM (GLuint *shaders, GLint maxShaders, GLint *numShaders);
+GL_APICALL void GL_APIENTRY glExtGetProgramsQCOM (GLuint *programs, GLint maxPrograms, GLint *numPrograms);
+GL_APICALL GLboolean GL_APIENTRY glExtIsProgramBinaryQCOM (GLuint program);
+GL_APICALL void GL_APIENTRY glExtGetProgramBinarySourceQCOM (GLuint program, GLenum shadertype, GLchar *source, GLint *length);
+#endif
+typedef void (GL_APIENTRYP PFNGLEXTGETSHADERSQCOMPROC) (GLuint *shaders, GLint maxShaders, GLint *numShaders);
+typedef void (GL_APIENTRYP PFNGLEXTGETPROGRAMSQCOMPROC) (GLuint *programs, GLint maxPrograms, GLint *numPrograms);
+typedef GLboolean (GL_APIENTRYP PFNGLEXTISPROGRAMBINARYQCOMPROC) (GLuint program);
+typedef void (GL_APIENTRYP PFNGLEXTGETPROGRAMBINARYSOURCEQCOMPROC) (GLuint program, GLenum shadertype, GLchar *source, GLint *length);
+#endif
+
+/* GL_QCOM_perfmon_global_mode */
+#ifndef GL_QCOM_perfmon_global_mode
+#define GL_QCOM_perfmon_global_mode 1
+#endif
+
+/* GL_QCOM_writeonly_rendering */
+#ifndef GL_QCOM_writeonly_rendering
+#define GL_QCOM_writeonly_rendering 1
+#endif
+
+/* GL_QCOM_tiled_rendering */
+#ifndef GL_QCOM_tiled_rendering
+#define GL_QCOM_tiled_rendering 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glStartTilingQCOM (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask);
+GL_APICALL void GL_APIENTRY glEndTilingQCOM (GLbitfield preserveMask);
+#endif
+typedef void (GL_APIENTRYP PFNGLSTARTTILINGQCOMPROC) (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask);
+typedef void (GL_APIENTRYP PFNGLENDTILINGQCOMPROC) (GLbitfield preserveMask);
+#endif
+
+/*------------------------------------------------------------------------*
+ * VIV extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_VIV_shader_binary */
+#ifndef GL_VIV_shader_binary
+#define GL_VIV_shader_binary 1
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gl2ext_h_ */
diff --git a/src/external/ANGLE/GLES2/gl2platform.h b/src/external/ANGLE/GLES2/gl2platform.h
new file mode 100644
index 000000000..c9fa3c4d6
--- /dev/null
+++ b/src/external/ANGLE/GLES2/gl2platform.h
@@ -0,0 +1,30 @@
+#ifndef __gl2platform_h_
+#define __gl2platform_h_
+
+/* $Revision: 10602 $ on $Date:: 2010-03-04 22:35:34 -0800 #$ */
+
+/*
+ * This document is licensed under the SGI Free Software B License Version
+ * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ .
+ */
+
+/* Platform-specific types and definitions for OpenGL ES 2.X gl2.h
+ *
+ * Adopters may modify khrplatform.h and this file to suit their platform.
+ * You are encouraged to submit all modifications to the Khronos group so that
+ * they can be included in future versions of this file. Please submit changes
+ * by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla)
+ * by filing a bug against product "OpenGL-ES" component "Registry".
+ */
+
+#include
+
+#ifndef GL_APICALL
+#define GL_APICALL KHRONOS_APICALL
+#endif
+
+#ifndef GL_APIENTRY
+#define GL_APIENTRY KHRONOS_APIENTRY
+#endif
+
+#endif /* __gl2platform_h_ */
diff --git a/src/external/ANGLE/GLES3/gl3.h b/src/external/ANGLE/GLES3/gl3.h
new file mode 100644
index 000000000..9c79862c0
--- /dev/null
+++ b/src/external/ANGLE/GLES3/gl3.h
@@ -0,0 +1,1061 @@
+#ifndef __gl3_h_
+#define __gl3_h_
+
+/*
+ * gl3.h last updated on $Date: 2013-02-12 14:37:24 -0800 (Tue, 12 Feb 2013) $
+ */
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright (c) 2007-2013 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+/*-------------------------------------------------------------------------
+ * Data type definitions
+ *-----------------------------------------------------------------------*/
+
+/* OpenGL ES 2.0 */
+
+typedef void GLvoid;
+typedef char GLchar;
+typedef unsigned int GLenum;
+typedef unsigned char GLboolean;
+typedef unsigned int GLbitfield;
+typedef khronos_int8_t GLbyte;
+typedef short GLshort;
+typedef int GLint;
+typedef int GLsizei;
+typedef khronos_uint8_t GLubyte;
+typedef unsigned short GLushort;
+typedef unsigned int GLuint;
+typedef khronos_float_t GLfloat;
+typedef khronos_float_t GLclampf;
+typedef khronos_int32_t GLfixed;
+typedef khronos_intptr_t GLintptr;
+typedef khronos_ssize_t GLsizeiptr;
+
+/* OpenGL ES 3.0 */
+
+typedef unsigned short GLhalf;
+typedef khronos_int64_t GLint64;
+typedef khronos_uint64_t GLuint64;
+typedef struct __GLsync *GLsync;
+
+/*-------------------------------------------------------------------------
+ * Token definitions
+ *-----------------------------------------------------------------------*/
+
+/* OpenGL ES core versions */
+#define GL_ES_VERSION_3_0 1
+#define GL_ES_VERSION_2_0 1
+
+/* OpenGL ES 2.0 */
+
+/* ClearBufferMask */
+#define GL_DEPTH_BUFFER_BIT 0x00000100
+#define GL_STENCIL_BUFFER_BIT 0x00000400
+#define GL_COLOR_BUFFER_BIT 0x00004000
+
+/* Boolean */
+#define GL_FALSE 0
+#define GL_TRUE 1
+
+/* BeginMode */
+#define GL_POINTS 0x0000
+#define GL_LINES 0x0001
+#define GL_LINE_LOOP 0x0002
+#define GL_LINE_STRIP 0x0003
+#define GL_TRIANGLES 0x0004
+#define GL_TRIANGLE_STRIP 0x0005
+#define GL_TRIANGLE_FAN 0x0006
+
+/* BlendingFactorDest */
+#define GL_ZERO 0
+#define GL_ONE 1
+#define GL_SRC_COLOR 0x0300
+#define GL_ONE_MINUS_SRC_COLOR 0x0301
+#define GL_SRC_ALPHA 0x0302
+#define GL_ONE_MINUS_SRC_ALPHA 0x0303
+#define GL_DST_ALPHA 0x0304
+#define GL_ONE_MINUS_DST_ALPHA 0x0305
+
+/* BlendingFactorSrc */
+/* GL_ZERO */
+/* GL_ONE */
+#define GL_DST_COLOR 0x0306
+#define GL_ONE_MINUS_DST_COLOR 0x0307
+#define GL_SRC_ALPHA_SATURATE 0x0308
+/* GL_SRC_ALPHA */
+/* GL_ONE_MINUS_SRC_ALPHA */
+/* GL_DST_ALPHA */
+/* GL_ONE_MINUS_DST_ALPHA */
+
+/* BlendEquationSeparate */
+#define GL_FUNC_ADD 0x8006
+#define GL_BLEND_EQUATION 0x8009
+#define GL_BLEND_EQUATION_RGB 0x8009 /* same as BLEND_EQUATION */
+#define GL_BLEND_EQUATION_ALPHA 0x883D
+
+/* BlendSubtract */
+#define GL_FUNC_SUBTRACT 0x800A
+#define GL_FUNC_REVERSE_SUBTRACT 0x800B
+
+/* Separate Blend Functions */
+#define GL_BLEND_DST_RGB 0x80C8
+#define GL_BLEND_SRC_RGB 0x80C9
+#define GL_BLEND_DST_ALPHA 0x80CA
+#define GL_BLEND_SRC_ALPHA 0x80CB
+#define GL_CONSTANT_COLOR 0x8001
+#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
+#define GL_CONSTANT_ALPHA 0x8003
+#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
+#define GL_BLEND_COLOR 0x8005
+
+/* Buffer Objects */
+#define GL_ARRAY_BUFFER 0x8892
+#define GL_ELEMENT_ARRAY_BUFFER 0x8893
+#define GL_ARRAY_BUFFER_BINDING 0x8894
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
+
+#define GL_STREAM_DRAW 0x88E0
+#define GL_STATIC_DRAW 0x88E4
+#define GL_DYNAMIC_DRAW 0x88E8
+
+#define GL_BUFFER_SIZE 0x8764
+#define GL_BUFFER_USAGE 0x8765
+
+#define GL_CURRENT_VERTEX_ATTRIB 0x8626
+
+/* CullFaceMode */
+#define GL_FRONT 0x0404
+#define GL_BACK 0x0405
+#define GL_FRONT_AND_BACK 0x0408
+
+/* DepthFunction */
+/* GL_NEVER */
+/* GL_LESS */
+/* GL_EQUAL */
+/* GL_LEQUAL */
+/* GL_GREATER */
+/* GL_NOTEQUAL */
+/* GL_GEQUAL */
+/* GL_ALWAYS */
+
+/* EnableCap */
+#define GL_TEXTURE_2D 0x0DE1
+#define GL_CULL_FACE 0x0B44
+#define GL_BLEND 0x0BE2
+#define GL_DITHER 0x0BD0
+#define GL_STENCIL_TEST 0x0B90
+#define GL_DEPTH_TEST 0x0B71
+#define GL_SCISSOR_TEST 0x0C11
+#define GL_POLYGON_OFFSET_FILL 0x8037
+#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
+#define GL_SAMPLE_COVERAGE 0x80A0
+
+/* ErrorCode */
+#define GL_NO_ERROR 0
+#define GL_INVALID_ENUM 0x0500
+#define GL_INVALID_VALUE 0x0501
+#define GL_INVALID_OPERATION 0x0502
+#define GL_OUT_OF_MEMORY 0x0505
+
+/* FrontFaceDirection */
+#define GL_CW 0x0900
+#define GL_CCW 0x0901
+
+/* GetPName */
+#define GL_LINE_WIDTH 0x0B21
+#define GL_ALIASED_POINT_SIZE_RANGE 0x846D
+#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
+#define GL_CULL_FACE_MODE 0x0B45
+#define GL_FRONT_FACE 0x0B46
+#define GL_DEPTH_RANGE 0x0B70
+#define GL_DEPTH_WRITEMASK 0x0B72
+#define GL_DEPTH_CLEAR_VALUE 0x0B73
+#define GL_DEPTH_FUNC 0x0B74
+#define GL_STENCIL_CLEAR_VALUE 0x0B91
+#define GL_STENCIL_FUNC 0x0B92
+#define GL_STENCIL_FAIL 0x0B94
+#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95
+#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96
+#define GL_STENCIL_REF 0x0B97
+#define GL_STENCIL_VALUE_MASK 0x0B93
+#define GL_STENCIL_WRITEMASK 0x0B98
+#define GL_STENCIL_BACK_FUNC 0x8800
+#define GL_STENCIL_BACK_FAIL 0x8801
+#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802
+#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803
+#define GL_STENCIL_BACK_REF 0x8CA3
+#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4
+#define GL_STENCIL_BACK_WRITEMASK 0x8CA5
+#define GL_VIEWPORT 0x0BA2
+#define GL_SCISSOR_BOX 0x0C10
+/* GL_SCISSOR_TEST */
+#define GL_COLOR_CLEAR_VALUE 0x0C22
+#define GL_COLOR_WRITEMASK 0x0C23
+#define GL_UNPACK_ALIGNMENT 0x0CF5
+#define GL_PACK_ALIGNMENT 0x0D05
+#define GL_MAX_TEXTURE_SIZE 0x0D33
+#define GL_MAX_VIEWPORT_DIMS 0x0D3A
+#define GL_SUBPIXEL_BITS 0x0D50
+#define GL_RED_BITS 0x0D52
+#define GL_GREEN_BITS 0x0D53
+#define GL_BLUE_BITS 0x0D54
+#define GL_ALPHA_BITS 0x0D55
+#define GL_DEPTH_BITS 0x0D56
+#define GL_STENCIL_BITS 0x0D57
+#define GL_POLYGON_OFFSET_UNITS 0x2A00
+/* GL_POLYGON_OFFSET_FILL */
+#define GL_POLYGON_OFFSET_FACTOR 0x8038
+#define GL_TEXTURE_BINDING_2D 0x8069
+#define GL_SAMPLE_BUFFERS 0x80A8
+#define GL_SAMPLES 0x80A9
+#define GL_SAMPLE_COVERAGE_VALUE 0x80AA
+#define GL_SAMPLE_COVERAGE_INVERT 0x80AB
+
+/* GetTextureParameter */
+/* GL_TEXTURE_MAG_FILTER */
+/* GL_TEXTURE_MIN_FILTER */
+/* GL_TEXTURE_WRAP_S */
+/* GL_TEXTURE_WRAP_T */
+
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
+#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
+
+/* HintMode */
+#define GL_DONT_CARE 0x1100
+#define GL_FASTEST 0x1101
+#define GL_NICEST 0x1102
+
+/* HintTarget */
+#define GL_GENERATE_MIPMAP_HINT 0x8192
+
+/* DataType */
+#define GL_BYTE 0x1400
+#define GL_UNSIGNED_BYTE 0x1401
+#define GL_SHORT 0x1402
+#define GL_UNSIGNED_SHORT 0x1403
+#define GL_INT 0x1404
+#define GL_UNSIGNED_INT 0x1405
+#define GL_FLOAT 0x1406
+#define GL_FIXED 0x140C
+
+/* PixelFormat */
+#define GL_DEPTH_COMPONENT 0x1902
+#define GL_ALPHA 0x1906
+#define GL_RGB 0x1907
+#define GL_RGBA 0x1908
+#define GL_LUMINANCE 0x1909
+#define GL_LUMINANCE_ALPHA 0x190A
+
+/* PixelType */
+/* GL_UNSIGNED_BYTE */
+#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
+#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
+#define GL_UNSIGNED_SHORT_5_6_5 0x8363
+
+/* Shaders */
+#define GL_FRAGMENT_SHADER 0x8B30
+#define GL_VERTEX_SHADER 0x8B31
+#define GL_MAX_VERTEX_ATTRIBS 0x8869
+#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
+#define GL_MAX_VARYING_VECTORS 0x8DFC
+#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
+#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
+#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
+#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
+#define GL_SHADER_TYPE 0x8B4F
+#define GL_DELETE_STATUS 0x8B80
+#define GL_LINK_STATUS 0x8B82
+#define GL_VALIDATE_STATUS 0x8B83
+#define GL_ATTACHED_SHADERS 0x8B85
+#define GL_ACTIVE_UNIFORMS 0x8B86
+#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
+#define GL_ACTIVE_ATTRIBUTES 0x8B89
+#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
+#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
+#define GL_CURRENT_PROGRAM 0x8B8D
+
+/* StencilFunction */
+#define GL_NEVER 0x0200
+#define GL_LESS 0x0201
+#define GL_EQUAL 0x0202
+#define GL_LEQUAL 0x0203
+#define GL_GREATER 0x0204
+#define GL_NOTEQUAL 0x0205
+#define GL_GEQUAL 0x0206
+#define GL_ALWAYS 0x0207
+
+/* StencilOp */
+/* GL_ZERO */
+#define GL_KEEP 0x1E00
+#define GL_REPLACE 0x1E01
+#define GL_INCR 0x1E02
+#define GL_DECR 0x1E03
+#define GL_INVERT 0x150A
+#define GL_INCR_WRAP 0x8507
+#define GL_DECR_WRAP 0x8508
+
+/* StringName */
+#define GL_VENDOR 0x1F00
+#define GL_RENDERER 0x1F01
+#define GL_VERSION 0x1F02
+#define GL_EXTENSIONS 0x1F03
+
+/* TextureMagFilter */
+#define GL_NEAREST 0x2600
+#define GL_LINEAR 0x2601
+
+/* TextureMinFilter */
+/* GL_NEAREST */
+/* GL_LINEAR */
+#define GL_NEAREST_MIPMAP_NEAREST 0x2700
+#define GL_LINEAR_MIPMAP_NEAREST 0x2701
+#define GL_NEAREST_MIPMAP_LINEAR 0x2702
+#define GL_LINEAR_MIPMAP_LINEAR 0x2703
+
+/* TextureParameterName */
+#define GL_TEXTURE_MAG_FILTER 0x2800
+#define GL_TEXTURE_MIN_FILTER 0x2801
+#define GL_TEXTURE_WRAP_S 0x2802
+#define GL_TEXTURE_WRAP_T 0x2803
+
+/* TextureTarget */
+/* GL_TEXTURE_2D */
+#define GL_TEXTURE 0x1702
+
+#define GL_TEXTURE_CUBE_MAP 0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C
+
+/* TextureUnit */
+#define GL_TEXTURE0 0x84C0
+#define GL_TEXTURE1 0x84C1
+#define GL_TEXTURE2 0x84C2
+#define GL_TEXTURE3 0x84C3
+#define GL_TEXTURE4 0x84C4
+#define GL_TEXTURE5 0x84C5
+#define GL_TEXTURE6 0x84C6
+#define GL_TEXTURE7 0x84C7
+#define GL_TEXTURE8 0x84C8
+#define GL_TEXTURE9 0x84C9
+#define GL_TEXTURE10 0x84CA
+#define GL_TEXTURE11 0x84CB
+#define GL_TEXTURE12 0x84CC
+#define GL_TEXTURE13 0x84CD
+#define GL_TEXTURE14 0x84CE
+#define GL_TEXTURE15 0x84CF
+#define GL_TEXTURE16 0x84D0
+#define GL_TEXTURE17 0x84D1
+#define GL_TEXTURE18 0x84D2
+#define GL_TEXTURE19 0x84D3
+#define GL_TEXTURE20 0x84D4
+#define GL_TEXTURE21 0x84D5
+#define GL_TEXTURE22 0x84D6
+#define GL_TEXTURE23 0x84D7
+#define GL_TEXTURE24 0x84D8
+#define GL_TEXTURE25 0x84D9
+#define GL_TEXTURE26 0x84DA
+#define GL_TEXTURE27 0x84DB
+#define GL_TEXTURE28 0x84DC
+#define GL_TEXTURE29 0x84DD
+#define GL_TEXTURE30 0x84DE
+#define GL_TEXTURE31 0x84DF
+#define GL_ACTIVE_TEXTURE 0x84E0
+
+/* TextureWrapMode */
+#define GL_REPEAT 0x2901
+#define GL_CLAMP_TO_EDGE 0x812F
+#define GL_MIRRORED_REPEAT 0x8370
+
+/* Uniform Types */
+#define GL_FLOAT_VEC2 0x8B50
+#define GL_FLOAT_VEC3 0x8B51
+#define GL_FLOAT_VEC4 0x8B52
+#define GL_INT_VEC2 0x8B53
+#define GL_INT_VEC3 0x8B54
+#define GL_INT_VEC4 0x8B55
+#define GL_BOOL 0x8B56
+#define GL_BOOL_VEC2 0x8B57
+#define GL_BOOL_VEC3 0x8B58
+#define GL_BOOL_VEC4 0x8B59
+#define GL_FLOAT_MAT2 0x8B5A
+#define GL_FLOAT_MAT3 0x8B5B
+#define GL_FLOAT_MAT4 0x8B5C
+#define GL_SAMPLER_2D 0x8B5E
+#define GL_SAMPLER_CUBE 0x8B60
+
+/* Vertex Arrays */
+#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
+#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
+#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
+#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
+#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
+#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
+#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
+
+/* Read Format */
+#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A
+#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B
+
+/* Shader Source */
+#define GL_COMPILE_STATUS 0x8B81
+#define GL_INFO_LOG_LENGTH 0x8B84
+#define GL_SHADER_SOURCE_LENGTH 0x8B88
+#define GL_SHADER_COMPILER 0x8DFA
+
+/* Shader Binary */
+#define GL_SHADER_BINARY_FORMATS 0x8DF8
+#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9
+
+/* Shader Precision-Specified Types */
+#define GL_LOW_FLOAT 0x8DF0
+#define GL_MEDIUM_FLOAT 0x8DF1
+#define GL_HIGH_FLOAT 0x8DF2
+#define GL_LOW_INT 0x8DF3
+#define GL_MEDIUM_INT 0x8DF4
+#define GL_HIGH_INT 0x8DF5
+
+/* Framebuffer Object. */
+#define GL_FRAMEBUFFER 0x8D40
+#define GL_RENDERBUFFER 0x8D41
+
+#define GL_RGBA4 0x8056
+#define GL_RGB5_A1 0x8057
+#define GL_RGB565 0x8D62
+#define GL_DEPTH_COMPONENT16 0x81A5
+#define GL_STENCIL_INDEX8 0x8D48
+
+#define GL_RENDERBUFFER_WIDTH 0x8D42
+#define GL_RENDERBUFFER_HEIGHT 0x8D43
+#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44
+#define GL_RENDERBUFFER_RED_SIZE 0x8D50
+#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51
+#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52
+#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53
+#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54
+#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
+
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
+
+#define GL_COLOR_ATTACHMENT0 0x8CE0
+#define GL_DEPTH_ATTACHMENT 0x8D00
+#define GL_STENCIL_ATTACHMENT 0x8D20
+
+#define GL_NONE 0
+
+#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
+#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9
+#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
+
+#define GL_FRAMEBUFFER_BINDING 0x8CA6
+#define GL_RENDERBUFFER_BINDING 0x8CA7
+#define GL_MAX_RENDERBUFFER_SIZE 0x84E8
+
+#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
+
+/* OpenGL ES 3.0 */
+
+#define GL_READ_BUFFER 0x0C02
+#define GL_UNPACK_ROW_LENGTH 0x0CF2
+#define GL_UNPACK_SKIP_ROWS 0x0CF3
+#define GL_UNPACK_SKIP_PIXELS 0x0CF4
+#define GL_PACK_ROW_LENGTH 0x0D02
+#define GL_PACK_SKIP_ROWS 0x0D03
+#define GL_PACK_SKIP_PIXELS 0x0D04
+#define GL_COLOR 0x1800
+#define GL_DEPTH 0x1801
+#define GL_STENCIL 0x1802
+#define GL_RED 0x1903
+#define GL_RGB8 0x8051
+#define GL_RGBA8 0x8058
+#define GL_RGB10_A2 0x8059
+#define GL_TEXTURE_BINDING_3D 0x806A
+#define GL_UNPACK_SKIP_IMAGES 0x806D
+#define GL_UNPACK_IMAGE_HEIGHT 0x806E
+#define GL_TEXTURE_3D 0x806F
+#define GL_TEXTURE_WRAP_R 0x8072
+#define GL_MAX_3D_TEXTURE_SIZE 0x8073
+#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
+#define GL_MAX_ELEMENTS_VERTICES 0x80E8
+#define GL_MAX_ELEMENTS_INDICES 0x80E9
+#define GL_TEXTURE_MIN_LOD 0x813A
+#define GL_TEXTURE_MAX_LOD 0x813B
+#define GL_TEXTURE_BASE_LEVEL 0x813C
+#define GL_TEXTURE_MAX_LEVEL 0x813D
+#define GL_MIN 0x8007
+#define GL_MAX 0x8008
+#define GL_DEPTH_COMPONENT24 0x81A6
+#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD
+#define GL_TEXTURE_COMPARE_MODE 0x884C
+#define GL_TEXTURE_COMPARE_FUNC 0x884D
+#define GL_CURRENT_QUERY 0x8865
+#define GL_QUERY_RESULT 0x8866
+#define GL_QUERY_RESULT_AVAILABLE 0x8867
+#define GL_BUFFER_MAPPED 0x88BC
+#define GL_BUFFER_MAP_POINTER 0x88BD
+#define GL_STREAM_READ 0x88E1
+#define GL_STREAM_COPY 0x88E2
+#define GL_STATIC_READ 0x88E5
+#define GL_STATIC_COPY 0x88E6
+#define GL_DYNAMIC_READ 0x88E9
+#define GL_DYNAMIC_COPY 0x88EA
+#define GL_MAX_DRAW_BUFFERS 0x8824
+#define GL_DRAW_BUFFER0 0x8825
+#define GL_DRAW_BUFFER1 0x8826
+#define GL_DRAW_BUFFER2 0x8827
+#define GL_DRAW_BUFFER3 0x8828
+#define GL_DRAW_BUFFER4 0x8829
+#define GL_DRAW_BUFFER5 0x882A
+#define GL_DRAW_BUFFER6 0x882B
+#define GL_DRAW_BUFFER7 0x882C
+#define GL_DRAW_BUFFER8 0x882D
+#define GL_DRAW_BUFFER9 0x882E
+#define GL_DRAW_BUFFER10 0x882F
+#define GL_DRAW_BUFFER11 0x8830
+#define GL_DRAW_BUFFER12 0x8831
+#define GL_DRAW_BUFFER13 0x8832
+#define GL_DRAW_BUFFER14 0x8833
+#define GL_DRAW_BUFFER15 0x8834
+#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49
+#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A
+#define GL_SAMPLER_3D 0x8B5F
+#define GL_SAMPLER_2D_SHADOW 0x8B62
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B
+#define GL_PIXEL_PACK_BUFFER 0x88EB
+#define GL_PIXEL_UNPACK_BUFFER 0x88EC
+#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED
+#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
+#define GL_FLOAT_MAT2x3 0x8B65
+#define GL_FLOAT_MAT2x4 0x8B66
+#define GL_FLOAT_MAT3x2 0x8B67
+#define GL_FLOAT_MAT3x4 0x8B68
+#define GL_FLOAT_MAT4x2 0x8B69
+#define GL_FLOAT_MAT4x3 0x8B6A
+#define GL_SRGB 0x8C40
+#define GL_SRGB8 0x8C41
+#define GL_SRGB8_ALPHA8 0x8C43
+#define GL_COMPARE_REF_TO_TEXTURE 0x884E
+#define GL_MAJOR_VERSION 0x821B
+#define GL_MINOR_VERSION 0x821C
+#define GL_NUM_EXTENSIONS 0x821D
+#define GL_RGBA32F 0x8814
+#define GL_RGB32F 0x8815
+#define GL_RGBA16F 0x881A
+#define GL_RGB16F 0x881B
+#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD
+#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF
+#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904
+#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905
+#define GL_MAX_VARYING_COMPONENTS 0x8B4B
+#define GL_TEXTURE_2D_ARRAY 0x8C1A
+#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D
+#define GL_R11F_G11F_B10F 0x8C3A
+#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B
+#define GL_RGB9_E5 0x8C3D
+#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E
+#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76
+#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80
+#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83
+#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84
+#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85
+#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88
+#define GL_RASTERIZER_DISCARD 0x8C89
+#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B
+#define GL_INTERLEAVED_ATTRIBS 0x8C8C
+#define GL_SEPARATE_ATTRIBS 0x8C8D
+#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F
+#define GL_RGBA32UI 0x8D70
+#define GL_RGB32UI 0x8D71
+#define GL_RGBA16UI 0x8D76
+#define GL_RGB16UI 0x8D77
+#define GL_RGBA8UI 0x8D7C
+#define GL_RGB8UI 0x8D7D
+#define GL_RGBA32I 0x8D82
+#define GL_RGB32I 0x8D83
+#define GL_RGBA16I 0x8D88
+#define GL_RGB16I 0x8D89
+#define GL_RGBA8I 0x8D8E
+#define GL_RGB8I 0x8D8F
+#define GL_RED_INTEGER 0x8D94
+#define GL_RGB_INTEGER 0x8D98
+#define GL_RGBA_INTEGER 0x8D99
+#define GL_SAMPLER_2D_ARRAY 0x8DC1
+#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4
+#define GL_SAMPLER_CUBE_SHADOW 0x8DC5
+#define GL_UNSIGNED_INT_VEC2 0x8DC6
+#define GL_UNSIGNED_INT_VEC3 0x8DC7
+#define GL_UNSIGNED_INT_VEC4 0x8DC8
+#define GL_INT_SAMPLER_2D 0x8DCA
+#define GL_INT_SAMPLER_3D 0x8DCB
+#define GL_INT_SAMPLER_CUBE 0x8DCC
+#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF
+#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2
+#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3
+#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4
+#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7
+#define GL_BUFFER_ACCESS_FLAGS 0x911F
+#define GL_BUFFER_MAP_LENGTH 0x9120
+#define GL_BUFFER_MAP_OFFSET 0x9121
+#define GL_DEPTH_COMPONENT32F 0x8CAC
+#define GL_DEPTH32F_STENCIL8 0x8CAD
+#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD
+#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210
+#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211
+#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212
+#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213
+#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214
+#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215
+#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216
+#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217
+#define GL_FRAMEBUFFER_DEFAULT 0x8218
+#define GL_FRAMEBUFFER_UNDEFINED 0x8219
+#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A
+#define GL_DEPTH_STENCIL 0x84F9
+#define GL_UNSIGNED_INT_24_8 0x84FA
+#define GL_DEPTH24_STENCIL8 0x88F0
+#define GL_UNSIGNED_NORMALIZED 0x8C17
+#define GL_DRAW_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING
+#define GL_READ_FRAMEBUFFER 0x8CA8
+#define GL_DRAW_FRAMEBUFFER 0x8CA9
+#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA
+#define GL_RENDERBUFFER_SAMPLES 0x8CAB
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4
+#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF
+#define GL_COLOR_ATTACHMENT1 0x8CE1
+#define GL_COLOR_ATTACHMENT2 0x8CE2
+#define GL_COLOR_ATTACHMENT3 0x8CE3
+#define GL_COLOR_ATTACHMENT4 0x8CE4
+#define GL_COLOR_ATTACHMENT5 0x8CE5
+#define GL_COLOR_ATTACHMENT6 0x8CE6
+#define GL_COLOR_ATTACHMENT7 0x8CE7
+#define GL_COLOR_ATTACHMENT8 0x8CE8
+#define GL_COLOR_ATTACHMENT9 0x8CE9
+#define GL_COLOR_ATTACHMENT10 0x8CEA
+#define GL_COLOR_ATTACHMENT11 0x8CEB
+#define GL_COLOR_ATTACHMENT12 0x8CEC
+#define GL_COLOR_ATTACHMENT13 0x8CED
+#define GL_COLOR_ATTACHMENT14 0x8CEE
+#define GL_COLOR_ATTACHMENT15 0x8CEF
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
+#define GL_MAX_SAMPLES 0x8D57
+#define GL_HALF_FLOAT 0x140B
+#define GL_MAP_READ_BIT 0x0001
+#define GL_MAP_WRITE_BIT 0x0002
+#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004
+#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008
+#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010
+#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020
+#define GL_RG 0x8227
+#define GL_RG_INTEGER 0x8228
+#define GL_R8 0x8229
+#define GL_RG8 0x822B
+#define GL_R16F 0x822D
+#define GL_R32F 0x822E
+#define GL_RG16F 0x822F
+#define GL_RG32F 0x8230
+#define GL_R8I 0x8231
+#define GL_R8UI 0x8232
+#define GL_R16I 0x8233
+#define GL_R16UI 0x8234
+#define GL_R32I 0x8235
+#define GL_R32UI 0x8236
+#define GL_RG8I 0x8237
+#define GL_RG8UI 0x8238
+#define GL_RG16I 0x8239
+#define GL_RG16UI 0x823A
+#define GL_RG32I 0x823B
+#define GL_RG32UI 0x823C
+#define GL_VERTEX_ARRAY_BINDING 0x85B5
+#define GL_R8_SNORM 0x8F94
+#define GL_RG8_SNORM 0x8F95
+#define GL_RGB8_SNORM 0x8F96
+#define GL_RGBA8_SNORM 0x8F97
+#define GL_SIGNED_NORMALIZED 0x8F9C
+#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69
+#define GL_COPY_READ_BUFFER 0x8F36
+#define GL_COPY_WRITE_BUFFER 0x8F37
+#define GL_COPY_READ_BUFFER_BINDING GL_COPY_READ_BUFFER
+#define GL_COPY_WRITE_BUFFER_BINDING GL_COPY_WRITE_BUFFER
+#define GL_UNIFORM_BUFFER 0x8A11
+#define GL_UNIFORM_BUFFER_BINDING 0x8A28
+#define GL_UNIFORM_BUFFER_START 0x8A29
+#define GL_UNIFORM_BUFFER_SIZE 0x8A2A
+#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B
+#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D
+#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E
+#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F
+#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30
+#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31
+#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33
+#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34
+#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35
+#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36
+#define GL_UNIFORM_TYPE 0x8A37
+#define GL_UNIFORM_SIZE 0x8A38
+#define GL_UNIFORM_NAME_LENGTH 0x8A39
+#define GL_UNIFORM_BLOCK_INDEX 0x8A3A
+#define GL_UNIFORM_OFFSET 0x8A3B
+#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C
+#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D
+#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E
+#define GL_UNIFORM_BLOCK_BINDING 0x8A3F
+#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40
+#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46
+#define GL_INVALID_INDEX 0xFFFFFFFFu
+#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122
+#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125
+#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111
+#define GL_OBJECT_TYPE 0x9112
+#define GL_SYNC_CONDITION 0x9113
+#define GL_SYNC_STATUS 0x9114
+#define GL_SYNC_FLAGS 0x9115
+#define GL_SYNC_FENCE 0x9116
+#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117
+#define GL_UNSIGNALED 0x9118
+#define GL_SIGNALED 0x9119
+#define GL_ALREADY_SIGNALED 0x911A
+#define GL_TIMEOUT_EXPIRED 0x911B
+#define GL_CONDITION_SATISFIED 0x911C
+#define GL_WAIT_FAILED 0x911D
+#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001
+#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE
+#define GL_ANY_SAMPLES_PASSED 0x8C2F
+#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A
+#define GL_SAMPLER_BINDING 0x8919
+#define GL_RGB10_A2UI 0x906F
+#define GL_TEXTURE_SWIZZLE_R 0x8E42
+#define GL_TEXTURE_SWIZZLE_G 0x8E43
+#define GL_TEXTURE_SWIZZLE_B 0x8E44
+#define GL_TEXTURE_SWIZZLE_A 0x8E45
+#define GL_GREEN 0x1904
+#define GL_BLUE 0x1905
+#define GL_INT_2_10_10_10_REV 0x8D9F
+#define GL_TRANSFORM_FEEDBACK 0x8E22
+#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23
+#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24
+#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25
+#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257
+#define GL_PROGRAM_BINARY_LENGTH 0x8741
+#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE
+#define GL_PROGRAM_BINARY_FORMATS 0x87FF
+#define GL_COMPRESSED_R11_EAC 0x9270
+#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271
+#define GL_COMPRESSED_RG11_EAC 0x9272
+#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273
+#define GL_COMPRESSED_RGB8_ETC2 0x9274
+#define GL_COMPRESSED_SRGB8_ETC2 0x9275
+#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276
+#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
+#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
+#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279
+#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F
+#define GL_MAX_ELEMENT_INDEX 0x8D6B
+#define GL_NUM_SAMPLE_COUNTS 0x9380
+#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF
+
+/*-------------------------------------------------------------------------
+ * Entrypoint definitions
+ *-----------------------------------------------------------------------*/
+
+/* OpenGL ES 2.0 */
+
+GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture);
+GL_APICALL void GL_APIENTRY glAttachShader (GLuint program, GLuint shader);
+GL_APICALL void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar* name);
+GL_APICALL void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer);
+GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer);
+GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer);
+GL_APICALL void GL_APIENTRY glBindTexture (GLenum target, GLuint texture);
+GL_APICALL void GL_APIENTRY glBlendColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+GL_APICALL void GL_APIENTRY glBlendEquation (GLenum mode);
+GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha);
+GL_APICALL void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor);
+GL_APICALL void GL_APIENTRY glBlendFuncSeparate (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);
+GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);
+GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target);
+GL_APICALL void GL_APIENTRY glClear (GLbitfield mask);
+GL_APICALL void GL_APIENTRY glClearColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+GL_APICALL void GL_APIENTRY glClearDepthf (GLfloat depth);
+GL_APICALL void GL_APIENTRY glClearStencil (GLint s);
+GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader);
+GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data);
+GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data);
+GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL GLuint GL_APIENTRY glCreateProgram (void);
+GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenum type);
+GL_APICALL void GL_APIENTRY glCullFace (GLenum mode);
+GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint* buffers);
+GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint* framebuffers);
+GL_APICALL void GL_APIENTRY glDeleteProgram (GLuint program);
+GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint* renderbuffers);
+GL_APICALL void GL_APIENTRY glDeleteShader (GLuint shader);
+GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint* textures);
+GL_APICALL void GL_APIENTRY glDepthFunc (GLenum func);
+GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag);
+GL_APICALL void GL_APIENTRY glDepthRangef (GLfloat n, GLfloat f);
+GL_APICALL void GL_APIENTRY glDetachShader (GLuint program, GLuint shader);
+GL_APICALL void GL_APIENTRY glDisable (GLenum cap);
+GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index);
+GL_APICALL void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count);
+GL_APICALL void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices);
+GL_APICALL void GL_APIENTRY glEnable (GLenum cap);
+GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index);
+GL_APICALL void GL_APIENTRY glFinish (void);
+GL_APICALL void GL_APIENTRY glFlush (void);
+GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GL_APICALL void GL_APIENTRY glFrontFace (GLenum mode);
+GL_APICALL void GL_APIENTRY glGenBuffers (GLsizei n, GLuint* buffers);
+GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenum target);
+GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint* framebuffers);
+GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint* renderbuffers);
+GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint* textures);
+GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
+GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
+GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders);
+GL_APICALL GLint GL_APIENTRY glGetAttribLocation (GLuint program, const GLchar* name);
+GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean* params);
+GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint* params);
+GL_APICALL GLenum GL_APIENTRY glGetError (void);
+GL_APICALL void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat* params);
+GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint* params);
+GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint* params);
+GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint* params);
+GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog);
+GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint* params);
+GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint* params);
+GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog);
+GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
+GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source);
+GL_APICALL const GLubyte* GL_APIENTRY glGetString (GLenum name);
+GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat* params);
+GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint* params);
+GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat* params);
+GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint* params);
+GL_APICALL GLint GL_APIENTRY glGetUniformLocation (GLuint program, const GLchar* name);
+GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat* params);
+GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint* params);
+GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, GLvoid** pointer);
+GL_APICALL void GL_APIENTRY glHint (GLenum target, GLenum mode);
+GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLuint buffer);
+GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenum cap);
+GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLuint framebuffer);
+GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLuint program);
+GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLuint renderbuffer);
+GL_APICALL GLboolean GL_APIENTRY glIsShader (GLuint shader);
+GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLuint texture);
+GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width);
+GL_APICALL void GL_APIENTRY glLinkProgram (GLuint program);
+GL_APICALL void GL_APIENTRY glPixelStorei (GLenum pname, GLint param);
+GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units);
+GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels);
+GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void);
+GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glSampleCoverage (GLfloat value, GLboolean invert);
+GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length);
+GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length);
+GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass);
+GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
+GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param);
+GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat* params);
+GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param);
+GL_APICALL void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint* params);
+GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels);
+GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat x);
+GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat* v);
+GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint x);
+GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint* v);
+GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat x, GLfloat y);
+GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat* v);
+GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint x, GLint y);
+GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint* v);
+GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat x, GLfloat y, GLfloat z);
+GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat* v);
+GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint x, GLint y, GLint z);
+GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint* v);
+GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat* v);
+GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint x, GLint y, GLint z, GLint w);
+GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint* v);
+GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void GL_APIENTRY glUseProgram (GLuint program);
+GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program);
+GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint indx, GLfloat x);
+GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint indx, const GLfloat* values);
+GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint indx, GLfloat x, GLfloat y);
+GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint indx, const GLfloat* values);
+GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint indx, GLfloat x, GLfloat y, GLfloat z);
+GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint indx, const GLfloat* values);
+GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint indx, const GLfloat* values);
+GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr);
+GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height);
+
+/* OpenGL ES 3.0 */
+
+GL_APICALL void GL_APIENTRY glReadBuffer (GLenum mode);
+GL_APICALL void GL_APIENTRY glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices);
+GL_APICALL void GL_APIENTRY glTexImage3D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+GL_APICALL void GL_APIENTRY glTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels);
+GL_APICALL void GL_APIENTRY glCopyTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glCompressedTexImage3D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data);
+GL_APICALL void GL_APIENTRY glCompressedTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data);
+GL_APICALL void GL_APIENTRY glGenQueries (GLsizei n, GLuint* ids);
+GL_APICALL void GL_APIENTRY glDeleteQueries (GLsizei n, const GLuint* ids);
+GL_APICALL GLboolean GL_APIENTRY glIsQuery (GLuint id);
+GL_APICALL void GL_APIENTRY glBeginQuery (GLenum target, GLuint id);
+GL_APICALL void GL_APIENTRY glEndQuery (GLenum target);
+GL_APICALL void GL_APIENTRY glGetQueryiv (GLenum target, GLenum pname, GLint* params);
+GL_APICALL void GL_APIENTRY glGetQueryObjectuiv (GLuint id, GLenum pname, GLuint* params);
+GL_APICALL GLboolean GL_APIENTRY glUnmapBuffer (GLenum target);
+GL_APICALL void GL_APIENTRY glGetBufferPointerv (GLenum target, GLenum pname, GLvoid** params);
+GL_APICALL void GL_APIENTRY glDrawBuffers (GLsizei n, const GLenum* bufs);
+GL_APICALL void GL_APIENTRY glUniformMatrix2x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void GL_APIENTRY glUniformMatrix3x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void GL_APIENTRY glUniformMatrix2x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void GL_APIENTRY glUniformMatrix4x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void GL_APIENTRY glUniformMatrix3x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void GL_APIENTRY glUniformMatrix4x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void GL_APIENTRY glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glFramebufferTextureLayer (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+GL_APICALL GLvoid* GL_APIENTRY glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+GL_APICALL void GL_APIENTRY glFlushMappedBufferRange (GLenum target, GLintptr offset, GLsizeiptr length);
+GL_APICALL void GL_APIENTRY glBindVertexArray (GLuint array);
+GL_APICALL void GL_APIENTRY glDeleteVertexArrays (GLsizei n, const GLuint* arrays);
+GL_APICALL void GL_APIENTRY glGenVertexArrays (GLsizei n, GLuint* arrays);
+GL_APICALL GLboolean GL_APIENTRY glIsVertexArray (GLuint array);
+GL_APICALL void GL_APIENTRY glGetIntegeri_v (GLenum target, GLuint index, GLint* data);
+GL_APICALL void GL_APIENTRY glBeginTransformFeedback (GLenum primitiveMode);
+GL_APICALL void GL_APIENTRY glEndTransformFeedback (void);
+GL_APICALL void GL_APIENTRY glBindBufferRange (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+GL_APICALL void GL_APIENTRY glBindBufferBase (GLenum target, GLuint index, GLuint buffer);
+GL_APICALL void GL_APIENTRY glTransformFeedbackVaryings (GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode);
+GL_APICALL void GL_APIENTRY glGetTransformFeedbackVarying (GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name);
+GL_APICALL void GL_APIENTRY glVertexAttribIPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer);
+GL_APICALL void GL_APIENTRY glGetVertexAttribIiv (GLuint index, GLenum pname, GLint* params);
+GL_APICALL void GL_APIENTRY glGetVertexAttribIuiv (GLuint index, GLenum pname, GLuint* params);
+GL_APICALL void GL_APIENTRY glVertexAttribI4i (GLuint index, GLint x, GLint y, GLint z, GLint w);
+GL_APICALL void GL_APIENTRY glVertexAttribI4ui (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+GL_APICALL void GL_APIENTRY glVertexAttribI4iv (GLuint index, const GLint* v);
+GL_APICALL void GL_APIENTRY glVertexAttribI4uiv (GLuint index, const GLuint* v);
+GL_APICALL void GL_APIENTRY glGetUniformuiv (GLuint program, GLint location, GLuint* params);
+GL_APICALL GLint GL_APIENTRY glGetFragDataLocation (GLuint program, const GLchar *name);
+GL_APICALL void GL_APIENTRY glUniform1ui (GLint location, GLuint v0);
+GL_APICALL void GL_APIENTRY glUniform2ui (GLint location, GLuint v0, GLuint v1);
+GL_APICALL void GL_APIENTRY glUniform3ui (GLint location, GLuint v0, GLuint v1, GLuint v2);
+GL_APICALL void GL_APIENTRY glUniform4ui (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+GL_APICALL void GL_APIENTRY glUniform1uiv (GLint location, GLsizei count, const GLuint* value);
+GL_APICALL void GL_APIENTRY glUniform2uiv (GLint location, GLsizei count, const GLuint* value);
+GL_APICALL void GL_APIENTRY glUniform3uiv (GLint location, GLsizei count, const GLuint* value);
+GL_APICALL void GL_APIENTRY glUniform4uiv (GLint location, GLsizei count, const GLuint* value);
+GL_APICALL void GL_APIENTRY glClearBufferiv (GLenum buffer, GLint drawbuffer, const GLint* value);
+GL_APICALL void GL_APIENTRY glClearBufferuiv (GLenum buffer, GLint drawbuffer, const GLuint* value);
+GL_APICALL void GL_APIENTRY glClearBufferfv (GLenum buffer, GLint drawbuffer, const GLfloat* value);
+GL_APICALL void GL_APIENTRY glClearBufferfi (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+GL_APICALL const GLubyte* GL_APIENTRY glGetStringi (GLenum name, GLuint index);
+GL_APICALL void GL_APIENTRY glCopyBufferSubData (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+GL_APICALL void GL_APIENTRY glGetUniformIndices (GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices);
+GL_APICALL void GL_APIENTRY glGetActiveUniformsiv (GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params);
+GL_APICALL GLuint GL_APIENTRY glGetUniformBlockIndex (GLuint program, const GLchar* uniformBlockName);
+GL_APICALL void GL_APIENTRY glGetActiveUniformBlockiv (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params);
+GL_APICALL void GL_APIENTRY glGetActiveUniformBlockName (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName);
+GL_APICALL void GL_APIENTRY glUniformBlockBinding (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+GL_APICALL void GL_APIENTRY glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count, GLsizei instanceCount);
+GL_APICALL void GL_APIENTRY glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount);
+GL_APICALL GLsync GL_APIENTRY glFenceSync (GLenum condition, GLbitfield flags);
+GL_APICALL GLboolean GL_APIENTRY glIsSync (GLsync sync);
+GL_APICALL void GL_APIENTRY glDeleteSync (GLsync sync);
+GL_APICALL GLenum GL_APIENTRY glClientWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout);
+GL_APICALL void GL_APIENTRY glWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout);
+GL_APICALL void GL_APIENTRY glGetInteger64v (GLenum pname, GLint64* params);
+GL_APICALL void GL_APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values);
+GL_APICALL void GL_APIENTRY glGetInteger64i_v (GLenum target, GLuint index, GLint64* data);
+GL_APICALL void GL_APIENTRY glGetBufferParameteri64v (GLenum target, GLenum pname, GLint64* params);
+GL_APICALL void GL_APIENTRY glGenSamplers (GLsizei count, GLuint* samplers);
+GL_APICALL void GL_APIENTRY glDeleteSamplers (GLsizei count, const GLuint* samplers);
+GL_APICALL GLboolean GL_APIENTRY glIsSampler (GLuint sampler);
+GL_APICALL void GL_APIENTRY glBindSampler (GLuint unit, GLuint sampler);
+GL_APICALL void GL_APIENTRY glSamplerParameteri (GLuint sampler, GLenum pname, GLint param);
+GL_APICALL void GL_APIENTRY glSamplerParameteriv (GLuint sampler, GLenum pname, const GLint* param);
+GL_APICALL void GL_APIENTRY glSamplerParameterf (GLuint sampler, GLenum pname, GLfloat param);
+GL_APICALL void GL_APIENTRY glSamplerParameterfv (GLuint sampler, GLenum pname, const GLfloat* param);
+GL_APICALL void GL_APIENTRY glGetSamplerParameteriv (GLuint sampler, GLenum pname, GLint* params);
+GL_APICALL void GL_APIENTRY glGetSamplerParameterfv (GLuint sampler, GLenum pname, GLfloat* params);
+GL_APICALL void GL_APIENTRY glVertexAttribDivisor (GLuint index, GLuint divisor);
+GL_APICALL void GL_APIENTRY glBindTransformFeedback (GLenum target, GLuint id);
+GL_APICALL void GL_APIENTRY glDeleteTransformFeedbacks (GLsizei n, const GLuint* ids);
+GL_APICALL void GL_APIENTRY glGenTransformFeedbacks (GLsizei n, GLuint* ids);
+GL_APICALL GLboolean GL_APIENTRY glIsTransformFeedback (GLuint id);
+GL_APICALL void GL_APIENTRY glPauseTransformFeedback (void);
+GL_APICALL void GL_APIENTRY glResumeTransformFeedback (void);
+GL_APICALL void GL_APIENTRY glGetProgramBinary (GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary);
+GL_APICALL void GL_APIENTRY glProgramBinary (GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length);
+GL_APICALL void GL_APIENTRY glProgramParameteri (GLuint program, GLenum pname, GLint value);
+GL_APICALL void GL_APIENTRY glInvalidateFramebuffer (GLenum target, GLsizei numAttachments, const GLenum* attachments);
+GL_APICALL void GL_APIENTRY glInvalidateSubFramebuffer (GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glTexStorage2D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glTexStorage3D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+GL_APICALL void GL_APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/external/ANGLE/GLES3/gl3ext.h b/src/external/ANGLE/GLES3/gl3ext.h
new file mode 100644
index 000000000..4d4ea96c4
--- /dev/null
+++ b/src/external/ANGLE/GLES3/gl3ext.h
@@ -0,0 +1,24 @@
+#ifndef __gl3ext_h_
+#define __gl3ext_h_
+
+/* $Revision: 17809 $ on $Date:: 2012-05-14 08:03:36 -0700 #$ */
+
+/*
+ * This document is licensed under the SGI Free Software B License Version
+ * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ .
+ */
+
+/* OpenGL ES 3 Extensions
+ *
+ * After an OES extension's interactions with OpenGl ES 3.0 have been documented,
+ * its tokens and function definitions should be added to this file in a manner
+ * that does not conflict with gl2ext.h or gl3.h.
+ *
+ * Tokens and function definitions for extensions that have become standard
+ * features in OpenGL ES 3.0 will not be added to this file.
+ *
+ * Applications using OpenGL-ES-2-only extensions should include gl2ext.h
+ */
+
+#endif /* __gl3ext_h_ */
+
diff --git a/src/external/ANGLE/GLES3/gl3platform.h b/src/external/ANGLE/GLES3/gl3platform.h
new file mode 100644
index 000000000..1bd1a850f
--- /dev/null
+++ b/src/external/ANGLE/GLES3/gl3platform.h
@@ -0,0 +1,30 @@
+#ifndef __gl3platform_h_
+#define __gl3platform_h_
+
+/* $Revision: 18437 $ on $Date:: 2012-07-08 23:31:39 -0700 #$ */
+
+/*
+ * This document is licensed under the SGI Free Software B License Version
+ * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ .
+ */
+
+/* Platform-specific types and definitions for OpenGL ES 3.X gl3.h
+ *
+ * Adopters may modify khrplatform.h and this file to suit their platform.
+ * You are encouraged to submit all modifications to the Khronos group so that
+ * they can be included in future versions of this file. Please submit changes
+ * by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla)
+ * by filing a bug against product "OpenGL-ES" component "Registry".
+ */
+
+#include
+
+#ifndef GL_APICALL
+#define GL_APICALL KHRONOS_APICALL
+#endif
+
+#ifndef GL_APIENTRY
+#define GL_APIENTRY KHRONOS_APIENTRY
+#endif
+
+#endif /* __gl3platform_h_ */
diff --git a/src/external/ANGLE/KHR/khrplatform.h b/src/external/ANGLE/KHR/khrplatform.h
new file mode 100644
index 000000000..c9e6f17d3
--- /dev/null
+++ b/src/external/ANGLE/KHR/khrplatform.h
@@ -0,0 +1,282 @@
+#ifndef __khrplatform_h_
+#define __khrplatform_h_
+
+/*
+** Copyright (c) 2008-2009 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+/* Khronos platform-specific types and definitions.
+ *
+ * $Revision: 23298 $ on $Date: 2013-09-30 17:07:13 -0700 (Mon, 30 Sep 2013) $
+ *
+ * Adopters may modify this file to suit their platform. Adopters are
+ * encouraged to submit platform specific modifications to the Khronos
+ * group so that they can be included in future versions of this file.
+ * Please submit changes by sending them to the public Khronos Bugzilla
+ * (http://khronos.org/bugzilla) by filing a bug against product
+ * "Khronos (general)" component "Registry".
+ *
+ * A predefined template which fills in some of the bug fields can be
+ * reached using http://tinyurl.com/khrplatform-h-bugreport, but you
+ * must create a Bugzilla login first.
+ *
+ *
+ * See the Implementer's Guidelines for information about where this file
+ * should be located on your system and for more details of its use:
+ * http://www.khronos.org/registry/implementers_guide.pdf
+ *
+ * This file should be included as
+ * #include
+ * by Khronos client API header files that use its types and defines.
+ *
+ * The types in khrplatform.h should only be used to define API-specific types.
+ *
+ * Types defined in khrplatform.h:
+ * khronos_int8_t signed 8 bit
+ * khronos_uint8_t unsigned 8 bit
+ * khronos_int16_t signed 16 bit
+ * khronos_uint16_t unsigned 16 bit
+ * khronos_int32_t signed 32 bit
+ * khronos_uint32_t unsigned 32 bit
+ * khronos_int64_t signed 64 bit
+ * khronos_uint64_t unsigned 64 bit
+ * khronos_intptr_t signed same number of bits as a pointer
+ * khronos_uintptr_t unsigned same number of bits as a pointer
+ * khronos_ssize_t signed size
+ * khronos_usize_t unsigned size
+ * khronos_float_t signed 32 bit floating point
+ * khronos_time_ns_t unsigned 64 bit time in nanoseconds
+ * khronos_utime_nanoseconds_t unsigned time interval or absolute time in
+ * nanoseconds
+ * khronos_stime_nanoseconds_t signed time interval in nanoseconds
+ * khronos_boolean_enum_t enumerated boolean type. This should
+ * only be used as a base type when a client API's boolean type is
+ * an enum. Client APIs which use an integer or other type for
+ * booleans cannot use this as the base type for their boolean.
+ *
+ * Tokens defined in khrplatform.h:
+ *
+ * KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
+ *
+ * KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
+ * KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
+ *
+ * Calling convention macros defined in this file:
+ * KHRONOS_APICALL
+ * KHRONOS_APIENTRY
+ * KHRONOS_APIATTRIBUTES
+ *
+ * These may be used in function prototypes as:
+ *
+ * KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
+ * int arg1,
+ * int arg2) KHRONOS_APIATTRIBUTES;
+ */
+
+/*-------------------------------------------------------------------------
+ * Definition of KHRONOS_APICALL
+ *-------------------------------------------------------------------------
+ * This precedes the return type of the function in the function prototype.
+ */
+#if defined(_WIN32) && !defined(__SCITECH_SNAP__)
+# define KHRONOS_APICALL __declspec(dllimport)
+#elif defined (__SYMBIAN32__)
+# define KHRONOS_APICALL IMPORT_C
+#else
+# define KHRONOS_APICALL
+#endif
+
+/*-------------------------------------------------------------------------
+ * Definition of KHRONOS_APIENTRY
+ *-------------------------------------------------------------------------
+ * This follows the return type of the function and precedes the function
+ * name in the function prototype.
+ */
+#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
+ /* Win32 but not WinCE */
+# define KHRONOS_APIENTRY __stdcall
+#else
+# define KHRONOS_APIENTRY
+#endif
+
+/*-------------------------------------------------------------------------
+ * Definition of KHRONOS_APIATTRIBUTES
+ *-------------------------------------------------------------------------
+ * This follows the closing parenthesis of the function prototype arguments.
+ */
+#if defined (__ARMCC_2__)
+#define KHRONOS_APIATTRIBUTES __softfp
+#else
+#define KHRONOS_APIATTRIBUTES
+#endif
+
+/*-------------------------------------------------------------------------
+ * basic type definitions
+ *-----------------------------------------------------------------------*/
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
+
+
+/*
+ * Using
+ */
+#include
+typedef int32_t khronos_int32_t;
+typedef uint32_t khronos_uint32_t;
+typedef int64_t khronos_int64_t;
+typedef uint64_t khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#elif defined(__VMS ) || defined(__sgi)
+
+/*
+ * Using
+ */
+#include
+typedef int32_t khronos_int32_t;
+typedef uint32_t khronos_uint32_t;
+typedef int64_t khronos_int64_t;
+typedef uint64_t khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
+
+/*
+ * Win32
+ */
+typedef __int32 khronos_int32_t;
+typedef unsigned __int32 khronos_uint32_t;
+typedef __int64 khronos_int64_t;
+typedef unsigned __int64 khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#elif defined(__sun__) || defined(__digital__)
+
+/*
+ * Sun or Digital
+ */
+typedef int khronos_int32_t;
+typedef unsigned int khronos_uint32_t;
+#if defined(__arch64__) || defined(_LP64)
+typedef long int khronos_int64_t;
+typedef unsigned long int khronos_uint64_t;
+#else
+typedef long long int khronos_int64_t;
+typedef unsigned long long int khronos_uint64_t;
+#endif /* __arch64__ */
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#elif 0
+
+/*
+ * Hypothetical platform with no float or int64 support
+ */
+typedef int khronos_int32_t;
+typedef unsigned int khronos_uint32_t;
+#define KHRONOS_SUPPORT_INT64 0
+#define KHRONOS_SUPPORT_FLOAT 0
+
+#else
+
+/*
+ * Generic fallback
+ */
+#include
+typedef int32_t khronos_int32_t;
+typedef uint32_t khronos_uint32_t;
+typedef int64_t khronos_int64_t;
+typedef uint64_t khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#endif
+
+
+/*
+ * Types that are (so far) the same on all platforms
+ */
+typedef signed char khronos_int8_t;
+typedef unsigned char khronos_uint8_t;
+typedef signed short int khronos_int16_t;
+typedef unsigned short int khronos_uint16_t;
+
+/*
+ * Types that differ between LLP64 and LP64 architectures - in LLP64,
+ * pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
+ * to be the only LLP64 architecture in current use.
+ */
+#ifdef _WIN64
+typedef signed long long int khronos_intptr_t;
+typedef unsigned long long int khronos_uintptr_t;
+typedef signed long long int khronos_ssize_t;
+typedef unsigned long long int khronos_usize_t;
+#else
+typedef signed long int khronos_intptr_t;
+typedef unsigned long int khronos_uintptr_t;
+typedef signed long int khronos_ssize_t;
+typedef unsigned long int khronos_usize_t;
+#endif
+
+#if KHRONOS_SUPPORT_FLOAT
+/*
+ * Float type
+ */
+typedef float khronos_float_t;
+#endif
+
+#if KHRONOS_SUPPORT_INT64
+/* Time types
+ *
+ * These types can be used to represent a time interval in nanoseconds or
+ * an absolute Unadjusted System Time. Unadjusted System Time is the number
+ * of nanoseconds since some arbitrary system event (e.g. since the last
+ * time the system booted). The Unadjusted System Time is an unsigned
+ * 64 bit value that wraps back to 0 every 584 years. Time intervals
+ * may be either signed or unsigned.
+ */
+typedef khronos_uint64_t khronos_utime_nanoseconds_t;
+typedef khronos_int64_t khronos_stime_nanoseconds_t;
+#endif
+
+/*
+ * Dummy value used to pad enum types to 32 bits.
+ */
+#ifndef KHRONOS_MAX_ENUM
+#define KHRONOS_MAX_ENUM 0x7FFFFFFF
+#endif
+
+/*
+ * Enumerated boolean type
+ *
+ * Values other than zero should be considered to be true. Therefore
+ * comparisons should not be made against KHRONOS_TRUE.
+ */
+typedef enum {
+ KHRONOS_FALSE = 0,
+ KHRONOS_TRUE = 1,
+ KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
+} khronos_boolean_enum_t;
+
+#endif /* __khrplatform_h_ */
diff --git a/src/external/ANGLE/angle_windowsstore.h b/src/external/ANGLE/angle_windowsstore.h
new file mode 100644
index 000000000..25eadacac
--- /dev/null
+++ b/src/external/ANGLE/angle_windowsstore.h
@@ -0,0 +1,51 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// angle_windowsstore.h:
+
+#ifndef ANGLE_WINDOWSSTORE_H_
+#define ANGLE_WINDOWSSTORE_H_
+
+// The following properties can be set on the CoreApplication to support additional
+// ANGLE configuration options.
+//
+// The Visual Studio sample templates provided with this version of ANGLE have examples
+// of how to set these property values.
+
+//
+// Property: EGLNativeWindowTypeProperty
+// Type: IInspectable
+// Description: Set this property to specify the window type to use for creating a surface.
+// If this property is missing, surface creation will fail.
+//
+const wchar_t EGLNativeWindowTypeProperty[] = L"EGLNativeWindowTypeProperty";
+
+//
+// Property: EGLRenderSurfaceSizeProperty
+// Type: Size
+// Description: Set this property to specify a preferred size in pixels of the render surface.
+// The render surface size width and height must be greater than 0.
+// If this property is set, then the render surface size is fixed.
+// The render surface will then be scaled to the window dimensions.
+// If this property is missing, a default behavior will be provided.
+// The default behavior uses the window size if a CoreWindow is specified or
+// the size of the SwapChainPanel control if one is specified.
+//
+const wchar_t EGLRenderSurfaceSizeProperty[] = L"EGLRenderSurfaceSizeProperty";
+
+//
+// Property: EGLRenderResolutionScaleProperty
+// Type: Single
+// Description: Use this to specify a preferred scale for the render surface compared to the window.
+// For example, if the window is 800x480, and:
+// - scale is set to 0.5f then the surface will be 400x240
+// - scale is set to 1.2f then the surface will be 960x576
+// If the window resizes or rotates then the surface will resize accordingly.
+// EGLRenderResolutionScaleProperty and EGLRenderSurfaceSizeProperty cannot both be set.
+// The scale factor should be > 0.0f and < 1.5f.
+//
+const wchar_t EGLRenderResolutionScaleProperty[] = L"EGLRenderResolutionScaleProperty";
+
+#endif // ANGLE_WINDOWSSTORE_H_
diff --git a/src/external/dr_flac.h b/src/external/dr_flac.h
index d2bebea5e..60f57eceb 100644
--- a/src/external/dr_flac.h
+++ b/src/external/dr_flac.h
@@ -1,13 +1,13 @@
// FLAC audio decoder. Public domain. See "unlicense" statement at the end of this file.
-// dr_flac - v0.4c - 2016-12-26
+// dr_flac - v0.8d - 2017-09-22
//
// David Reid - mackron@gmail.com
// USAGE
//
// dr_flac is a single-file library. To use it, do something like the following in one .c file.
-// #define DR_FLAC_IMPLEMENTATION
-// #include "dr_flac.h"
+// #define DR_FLAC_IMPLEMENTATION
+// #include "dr_flac.h"
//
// You can then #include this file in other parts of the program as you would with any other header file. To decode audio data,
// do something like the following:
@@ -17,8 +17,8 @@
// // Failed to open FLAC file
// }
//
-// int32_t* pSamples = malloc(pFlac->totalSampleCount * sizeof(int32_t));
-// uint64_t numberOfInterleavedSamplesActuallyRead = drflac_read_s32(pFlac, pFlac->totalSampleCount, pSamples);
+// drflac_int32* pSamples = malloc(pFlac->totalSampleCount * sizeof(drflac_int32));
+// drflac_uint64 numberOfInterleavedSamplesActuallyRead = drflac_read_s32(pFlac, pFlac->totalSampleCount, pSamples);
//
// The drflac object represents the decoder. It is a transparent type so all the information you need, such as the number of
// channels and the bits per sample, should be directly accessible - just make sure you don't change their values. Samples are
@@ -43,8 +43,8 @@
//
// unsigned int channels;
// unsigned int sampleRate;
-// uint64_t totalSampleCount;
-// int32_t* pSampleData = drflac_open_and_decode_file("MySong.flac", &channels, &sampleRate, &totalSampleCount);
+// drflac_uint64 totalSampleCount;
+// drflac_int32* pSampleData = drflac_open_and_decode_file_s32("MySong.flac", &channels, &sampleRate, &totalSampleCount);
// if (pSampleData == NULL) {
// // Failed to open and decode FLAC file.
// }
@@ -54,13 +54,25 @@
// drflac_free(pSampleData);
//
//
+// You can read samples as signed 16-bit integer and 32-bit floating-point PCM with the *_s16() and *_f32() family of APIs
+// respectively, but note that these should be considered lossy.
+//
+//
// If you need access to metadata (album art, etc.), use drflac_open_with_metadata(), drflac_open_file_with_metdata() or
// drflac_open_memory_with_metadata(). The rationale for keeping these APIs separate is that they're slightly slower than the
// normal versions and also just a little bit harder to use.
//
// dr_flac reports metadata to the application through the use of a callback, and every metadata block is reported before
-// drflac_open_with_metdata() returns. See https://github.com/mackron/dr_libs_tests/blob/master/dr_flac/dr_flac_test_2.c for
-// an example on how to read metadata.
+// drflac_open_with_metdata() returns.
+//
+//
+// The main opening APIs (drflac_open(), etc.) will fail if the header is not present. The presents a problem in certain
+// scenarios such as broadcast style streams like internet radio where the header may not be present because the user has
+// started playback mid-stream. To handle this, use the relaxed APIs: drflac_open_relaxed() and drflac_open_with_metadata_relaxed().
+//
+// It is not recommended to use these APIs for file based streams because a missing header would usually indicate a
+// corrupted or perverse file. In addition, these APIs can take a long time to initialize because they may need to spend
+// a lot of time finding the first frame.
//
//
//
@@ -84,54 +96,53 @@
// returns after about 4KB (which is the default). Consider reducing this if you have a very efficient implementation of
// onRead(), or increase it if it's very inefficient. Must be a multiple of 8.
//
+// #define DR_FLAC_NO_CRC
+// Disables CRC checks. This will offer a performance boost when CRC is unnecessary.
+//
+// #define DR_FLAC_NO_SIMD
+// Disables SIMD optimizations (SSE on x86/x64 architectures). Use this if you are having compatibility issues with your
+// compiler.
+//
//
//
// QUICK NOTES
-// - Based on my tests, the performance of the 32-bit build is at about parity with the reference implementation. The 64-bit build
-// is slightly faster.
-// - dr_flac does not currently do any CRC checks.
-// - dr_flac should work fine with valid native FLAC files, but for broadcast streams it won't work if the header and STREAMINFO
-// block is unavailable.
// - Audio data is output as signed 32-bit PCM, regardless of the bits per sample the FLAC stream is encoded as.
// - This has not been tested on big-endian architectures.
// - Rice codes in unencoded binary form (see https://xiph.org/flac/format.html#rice_partition) has not been tested. If anybody
// knows where I can find some test files for this, let me know.
-// - Perverse and erroneous files have not been tested. Again, if you know where I can get some test files let me know.
// - dr_flac is not thread-safe, but it's APIs can be called from any thread so long as you do your own synchronization.
+// - When using Ogg encapsulation, a corrupted metadata block will result in drflac_open_with_metadata() and drflac_open()
+// returning inconsistent samples.
#ifndef dr_flac_h
#define dr_flac_h
-#include
#include
-#ifndef DR_SIZED_TYPES_DEFINED
-#define DR_SIZED_TYPES_DEFINED
#if defined(_MSC_VER) && _MSC_VER < 1600
-typedef signed char dr_int8;
-typedef unsigned char dr_uint8;
-typedef signed short dr_int16;
-typedef unsigned short dr_uint16;
-typedef signed int dr_int32;
-typedef unsigned int dr_uint32;
-typedef signed __int64 dr_int64;
-typedef unsigned __int64 dr_uint64;
+typedef signed char drflac_int8;
+typedef unsigned char drflac_uint8;
+typedef signed short drflac_int16;
+typedef unsigned short drflac_uint16;
+typedef signed int drflac_int32;
+typedef unsigned int drflac_uint32;
+typedef signed __int64 drflac_int64;
+typedef unsigned __int64 drflac_uint64;
#else
#include
-typedef int8_t dr_int8;
-typedef uint8_t dr_uint8;
-typedef int16_t dr_int16;
-typedef uint16_t dr_uint16;
-typedef int32_t dr_int32;
-typedef uint32_t dr_uint32;
-typedef int64_t dr_int64;
-typedef uint64_t dr_uint64;
-#endif
-typedef dr_int8 dr_bool8;
-typedef dr_int32 dr_bool32;
-#define DR_TRUE 1
-#define DR_FALSE 0
+typedef int8_t drflac_int8;
+typedef uint8_t drflac_uint8;
+typedef int16_t drflac_int16;
+typedef uint16_t drflac_uint16;
+typedef int32_t drflac_int32;
+typedef uint32_t drflac_uint32;
+typedef int64_t drflac_int64;
+typedef uint64_t drflac_uint64;
#endif
+typedef drflac_uint8 drflac_bool8;
+typedef drflac_uint32 drflac_bool32;
+#define DRFLAC_TRUE 1
+#define DRFLAC_FALSE 0
// As data is read from the client it is placed into an internal buffer for fast access. This controls the
// size of that buffer. Larger values means more speed, but also more memory. In my testing there is diminishing
@@ -156,9 +167,9 @@ extern "C" {
#endif
#ifdef DRFLAC_64BIT
-typedef uint64_t drflac_cache_t;
+typedef drflac_uint64 drflac_cache_t;
#else
-typedef uint32_t drflac_cache_t;
+typedef drflac_uint32 drflac_cache_t;
#endif
// The various metadata block types.
@@ -197,7 +208,8 @@ typedef uint32_t drflac_cache_t;
typedef enum
{
drflac_container_native,
- drflac_container_ogg
+ drflac_container_ogg,
+ drflac_container_unknown
} drflac_container;
typedef enum
@@ -210,29 +222,29 @@ typedef enum
#pragma pack(2)
typedef struct
{
- uint64_t firstSample;
- uint64_t frameOffset; // The offset from the first byte of the header of the first frame.
- uint16_t sampleCount;
+ drflac_uint64 firstSample;
+ drflac_uint64 frameOffset; // The offset from the first byte of the header of the first frame.
+ drflac_uint16 sampleCount;
} drflac_seekpoint;
#pragma pack()
typedef struct
{
- uint16_t minBlockSize;
- uint16_t maxBlockSize;
- uint32_t minFrameSize;
- uint32_t maxFrameSize;
- uint32_t sampleRate;
- uint8_t channels;
- uint8_t bitsPerSample;
- uint64_t totalSampleCount;
- uint8_t md5[16];
+ drflac_uint16 minBlockSize;
+ drflac_uint16 maxBlockSize;
+ drflac_uint32 minFrameSize;
+ drflac_uint32 maxFrameSize;
+ drflac_uint32 sampleRate;
+ drflac_uint8 channels;
+ drflac_uint8 bitsPerSample;
+ drflac_uint64 totalSampleCount;
+ drflac_uint8 md5[16];
} drflac_streaminfo;
typedef struct
{
// The metadata type. Use this to know how to interpret the data below.
- uint32_t type;
+ drflac_uint32 type;
// A pointer to the raw data. This points to a temporary buffer so don't hold on to it. It's best to
// not modify the contents of this buffer. Use the structures below for more meaningful and structured
@@ -240,7 +252,7 @@ typedef struct
const void* pRawData;
// The size in bytes of the block and the buffer pointed to by pRawData if it's non-NULL.
- uint32_t rawDataSize;
+ drflac_uint32 rawDataSize;
union
{
@@ -253,50 +265,49 @@ typedef struct
struct
{
- uint32_t id;
+ drflac_uint32 id;
const void* pData;
- uint32_t dataSize;
+ drflac_uint32 dataSize;
} application;
struct
{
- uint32_t seekpointCount;
+ drflac_uint32 seekpointCount;
const drflac_seekpoint* pSeekpoints;
} seektable;
struct
{
- uint32_t vendorLength;
+ drflac_uint32 vendorLength;
const char* vendor;
- uint32_t commentCount;
+ drflac_uint32 commentCount;
const char* comments;
} vorbis_comment;
struct
{
char catalog[128];
- uint64_t leadInSampleCount;
- dr_bool32 isCD;
- uint8_t trackCount;
- const uint8_t* pTrackData;
+ drflac_uint64 leadInSampleCount;
+ drflac_bool32 isCD;
+ drflac_uint8 trackCount;
+ const drflac_uint8* pTrackData;
} cuesheet;
struct
{
- uint32_t type;
- uint32_t mimeLength;
+ drflac_uint32 type;
+ drflac_uint32 mimeLength;
const char* mime;
- uint32_t descriptionLength;
+ drflac_uint32 descriptionLength;
const char* description;
- uint32_t width;
- uint32_t height;
- uint32_t colorDepth;
- uint32_t indexColorCount;
- uint32_t pictureDataSize;
- const uint8_t* pPictureData;
+ drflac_uint32 width;
+ drflac_uint32 height;
+ drflac_uint32 colorDepth;
+ drflac_uint32 indexColorCount;
+ drflac_uint32 pictureDataSize;
+ const drflac_uint8* pPictureData;
} picture;
} data;
-
} drflac_metadata;
@@ -307,6 +318,9 @@ typedef struct
// bytesToRead [in] The number of bytes to read.
//
// Returns the number of bytes actually read.
+//
+// A return value of less than bytesToRead indicates the end of the stream. Do _not_ return from this callback until
+// either the entire bytesToRead is filled or you have reached the end of the stream.
typedef size_t (* drflac_read_proc)(void* pUserData, void* pBufferOut, size_t bytesToRead);
// Callback for when data needs to be seeked.
@@ -319,7 +333,7 @@ typedef size_t (* drflac_read_proc)(void* pUserData, void* pBufferOut, size_t by
//
// The offset will never be negative. Whether or not it is relative to the beginning or current position is determined
// by the "origin" parameter which will be either drflac_seek_origin_start or drflac_seek_origin_current.
-typedef dr_bool32 (* drflac_seek_proc)(void* pUserData, int offset, drflac_seek_origin origin);
+typedef drflac_bool32 (* drflac_seek_proc)(void* pUserData, int offset, drflac_seek_origin origin);
// Callback for when a metadata block is read.
//
@@ -333,7 +347,7 @@ typedef void (* drflac_meta_proc)(void* pUserData, drflac_metadata* pMetadata);
// Structure for internal use. Only used for decoders opened with drflac_open_memory.
typedef struct
{
- const uint8_t* data;
+ const drflac_uint8* data;
size_t dataSize;
size_t currentReadPos;
} drflac__memory_stream;
@@ -360,64 +374,67 @@ typedef struct
drflac_cache_t unalignedCache;
// The index of the next valid cache line in the "L2" cache.
- size_t nextL2Line;
+ drflac_uint32 nextL2Line;
// The number of bits that have been consumed by the cache. This is used to determine how many valid bits are remaining.
- size_t consumedBits;
+ drflac_uint32 consumedBits;
// The cached data which was most recently read from the client. There are two levels of cache. Data flows as such:
// Client -> L2 -> L1. The L2 -> L1 movement is aligned and runs on a fast path in just a few instructions.
drflac_cache_t cacheL2[DR_FLAC_BUFFER_SIZE/sizeof(drflac_cache_t)];
drflac_cache_t cache;
+ // CRC-16. This is updated whenever bits are read from the bit stream. Manually set this to 0 to reset the CRC. For FLAC, this
+ // is reset to 0 at the beginning of each frame.
+ drflac_uint16 crc16;
+ drflac_cache_t crc16Cache; // A cache for optimizing CRC calculations. This is filled when when the L1 cache is reloaded.
+ drflac_uint32 crc16CacheIgnoredBytes; // The number of bytes to ignore when updating the CRC-16 from the CRC-16 cache.
} drflac_bs;
typedef struct
{
// The type of the subframe: SUBFRAME_CONSTANT, SUBFRAME_VERBATIM, SUBFRAME_FIXED or SUBFRAME_LPC.
- uint8_t subframeType;
+ drflac_uint8 subframeType;
// The number of wasted bits per sample as specified by the sub-frame header.
- uint8_t wastedBitsPerSample;
+ drflac_uint8 wastedBitsPerSample;
// The order to use for the prediction stage for SUBFRAME_FIXED and SUBFRAME_LPC.
- uint8_t lpcOrder;
+ drflac_uint8 lpcOrder;
// The number of bits per sample for this subframe. This is not always equal to the current frame's bit per sample because
// an extra bit is required for side channels when interchannel decorrelation is being used.
- uint32_t bitsPerSample;
-
- // A pointer to the buffer containing the decoded samples in the subframe. This pointer is an offset from drflac::pExtraData, or
- // NULL if the heap is not being used. Note that it's a signed 32-bit integer for each value.
- int32_t* pDecodedSamples;
+ drflac_uint32 bitsPerSample;
+ // A pointer to the buffer containing the decoded samples in the subframe. This pointer is an offset from drflac::pExtraData. Note that
+ // it's a signed 32-bit integer for each value.
+ drflac_int32* pDecodedSamples;
} drflac_subframe;
typedef struct
{
// If the stream uses variable block sizes, this will be set to the index of the first sample. If fixed block sizes are used, this will
// always be set to 0.
- uint64_t sampleNumber;
+ drflac_uint64 sampleNumber;
// If the stream uses fixed block sizes, this will be set to the frame number. If variable block sizes are used, this will always be 0.
- uint32_t frameNumber;
+ drflac_uint32 frameNumber;
// The sample rate of this frame.
- uint32_t sampleRate;
+ drflac_uint32 sampleRate;
// The number of samples in each sub-frame within this frame.
- uint16_t blockSize;
+ drflac_uint16 blockSize;
// The channel assignment of this frame. This is not always set to the channel count. If interchannel decorrelation is being used this
// will be set to DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE, DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE or DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE.
- uint8_t channelAssignment;
+ drflac_uint8 channelAssignment;
// The number of bits per sample within this frame.
- uint8_t bitsPerSample;
-
- // The frame's CRC. This is set, but unused at the moment.
- uint8_t crc8;
+ drflac_uint8 bitsPerSample;
+ // The frame's CRC.
+ drflac_uint8 crc8;
} drflac_frame_header;
typedef struct
@@ -427,11 +444,10 @@ typedef struct
// The number of samples left to be read in this frame. This is initially set to the block size multiplied by the channel count. As samples
// are read, this will be decremented. When it reaches 0, the decoder will see this frame as fully consumed and load the next frame.
- uint32_t samplesRemaining;
+ drflac_uint32 samplesRemaining;
// The list of sub-frames within the frame. There is one sub-frame for each channel, and there's a maximum of 8 channels.
drflac_subframe subframes[8];
-
} drflac_frame;
typedef struct
@@ -444,22 +460,22 @@ typedef struct
// The sample rate. Will be set to something like 44100.
- uint32_t sampleRate;
+ drflac_uint32 sampleRate;
// The number of channels. This will be set to 1 for monaural streams, 2 for stereo, etc. Maximum 8. This is set based on the
// value specified in the STREAMINFO block.
- uint8_t channels;
+ drflac_uint8 channels;
// The bits per sample. Will be set to somthing like 16, 24, etc.
- uint8_t bitsPerSample;
+ drflac_uint8 bitsPerSample;
// The maximum block size, in samples. This number represents the number of samples in each channel (not combined).
- uint16_t maxBlockSize;
+ drflac_uint16 maxBlockSize;
// The total number of samples making up the stream. This includes every channel. For example, if the stream has 2 channels,
// with each channel having a total of 4096, this value will be set to 2*4096 = 8192. Can be 0 in which case it's still a
// valid stream, but just means the total sample count is unknown. Likely the case with streams like internet radio.
- uint64_t totalSampleCount;
+ drflac_uint64 totalSampleCount;
// The container type. This is set based on whether or not the decoder was opened from a native or Ogg stream.
@@ -467,34 +483,34 @@ typedef struct
// The position of the seektable in the file.
- uint64_t seektablePos;
+ drflac_uint64 seektablePos;
// The size of the seektable.
- uint32_t seektableSize;
+ drflac_uint32 seektableSize;
// Information about the frame the decoder is currently sitting on.
drflac_frame currentFrame;
// The position of the first frame in the stream. This is only ever used for seeking.
- uint64_t firstFramePos;
+ drflac_uint64 firstFramePos;
// A hack to avoid a malloc() when opening a decoder with drflac_open_memory().
drflac__memory_stream memoryStream;
-
// A pointer to the decoded sample data. This is an offset of pExtraData.
- int32_t* pDecodedSamples;
+ drflac_int32* pDecodedSamples;
+ // Internal use only. Only used with Ogg containers. Points to a drflac_oggbs object. This is an offset of pExtraData.
+ void* _oggbs;
// The bit streamer. The raw FLAC data is fed through this object.
drflac_bs bs;
- // Variable length extra data. We attach this to the end of the object so we avoid unnecessary mallocs.
- uint8_t pExtraData[1];
-
+ // Variable length extra data. We attach this to the end of the object so we can avoid unnecessary mallocs.
+ drflac_uint8 pExtraData[1];
} drflac;
@@ -515,11 +531,22 @@ typedef struct
// This is the lowest level function for opening a FLAC stream. You can also use drflac_open_file() and drflac_open_memory()
// to open the stream from a file or from a block of memory respectively.
//
-// The STREAMINFO block must be present for this to succeed.
+// The STREAMINFO block must be present for this to succeed. Use drflac_open_relaxed() to open a FLAC stream where
+// the header may not be present.
//
// See also: drflac_open_file(), drflac_open_memory(), drflac_open_with_metadata(), drflac_close()
drflac* drflac_open(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData);
+// The same as drflac_open(), except attempts to open the stream even when a header block is not present.
+//
+// Because the header is not necessarily available, the caller must explicitly define the container (Native or Ogg). Do
+// not set this to drflac_container_unknown - that is for internal use only.
+//
+// Opening in relaxed mode will continue reading data from onRead until it finds a valid frame. If a frame is never
+// found it will continue forever. To abort, force your onRead callback to return 0, which dr_flac will use as an
+// indicator that the end of the stream was found.
+drflac* drflac_open_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_container container, void* pUserData);
+
// Opens a FLAC decoder and notifies the caller of the metadata chunks (album art, etc.).
//
// onRead [in] The function to call when data needs to be read from the client.
@@ -531,15 +558,29 @@ drflac* drflac_open(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUse
//
// Close the decoder with drflac_close().
//
-// This is slower than drflac_open(), so avoid this one if you don't need metadata. Internally, this will do a malloc()
-// and free() for every metadata block except for STREAMINFO and PADDING blocks.
+// This is slower than drflac_open(), so avoid this one if you don't need metadata. Internally, this will do a DRFLAC_MALLOC()
+// and DRFLAC_FREE() for every metadata block except for STREAMINFO and PADDING blocks.
//
-// The caller is notified of the metadata via the onMeta callback. All metadata blocks with be handled before the function
+// The caller is notified of the metadata via the onMeta callback. All metadata blocks will be handled before the function
// returns.
//
+// The STREAMINFO block must be present for this to succeed. Use drflac_open_with_metadata_relaxed() to open a FLAC
+// stream where the header may not be present.
+//
+// Note that this will behave inconsistently with drflac_open() if the stream is an Ogg encapsulated stream and a metadata
+// block is corrupted. This is due to the way the Ogg stream recovers from corrupted pages. When drflac_open_with_metadata()
+// is being used, the open routine will try to read the contents of the metadata block, whereas drflac_open() will simply
+// seek past it (for the sake of efficiency). This inconsistency can result in different samples being returned depending on
+// whether or not the stream is being opened with metadata.
+//
// See also: drflac_open_file_with_metadata(), drflac_open_memory_with_metadata(), drflac_open(), drflac_close()
drflac* drflac_open_with_metadata(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData);
+// The same as drflac_open_with_metadata(), except attemps to open the stream even when a header block is not present.
+//
+// See also: drflac_open_with_metadata(), drflac_open_relaxed()
+drflac* drflac_open_with_metadata_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, drflac_container container, void* pUserData);
+
// Closes the given FLAC decoder.
//
// pFlac [in] The decoder to close.
@@ -558,25 +599,50 @@ void drflac_close(drflac* pFlac);
//
// pBufferOut can be null, in which case the call will act as a seek, and the return value will be the number of samples
// seeked.
-uint64_t drflac_read_s32(drflac* pFlac, uint64_t samplesToRead, int32_t* pBufferOut);
+drflac_uint64 drflac_read_s32(drflac* pFlac, drflac_uint64 samplesToRead, drflac_int32* pBufferOut);
-// Same as drflac_read_s32(), except outputs samples as 16-bit integer PCM rather than 32-bit. Note
-// that this is lossey.
-uint64_t drflac_read_s16(drflac* pFlac, uint64_t samplesToRead, int16_t* pBufferOut);
+// Same as drflac_read_s32(), except outputs samples as 16-bit integer PCM rather than 32-bit.
+//
+// pFlac [in] The decoder.
+// samplesToRead [in] The number of samples to read.
+// pBufferOut [out, optional] A pointer to the buffer that will receive the decoded samples.
+//
+// Returns the number of samples actually read.
+//
+// pBufferOut can be null, in which case the call will act as a seek, and the return value will be the number of samples
+// seeked.
+//
+// Note that this is lossy for streams where the bits per sample is larger than 16.
+drflac_uint64 drflac_read_s16(drflac* pFlac, drflac_uint64 samplesToRead, drflac_int16* pBufferOut);
+
+// Same as drflac_read_s32(), except outputs samples as 32-bit floating-point PCM.
+//
+// pFlac [in] The decoder.
+// samplesToRead [in] The number of samples to read.
+// pBufferOut [out, optional] A pointer to the buffer that will receive the decoded samples.
+//
+// Returns the number of samples actually read.
+//
+// pBufferOut can be null, in which case the call will act as a seek, and the return value will be the number of samples
+// seeked.
+//
+// Note that this should be considered lossy due to the nature of floating point numbers not being able to exactly
+// represent every possible number.
+drflac_uint64 drflac_read_f32(drflac* pFlac, drflac_uint64 samplesToRead, float* pBufferOut);
// Seeks to the sample at the given index.
//
// pFlac [in] The decoder.
// sampleIndex [in] The index of the sample to seek to. See notes below.
//
-// Returns DR_TRUE if successful; DR_FALSE otherwise.
+// Returns DRFLAC_TRUE if successful; DRFLAC_FALSE otherwise.
//
// The sample index is based on interleaving. In a stereo stream, for example, the sample at index 0 is the first sample
// in the left channel; the sample at index 1 is the first sample on the right channel, and so on.
//
// When seeking, you will likely want to ensure it's rounded to a multiple of the channel count. You can do this with
// something like drflac_seek_to_sample(pFlac, (mySampleIndex + (mySampleIndex % pFlac->channels)))
-dr_bool32 drflac_seek_to_sample(drflac* pFlac, uint64_t sampleIndex);
+drflac_bool32 drflac_seek_to_sample(drflac* pFlac, drflac_uint64 sampleIndex);
@@ -618,43 +684,58 @@ drflac* drflac_open_memory_with_metadata(const void* data, size_t dataSize, drfl
//// High Level APIs ////
// Opens a FLAC stream from the given callbacks and fully decodes it in a single operation. The return value is a
-// pointer to the sample data as interleaved signed 32-bit PCM. The returned data must be freed with drflac_free().
+// pointer to the sample data as interleaved signed 32-bit PCM. The returned data must be freed with DRFLAC_FREE().
//
// Sometimes a FLAC file won't keep track of the total sample count. In this situation the function will continuously
// read samples into a dynamically sized buffer on the heap until no samples are left.
//
// Do not call this function on a broadcast type of stream (like internet radio streams and whatnot).
-int32_t* drflac_open_and_decode_s32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount);
-int16_t* drflac_open_and_decode_s16(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount);
+drflac_int32* drflac_open_and_decode_s32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount);
+
+// Same as drflac_open_and_decode_s32(), except returns signed 16-bit integer samples.
+drflac_int16* drflac_open_and_decode_s16(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount);
+
+// Same as drflac_open_and_decode_s32(), except returns 32-bit floating-point samples.
+float* drflac_open_and_decode_f32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount);
#ifndef DR_FLAC_NO_STDIO
// Same as drflac_open_and_decode_s32() except opens the decoder from a file.
-int32_t* drflac_open_and_decode_file_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount);
-int16_t* drflac_open_and_decode_file_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount);
+drflac_int32* drflac_open_and_decode_file_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount);
+
+// Same as drflac_open_and_decode_file_s32(), except returns signed 16-bit integer samples.
+drflac_int16* drflac_open_and_decode_file_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount);
+
+// Same as drflac_open_and_decode_file_f32(), except returns 32-bit floating-point samples.
+float* drflac_open_and_decode_file_f32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount);
#endif
// Same as drflac_open_and_decode_s32() except opens the decoder from a block of memory.
-int32_t* drflac_open_and_decode_memory_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount);
-int16_t* drflac_open_and_decode_memory_s16(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount);
+drflac_int32* drflac_open_and_decode_memory_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount);
-// Frees data returned by drflac_open_and_decode_*().
-void drflac_free(void* pSampleDataReturnedByOpenAndDecode);
+// Same as drflac_open_and_decode_memory_s32(), except returns signed 16-bit integer samples.
+drflac_int16* drflac_open_and_decode_memory_s16(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount);
+
+// Same as drflac_open_and_decode_memory_s32(), except returns 32-bit floating-point samples.
+float* drflac_open_and_decode_memory_f32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount);
+
+// Frees memory that was allocated internally by dr_flac.
+void drflac_free(void* p);
// Structure representing an iterator for vorbis comments in a VORBIS_COMMENT metadata block.
typedef struct
{
- uint32_t countRemaining;
+ drflac_uint32 countRemaining;
const char* pRunningData;
} drflac_vorbis_comment_iterator;
// Initializes a vorbis comment iterator. This can be used for iterating over the vorbis comments in a VORBIS_COMMENT
// metadata block.
-void drflac_init_vorbis_comment_iterator(drflac_vorbis_comment_iterator* pIter, uint32_t commentCount, const char* pComments);
+void drflac_init_vorbis_comment_iterator(drflac_vorbis_comment_iterator* pIter, drflac_uint32 commentCount, const char* pComments);
// Goes to the next vorbis comment in the given iterator. If null is returned it means there are no more comments. The
// returned string is NOT null terminated.
-const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, uint32_t* pCommentLengthOut);
+const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, drflac_uint32* pCommentLengthOut);
@@ -672,22 +753,119 @@ const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, ui
#ifdef DR_FLAC_IMPLEMENTATION
#include
#include
-#include
-#ifdef _MSC_VER
-#include // For _byteswap_ulong and _byteswap_uint64
+// CPU architecture.
+#if defined(__x86_64__) || defined(_M_X64)
+#define DRFLAC_X64
+#elif defined(__i386) || defined(_M_IX86)
+#define DRFLAC_X86
#endif
+// Compile-time CPU feature support.
+#if !defined(DR_FLAC_NO_SIMD) && (defined(DRFLAC_X86) || defined(DRFLAC_X64))
+ #ifdef _MSC_VER
+ #if _MSC_VER >= 1400
+ #include
+ static void drflac__cpuid(int info[4], int fid)
+ {
+ __cpuid(info, fid);
+ }
+ #else
+ #define DRFLAC_NO_CPUID
+ #endif
+ #else
+ #if defined(__GNUC__) || defined(__clang__)
+ static void drflac__cpuid(int info[4], int fid)
+ {
+ asm (
+ "movl %[fid], %%eax\n\t"
+ "cpuid\n\t"
+ "movl %%eax, %[info0]\n\t"
+ "movl %%ebx, %[info1]\n\t"
+ "movl %%ecx, %[info2]\n\t"
+ "movl %%edx, %[info3]\n\t"
+ : [info0] "=rm"(info[0]),
+ [info1] "=rm"(info[1]),
+ [info2] "=rm"(info[2]),
+ [info3] "=rm"(info[3])
+ : [fid] "rm"(fid)
+ : "eax", "ebx", "ecx", "edx"
+ );
+ }
+ #else
+ #define DRFLAC_NO_CPUID
+ #endif
+ #endif
+#else
+#define DRFLAC_NO_CPUID
+#endif
+
+
#ifdef __linux__
#define _BSD_SOURCE
#include
#endif
+#if defined(_MSC_VER) && _MSC_VER >= 1500
+#define DRFLAC_HAS_LZCNT_INTRINSIC
+#elif (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)))
+#define DRFLAC_HAS_LZCNT_INTRINSIC
+#elif defined(__clang__)
+ #if __has_builtin(__builtin_clzll) || __has_builtin(__builtin_clzl)
+ #define DRFLAC_HAS_LZCNT_INTRINSIC
+ #endif
+#endif
+
+#if defined(_MSC_VER) && _MSC_VER >= 1300
+#define DRFLAC_HAS_BYTESWAP_INTRINSIC
+#elif defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
+#define DRFLAC_HAS_BYTESWAP_INTRINSIC
+#elif defined(__clang__)
+ #if __has_builtin(__builtin_bswap16) && __has_builtin(__builtin_bswap32) && __has_builtin(__builtin_bswap64)
+ #define DRFLAC_HAS_BYTESWAP_INTRINSIC
+ #endif
+#endif
+
+
+// Standard library stuff.
+#ifndef DRFLAC_ASSERT
+#include
+#define DRFLAC_ASSERT(expression) assert(expression)
+#endif
+#ifndef DRFLAC_MALLOC
+#define DRFLAC_MALLOC(sz) malloc((sz))
+#endif
+#ifndef DRFLAC_REALLOC
+#define DRFLAC_REALLOC(p, sz) realloc((p), (sz))
+#endif
+#ifndef DRFLAC_FREE
+#define DRFLAC_FREE(p) free((p))
+#endif
+#ifndef DRFLAC_COPY_MEMORY
+#define DRFLAC_COPY_MEMORY(dst, src, sz) memcpy((dst), (src), (sz))
+#endif
+#ifndef DRFLAC_ZERO_MEMORY
+#define DRFLAC_ZERO_MEMORY(p, sz) memset((p), 0, (sz))
+#endif
+
+#define DRFLAC_MAX_SIMD_VECTOR_SIZE 64 // 64 for AVX-512 in the future.
+
#ifdef _MSC_VER
#define DRFLAC_INLINE __forceinline
#else
+#ifdef __GNUC__
+#define DRFLAC_INLINE inline __attribute__((always_inline))
+#else
#define DRFLAC_INLINE inline
#endif
+#endif
+
+typedef drflac_int32 drflac_result;
+#define DRFLAC_SUCCESS 0
+#define DRFLAC_ERROR -1 // A generic error.
+#define DRFLAC_INVALID_ARGS -2
+#define DRFLAC_END_OF_STREAM -128
+#define DRFLAC_CRC_MISMATCH -129
#define DRFLAC_SUBFRAME_CONSTANT 0
#define DRFLAC_SUBFRAME_VERBATIM 1
@@ -704,31 +882,68 @@ const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, ui
#define DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE 10
-//// Endian Management ////
-static DRFLAC_INLINE dr_bool32 drflac__is_little_endian()
+#define drflac_align(x, a) ((((x) + (a) - 1) / (a)) * (a))
+#define drflac_assert DRFLAC_ASSERT
+#define drflac_copy_memory DRFLAC_COPY_MEMORY
+#define drflac_zero_memory DRFLAC_ZERO_MEMORY
+
+
+// CPU caps.
+static drflac_bool32 drflac__gIsLZCNTSupported = DRFLAC_FALSE;
+#ifndef DRFLAC_NO_CPUID
+static drflac_bool32 drflac__gIsSSE42Supported = DRFLAC_FALSE;
+static void drflac__init_cpu_caps()
{
+ int info[4] = {0};
+
+ // LZCNT
+ drflac__cpuid(info, 0x80000001);
+ drflac__gIsLZCNTSupported = (info[2] & (1 << 5)) != 0;
+
+ // SSE4.2
+ drflac__cpuid(info, 1);
+ drflac__gIsSSE42Supported = (info[2] & (1 << 19)) != 0;
+}
+#endif
+
+
+//// Endian Management ////
+static DRFLAC_INLINE drflac_bool32 drflac__is_little_endian()
+{
+#if defined(DRFLAC_X86) || defined(DRFLAC_X64)
+ return DRFLAC_TRUE;
+#else
int n = 1;
return (*(char*)&n) == 1;
+#endif
}
-static DRFLAC_INLINE uint16_t drflac__swap_endian_uint16(uint16_t n)
+static DRFLAC_INLINE drflac_uint16 drflac__swap_endian_uint16(drflac_uint16 n)
{
-#ifdef _MSC_VER
- return _byteswap_ushort(n);
-#elif defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
- return __builtin_bswap16(n);
+#ifdef DRFLAC_HAS_BYTESWAP_INTRINSIC
+ #if defined(_MSC_VER)
+ return _byteswap_ushort(n);
+ #elif defined(__GNUC__) || defined(__clang__)
+ return __builtin_bswap16(n);
+ #else
+ #error "This compiler does not support the byte swap intrinsic."
+ #endif
#else
return ((n & 0xFF00) >> 8) |
((n & 0x00FF) << 8);
#endif
}
-static DRFLAC_INLINE uint32_t drflac__swap_endian_uint32(uint32_t n)
+static DRFLAC_INLINE drflac_uint32 drflac__swap_endian_uint32(drflac_uint32 n)
{
-#ifdef _MSC_VER
- return _byteswap_ulong(n);
-#elif defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
- return __builtin_bswap32(n);
+#ifdef DRFLAC_HAS_BYTESWAP_INTRINSIC
+ #if defined(_MSC_VER)
+ return _byteswap_ulong(n);
+ #elif defined(__GNUC__) || defined(__clang__)
+ return __builtin_bswap32(n);
+ #else
+ #error "This compiler does not support the byte swap intrinsic."
+ #endif
#else
return ((n & 0xFF000000) >> 24) |
((n & 0x00FF0000) >> 8) |
@@ -737,25 +952,30 @@ static DRFLAC_INLINE uint32_t drflac__swap_endian_uint32(uint32_t n)
#endif
}
-static DRFLAC_INLINE uint64_t drflac__swap_endian_uint64(uint64_t n)
+static DRFLAC_INLINE drflac_uint64 drflac__swap_endian_uint64(drflac_uint64 n)
{
-#ifdef _MSC_VER
- return _byteswap_uint64(n);
-#elif defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
- return __builtin_bswap64(n);
+#ifdef DRFLAC_HAS_BYTESWAP_INTRINSIC
+ #if defined(_MSC_VER)
+ return _byteswap_uint64(n);
+ #elif defined(__GNUC__) || defined(__clang__)
+ return __builtin_bswap64(n);
+ #else
+ #error "This compiler does not support the byte swap intrinsic."
+ #endif
#else
- return ((n & 0xFF00000000000000ULL) >> 56) |
- ((n & 0x00FF000000000000ULL) >> 40) |
- ((n & 0x0000FF0000000000ULL) >> 24) |
- ((n & 0x000000FF00000000ULL) >> 8) |
- ((n & 0x00000000FF000000ULL) << 8) |
- ((n & 0x0000000000FF0000ULL) << 24) |
- ((n & 0x000000000000FF00ULL) << 40) |
- ((n & 0x00000000000000FFULL) << 56);
+ return ((n & (drflac_uint64)0xFF00000000000000) >> 56) |
+ ((n & (drflac_uint64)0x00FF000000000000) >> 40) |
+ ((n & (drflac_uint64)0x0000FF0000000000) >> 24) |
+ ((n & (drflac_uint64)0x000000FF00000000) >> 8) |
+ ((n & (drflac_uint64)0x00000000FF000000) << 8) |
+ ((n & (drflac_uint64)0x0000000000FF0000) << 24) |
+ ((n & (drflac_uint64)0x000000000000FF00) << 40) |
+ ((n & (drflac_uint64)0x00000000000000FF) << 56);
#endif
}
-static DRFLAC_INLINE uint16_t drflac__be2host_16(uint16_t n)
+
+static DRFLAC_INLINE drflac_uint16 drflac__be2host_16(drflac_uint16 n)
{
#ifdef __linux__
return be16toh(n);
@@ -768,7 +988,7 @@ static DRFLAC_INLINE uint16_t drflac__be2host_16(uint16_t n)
#endif
}
-static DRFLAC_INLINE uint32_t drflac__be2host_32(uint32_t n)
+static DRFLAC_INLINE drflac_uint32 drflac__be2host_32(drflac_uint32 n)
{
#ifdef __linux__
return be32toh(n);
@@ -781,7 +1001,7 @@ static DRFLAC_INLINE uint32_t drflac__be2host_32(uint32_t n)
#endif
}
-static DRFLAC_INLINE uint64_t drflac__be2host_64(uint64_t n)
+static DRFLAC_INLINE drflac_uint64 drflac__be2host_64(drflac_uint64 n)
{
#ifdef __linux__
return be64toh(n);
@@ -795,7 +1015,7 @@ static DRFLAC_INLINE uint64_t drflac__be2host_64(uint64_t n)
}
-static DRFLAC_INLINE uint32_t drflac__le2host_32(uint32_t n)
+static DRFLAC_INLINE drflac_uint32 drflac__le2host_32(drflac_uint32 n)
{
#ifdef __linux__
return le32toh(n);
@@ -809,13 +1029,242 @@ static DRFLAC_INLINE uint32_t drflac__le2host_32(uint32_t n)
}
+static DRFLAC_INLINE drflac_uint32 drflac__unsynchsafe_32(drflac_uint32 n)
+{
+ drflac_uint32 result = 0;
+ result |= (n & 0x7F000000) >> 3;
+ result |= (n & 0x007F0000) >> 2;
+ result |= (n & 0x00007F00) >> 1;
+ result |= (n & 0x0000007F) >> 0;
+
+ return result;
+}
+
+
+
+// The CRC code below is based on this document: http://zlib.net/crc_v3.txt
+static drflac_uint8 drflac__crc8_table[] = {
+ 0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15, 0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,
+ 0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65, 0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D,
+ 0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5, 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
+ 0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85, 0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD,
+ 0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2, 0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA,
+ 0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2, 0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,
+ 0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32, 0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A,
+ 0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42, 0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A,
+ 0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C, 0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,
+ 0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC, 0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4,
+ 0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C, 0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44,
+ 0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C, 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
+ 0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B, 0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63,
+ 0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B, 0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13,
+ 0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB, 0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,
+ 0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB, 0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3
+};
+
+static drflac_uint16 drflac__crc16_table[] = {
+ 0x0000, 0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011,
+ 0x8033, 0x0036, 0x003C, 0x8039, 0x0028, 0x802D, 0x8027, 0x0022,
+ 0x8063, 0x0066, 0x006C, 0x8069, 0x0078, 0x807D, 0x8077, 0x0072,
+ 0x0050, 0x8055, 0x805F, 0x005A, 0x804B, 0x004E, 0x0044, 0x8041,
+ 0x80C3, 0x00C6, 0x00CC, 0x80C9, 0x00D8, 0x80DD, 0x80D7, 0x00D2,
+ 0x00F0, 0x80F5, 0x80FF, 0x00FA, 0x80EB, 0x00EE, 0x00E4, 0x80E1,
+ 0x00A0, 0x80A5, 0x80AF, 0x00AA, 0x80BB, 0x00BE, 0x00B4, 0x80B1,
+ 0x8093, 0x0096, 0x009C, 0x8099, 0x0088, 0x808D, 0x8087, 0x0082,
+ 0x8183, 0x0186, 0x018C, 0x8189, 0x0198, 0x819D, 0x8197, 0x0192,
+ 0x01B0, 0x81B5, 0x81BF, 0x01BA, 0x81AB, 0x01AE, 0x01A4, 0x81A1,
+ 0x01E0, 0x81E5, 0x81EF, 0x01EA, 0x81FB, 0x01FE, 0x01F4, 0x81F1,
+ 0x81D3, 0x01D6, 0x01DC, 0x81D9, 0x01C8, 0x81CD, 0x81C7, 0x01C2,
+ 0x0140, 0x8145, 0x814F, 0x014A, 0x815B, 0x015E, 0x0154, 0x8151,
+ 0x8173, 0x0176, 0x017C, 0x8179, 0x0168, 0x816D, 0x8167, 0x0162,
+ 0x8123, 0x0126, 0x012C, 0x8129, 0x0138, 0x813D, 0x8137, 0x0132,
+ 0x0110, 0x8115, 0x811F, 0x011A, 0x810B, 0x010E, 0x0104, 0x8101,
+ 0x8303, 0x0306, 0x030C, 0x8309, 0x0318, 0x831D, 0x8317, 0x0312,
+ 0x0330, 0x8335, 0x833F, 0x033A, 0x832B, 0x032E, 0x0324, 0x8321,
+ 0x0360, 0x8365, 0x836F, 0x036A, 0x837B, 0x037E, 0x0374, 0x8371,
+ 0x8353, 0x0356, 0x035C, 0x8359, 0x0348, 0x834D, 0x8347, 0x0342,
+ 0x03C0, 0x83C5, 0x83CF, 0x03CA, 0x83DB, 0x03DE, 0x03D4, 0x83D1,
+ 0x83F3, 0x03F6, 0x03FC, 0x83F9, 0x03E8, 0x83ED, 0x83E7, 0x03E2,
+ 0x83A3, 0x03A6, 0x03AC, 0x83A9, 0x03B8, 0x83BD, 0x83B7, 0x03B2,
+ 0x0390, 0x8395, 0x839F, 0x039A, 0x838B, 0x038E, 0x0384, 0x8381,
+ 0x0280, 0x8285, 0x828F, 0x028A, 0x829B, 0x029E, 0x0294, 0x8291,
+ 0x82B3, 0x02B6, 0x02BC, 0x82B9, 0x02A8, 0x82AD, 0x82A7, 0x02A2,
+ 0x82E3, 0x02E6, 0x02EC, 0x82E9, 0x02F8, 0x82FD, 0x82F7, 0x02F2,
+ 0x02D0, 0x82D5, 0x82DF, 0x02DA, 0x82CB, 0x02CE, 0x02C4, 0x82C1,
+ 0x8243, 0x0246, 0x024C, 0x8249, 0x0258, 0x825D, 0x8257, 0x0252,
+ 0x0270, 0x8275, 0x827F, 0x027A, 0x826B, 0x026E, 0x0264, 0x8261,
+ 0x0220, 0x8225, 0x822F, 0x022A, 0x823B, 0x023E, 0x0234, 0x8231,
+ 0x8213, 0x0216, 0x021C, 0x8219, 0x0208, 0x820D, 0x8207, 0x0202
+};
+
+static DRFLAC_INLINE drflac_uint8 drflac_crc8_byte(drflac_uint8 crc, drflac_uint8 data)
+{
+ return drflac__crc8_table[crc ^ data];
+}
+
+static DRFLAC_INLINE drflac_uint8 drflac_crc8(drflac_uint8 crc, drflac_uint32 data, drflac_uint32 count)
+{
+ drflac_assert(count <= 32);
+
+#ifdef DR_FLAC_NO_CRC
+ (void)crc;
+ (void)data;
+ (void)count;
+ return 0;
+#else
+#if 0
+ // REFERENCE (use of this implementation requires an explicit flush by doing "drflac_crc8(crc, 0, 8);")
+ drflac_uint8 p = 0x07;
+ for (int i = count-1; i >= 0; --i) {
+ drflac_uint8 bit = (data & (1 << i)) >> i;
+ if (crc & 0x80) {
+ crc = ((crc << 1) | bit) ^ p;
+ } else {
+ crc = ((crc << 1) | bit);
+ }
+ }
+ return crc;
+#else
+ drflac_uint32 wholeBytes = count >> 3;
+ drflac_uint32 leftoverBits = count - (wholeBytes*8);
+
+ static drflac_uint64 leftoverDataMaskTable[8] = {
+ 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F
+ };
+ drflac_uint64 leftoverDataMask = leftoverDataMaskTable[leftoverBits];
+
+ switch (wholeBytes) {
+ case 4: crc = drflac_crc8_byte(crc, (drflac_uint8)((data & (0xFF000000UL << leftoverBits)) >> (24 + leftoverBits)));
+ case 3: crc = drflac_crc8_byte(crc, (drflac_uint8)((data & (0x00FF0000UL << leftoverBits)) >> (16 + leftoverBits)));
+ case 2: crc = drflac_crc8_byte(crc, (drflac_uint8)((data & (0x0000FF00UL << leftoverBits)) >> ( 8 + leftoverBits)));
+ case 1: crc = drflac_crc8_byte(crc, (drflac_uint8)((data & (0x000000FFUL << leftoverBits)) >> ( 0 + leftoverBits)));
+ case 0: if (leftoverBits > 0) crc = (crc << leftoverBits) ^ drflac__crc8_table[(crc >> (8 - leftoverBits)) ^ (data & leftoverDataMask)];
+ }
+ return crc;
+#endif
+#endif
+}
+
+static DRFLAC_INLINE drflac_uint16 drflac_crc16_byte(drflac_uint16 crc, drflac_uint8 data)
+{
+ return (crc << 8) ^ drflac__crc16_table[(drflac_uint8)(crc >> 8) ^ data];
+}
+
+static DRFLAC_INLINE drflac_uint16 drflac_crc16_bytes(drflac_uint16 crc, drflac_cache_t data, drflac_uint32 byteCount)
+{
+ switch (byteCount)
+ {
+#ifdef DRFLAC_64BIT
+ case 8: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 56) & 0xFF));
+ case 7: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 48) & 0xFF));
+ case 6: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 40) & 0xFF));
+ case 5: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 32) & 0xFF));
+#endif
+ case 4: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 24) & 0xFF));
+ case 3: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 16) & 0xFF));
+ case 2: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 8) & 0xFF));
+ case 1: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 0) & 0xFF));
+ }
+
+ return crc;
+}
+
+static DRFLAC_INLINE drflac_uint16 drflac_crc16__32bit(drflac_uint16 crc, drflac_uint32 data, drflac_uint32 count)
+{
+ drflac_assert(count <= 64);
+
+#ifdef DR_FLAC_NO_CRC
+ (void)crc;
+ (void)data;
+ (void)count;
+ return 0;
+#else
+#if 0
+ // REFERENCE (use of this implementation requires an explicit flush by doing "drflac_crc16(crc, 0, 16);")
+ drflac_uint16 p = 0x8005;
+ for (int i = count-1; i >= 0; --i) {
+ drflac_uint16 bit = (data & (1ULL << i)) >> i;
+ if (r & 0x8000) {
+ r = ((r << 1) | bit) ^ p;
+ } else {
+ r = ((r << 1) | bit);
+ }
+ }
+
+ return crc;
+#else
+ drflac_uint32 wholeBytes = count >> 3;
+ drflac_uint32 leftoverBits = count - (wholeBytes*8);
+
+ static drflac_uint64 leftoverDataMaskTable[8] = {
+ 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F
+ };
+ drflac_uint64 leftoverDataMask = leftoverDataMaskTable[leftoverBits];
+
+ switch (wholeBytes) {
+ default:
+ case 4: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (0xFF000000UL << leftoverBits)) >> (24 + leftoverBits)));
+ case 3: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (0x00FF0000UL << leftoverBits)) >> (16 + leftoverBits)));
+ case 2: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (0x0000FF00UL << leftoverBits)) >> ( 8 + leftoverBits)));
+ case 1: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (0x000000FFUL << leftoverBits)) >> ( 0 + leftoverBits)));
+ case 0: if (leftoverBits > 0) crc = (crc << leftoverBits) ^ drflac__crc16_table[(crc >> (16 - leftoverBits)) ^ (data & leftoverDataMask)];
+ }
+ return crc;
+#endif
+#endif
+}
+
+static DRFLAC_INLINE drflac_uint16 drflac_crc16__64bit(drflac_uint16 crc, drflac_uint64 data, drflac_uint32 count)
+{
+ drflac_assert(count <= 64);
+
+#ifdef DR_FLAC_NO_CRC
+ (void)crc;
+ (void)data;
+ (void)count;
+ return 0;
+#else
+ drflac_uint32 wholeBytes = count >> 3;
+ drflac_uint32 leftoverBits = count - (wholeBytes*8);
+
+ static drflac_uint64 leftoverDataMaskTable[8] = {
+ 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F
+ };
+ drflac_uint64 leftoverDataMask = leftoverDataMaskTable[leftoverBits];
+
+ switch (wholeBytes) {
+ default:
+ case 8: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & ((drflac_uint64)0xFF00000000000000 << leftoverBits)) >> (56 + leftoverBits)));
+ case 7: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & ((drflac_uint64)0x00FF000000000000 << leftoverBits)) >> (48 + leftoverBits)));
+ case 6: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & ((drflac_uint64)0x0000FF0000000000 << leftoverBits)) >> (40 + leftoverBits)));
+ case 5: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & ((drflac_uint64)0x000000FF00000000 << leftoverBits)) >> (32 + leftoverBits)));
+ case 4: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & ((drflac_uint64)0x00000000FF000000 << leftoverBits)) >> (24 + leftoverBits)));
+ case 3: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & ((drflac_uint64)0x0000000000FF0000 << leftoverBits)) >> (16 + leftoverBits)));
+ case 2: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & ((drflac_uint64)0x000000000000FF00 << leftoverBits)) >> ( 8 + leftoverBits)));
+ case 1: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & ((drflac_uint64)0x00000000000000FF << leftoverBits)) >> ( 0 + leftoverBits)));
+ case 0: if (leftoverBits > 0) crc = (crc << leftoverBits) ^ drflac__crc16_table[(crc >> (16 - leftoverBits)) ^ (data & leftoverDataMask)];
+ }
+ return crc;
+#endif
+}
+
+
+static DRFLAC_INLINE drflac_uint16 drflac_crc16(drflac_uint16 crc, drflac_cache_t data, drflac_uint32 count)
+{
+#ifdef DRFLAC_64BIT
+ return drflac_crc16__64bit(crc, data, count);
+#else
+ return drflac_crc16__32bit(crc, data, count);
+#endif
+}
+
+
#ifdef DRFLAC_64BIT
#define drflac__be2host__cache_line drflac__be2host_64
#else
#define drflac__be2host__cache_line drflac__be2host_32
#endif
-
// BIT READING ATTEMPT #2
//
// This uses a 32- or 64-bit bit-shifted cache - as bits are read, the cache is shifted such that the first valid bit is sitting
@@ -827,9 +1276,9 @@ static DRFLAC_INLINE uint32_t drflac__le2host_32(uint32_t n)
#define DRFLAC_CACHE_L1_SIZE_BITS(bs) (sizeof((bs)->cache)*8)
#define DRFLAC_CACHE_L1_BITS_REMAINING(bs) (DRFLAC_CACHE_L1_SIZE_BITS(bs) - ((bs)->consumedBits))
#ifdef DRFLAC_64BIT
-#define DRFLAC_CACHE_L1_SELECTION_MASK(_bitCount) (~(((uint64_t)-1LL) >> (_bitCount)))
+#define DRFLAC_CACHE_L1_SELECTION_MASK(_bitCount) (~(((drflac_uint64)-1LL) >> (_bitCount)))
#else
-#define DRFLAC_CACHE_L1_SELECTION_MASK(_bitCount) (~(((uint32_t)-1) >> (_bitCount)))
+#define DRFLAC_CACHE_L1_SELECTION_MASK(_bitCount) (~(((drflac_uint32)-1) >> (_bitCount)))
#endif
#define DRFLAC_CACHE_L1_SELECTION_SHIFT(bs, _bitCount) (DRFLAC_CACHE_L1_SIZE_BITS(bs) - (_bitCount))
#define DRFLAC_CACHE_L1_SELECT(bs, _bitCount) (((bs)->cache) & DRFLAC_CACHE_L1_SELECTION_MASK(_bitCount))
@@ -838,18 +1287,54 @@ static DRFLAC_INLINE uint32_t drflac__le2host_32(uint32_t n)
#define DRFLAC_CACHE_L2_LINE_COUNT(bs) (DRFLAC_CACHE_L2_SIZE_BYTES(bs) / sizeof((bs)->cacheL2[0]))
#define DRFLAC_CACHE_L2_LINES_REMAINING(bs) (DRFLAC_CACHE_L2_LINE_COUNT(bs) - (bs)->nextL2Line)
-static DRFLAC_INLINE dr_bool32 drflac__reload_l1_cache_from_l2(drflac_bs* bs)
+
+#ifndef DR_FLAC_NO_CRC
+static DRFLAC_INLINE void drflac__reset_crc16(drflac_bs* bs)
+{
+ bs->crc16 = 0;
+ bs->crc16CacheIgnoredBytes = bs->consumedBits >> 3;
+}
+
+static DRFLAC_INLINE void drflac__update_crc16(drflac_bs* bs)
+{
+ bs->crc16 = drflac_crc16_bytes(bs->crc16, bs->crc16Cache, DRFLAC_CACHE_L1_SIZE_BYTES(bs) - bs->crc16CacheIgnoredBytes);
+ bs->crc16CacheIgnoredBytes = 0;
+}
+
+static DRFLAC_INLINE drflac_uint16 drflac__flush_crc16(drflac_bs* bs)
+{
+ // We should never be flushing in a situation where we are not aligned on a byte boundary.
+ drflac_assert((DRFLAC_CACHE_L1_BITS_REMAINING(bs) & 7) == 0);
+
+ // The bits that were read from the L1 cache need to be accumulated. The number of bytes needing to be accumulated is determined
+ // by the number of bits that have been consumed.
+ if (DRFLAC_CACHE_L1_BITS_REMAINING(bs) == 0) {
+ drflac__update_crc16(bs);
+ } else {
+ // We only accumulate the consumed bits.
+ bs->crc16 = drflac_crc16_bytes(bs->crc16, bs->crc16Cache >> DRFLAC_CACHE_L1_BITS_REMAINING(bs), (bs->consumedBits >> 3) - bs->crc16CacheIgnoredBytes);
+
+ // The bits that we just accumulated should never be accumulated again. We need to keep track of how many bytes were accumulated
+ // so we can handle that later.
+ bs->crc16CacheIgnoredBytes = bs->consumedBits >> 3;
+ }
+
+ return bs->crc16;
+}
+#endif
+
+static DRFLAC_INLINE drflac_bool32 drflac__reload_l1_cache_from_l2(drflac_bs* bs)
{
// Fast path. Try loading straight from L2.
if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) {
bs->cache = bs->cacheL2[bs->nextL2Line++];
- return DR_TRUE;
+ return DRFLAC_TRUE;
}
// If we get here it means we've run out of data in the L2 cache. We'll need to fetch more from the client, if there's
// any left.
if (bs->unalignedByteCount > 0) {
- return DR_FALSE; // If we have any unaligned bytes it means there's not more aligned bytes left in the client.
+ return DRFLAC_FALSE; // If we have any unaligned bytes it means there's no more aligned bytes left in the client.
}
size_t bytesRead = bs->onRead(bs->pUserData, bs->cacheL2, DRFLAC_CACHE_L2_SIZE_BYTES(bs));
@@ -857,7 +1342,7 @@ static DRFLAC_INLINE dr_bool32 drflac__reload_l1_cache_from_l2(drflac_bs* bs)
bs->nextL2Line = 0;
if (bytesRead == DRFLAC_CACHE_L2_SIZE_BYTES(bs)) {
bs->cache = bs->cacheL2[bs->nextL2Line++];
- return DR_TRUE;
+ return DRFLAC_TRUE;
}
@@ -870,35 +1355,39 @@ static DRFLAC_INLINE dr_bool32 drflac__reload_l1_cache_from_l2(drflac_bs* bs)
// We need to keep track of any unaligned bytes for later use.
bs->unalignedByteCount = bytesRead - (alignedL1LineCount * DRFLAC_CACHE_L1_SIZE_BYTES(bs));
if (bs->unalignedByteCount > 0) {
- bs->unalignedCache = bs->cacheL2[alignedL1LineCount];
+ bs->unalignedCache = bs->cacheL2[alignedL1LineCount];
}
- if (alignedL1LineCount > 0)
- {
+ if (alignedL1LineCount > 0) {
size_t offset = DRFLAC_CACHE_L2_LINE_COUNT(bs) - alignedL1LineCount;
for (size_t i = alignedL1LineCount; i > 0; --i) {
bs->cacheL2[i-1 + offset] = bs->cacheL2[i-1];
}
- bs->nextL2Line = offset;
+ bs->nextL2Line = (drflac_uint32)offset;
bs->cache = bs->cacheL2[bs->nextL2Line++];
- return DR_TRUE;
- }
- else
- {
+ return DRFLAC_TRUE;
+ } else {
// If we get into this branch it means we weren't able to load any L1-aligned data.
bs->nextL2Line = DRFLAC_CACHE_L2_LINE_COUNT(bs);
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
}
-static dr_bool32 drflac__reload_cache(drflac_bs* bs)
+static drflac_bool32 drflac__reload_cache(drflac_bs* bs)
{
+#ifndef DR_FLAC_NO_CRC
+ drflac__update_crc16(bs);
+#endif
+
// Fast path. Try just moving the next value in the L2 cache to the L1 cache.
if (drflac__reload_l1_cache_from_l2(bs)) {
bs->cache = drflac__be2host__cache_line(bs->cache);
bs->consumedBits = 0;
- return DR_TRUE;
+#ifndef DR_FLAC_NO_CRC
+ bs->crc16Cache = bs->cache;
+#endif
+ return DRFLAC_TRUE;
}
// Slow path.
@@ -908,15 +1397,21 @@ static dr_bool32 drflac__reload_cache(drflac_bs* bs)
// data from the unaligned cache.
size_t bytesRead = bs->unalignedByteCount;
if (bytesRead == 0) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
- assert(bytesRead < DRFLAC_CACHE_L1_SIZE_BYTES(bs));
- bs->consumedBits = (DRFLAC_CACHE_L1_SIZE_BYTES(bs) - bytesRead) * 8;
+ drflac_assert(bytesRead < DRFLAC_CACHE_L1_SIZE_BYTES(bs));
+ bs->consumedBits = (drflac_uint32)(DRFLAC_CACHE_L1_SIZE_BYTES(bs) - bytesRead) * 8;
bs->cache = drflac__be2host__cache_line(bs->unalignedCache);
bs->cache &= DRFLAC_CACHE_L1_SELECTION_MASK(DRFLAC_CACHE_L1_SIZE_BITS(bs) - bs->consumedBits); // <-- Make sure the consumed bits are always set to zero. Other parts of the library depend on this property.
- return DR_TRUE;
+ bs->unalignedByteCount = 0; // <-- At this point the unaligned bytes have been moved into the cache and we thus have no more unaligned bytes.
+
+#ifndef DR_FLAC_NO_CRC
+ bs->crc16Cache = bs->cache >> bs->consumedBits;
+ bs->crc16CacheIgnoredBytes = bs->consumedBits >> 3;
+#endif
+ return DRFLAC_TRUE;
}
static void drflac__reset_cache(drflac_bs* bs)
@@ -926,69 +1421,24 @@ static void drflac__reset_cache(drflac_bs* bs)
bs->cache = 0;
bs->unalignedByteCount = 0; // <-- This clears the trailing unaligned bytes.
bs->unalignedCache = 0;
+
+#ifndef DR_FLAC_NO_CRC
+ bs->crc16Cache = 0;
+ bs->crc16CacheIgnoredBytes = 0;
+#endif
}
-static dr_bool32 drflac__seek_bits(drflac_bs* bs, size_t bitsToSeek)
+
+static DRFLAC_INLINE drflac_bool32 drflac__read_uint32(drflac_bs* bs, unsigned int bitCount, drflac_uint32* pResultOut)
{
- if (bitsToSeek <= DRFLAC_CACHE_L1_BITS_REMAINING(bs)) {
- bs->consumedBits += bitsToSeek;
- bs->cache <<= bitsToSeek;
- return DR_TRUE;
- } else {
- // It straddles the cached data. This function isn't called too frequently so I'm favouring simplicity here.
- bitsToSeek -= DRFLAC_CACHE_L1_BITS_REMAINING(bs);
- bs->consumedBits += DRFLAC_CACHE_L1_BITS_REMAINING(bs);
- bs->cache = 0;
-
- size_t wholeBytesRemaining = bitsToSeek/8;
- if (wholeBytesRemaining > 0)
- {
- // The next bytes to seek will be located in the L2 cache. The problem is that the L2 cache is not byte aligned,
- // but rather DRFLAC_CACHE_L1_SIZE_BYTES aligned (usually 4 or 8). If, for example, the number of bytes to seek is
- // 3, we'll need to handle it in a special way.
- size_t wholeCacheLinesRemaining = wholeBytesRemaining / DRFLAC_CACHE_L1_SIZE_BYTES(bs);
- if (wholeCacheLinesRemaining < DRFLAC_CACHE_L2_LINES_REMAINING(bs))
- {
- wholeBytesRemaining -= wholeCacheLinesRemaining * DRFLAC_CACHE_L1_SIZE_BYTES(bs);
- bitsToSeek -= wholeCacheLinesRemaining * DRFLAC_CACHE_L1_SIZE_BITS(bs);
- bs->nextL2Line += wholeCacheLinesRemaining;
- }
- else
- {
- wholeBytesRemaining -= DRFLAC_CACHE_L2_LINES_REMAINING(bs) * DRFLAC_CACHE_L1_SIZE_BYTES(bs);
- bitsToSeek -= DRFLAC_CACHE_L2_LINES_REMAINING(bs) * DRFLAC_CACHE_L1_SIZE_BITS(bs);
- bs->nextL2Line += DRFLAC_CACHE_L2_LINES_REMAINING(bs);
-
- if (wholeBytesRemaining > 0) {
- bs->onSeek(bs->pUserData, (int)wholeBytesRemaining, drflac_seek_origin_current);
- bitsToSeek -= wholeBytesRemaining*8;
- }
- }
- }
-
-
- if (bitsToSeek > 0) {
- if (!drflac__reload_cache(bs)) {
- return DR_FALSE;
- }
-
- return drflac__seek_bits(bs, bitsToSeek);
- }
-
- return DR_TRUE;
- }
-}
-
-static dr_bool32 drflac__read_uint32(drflac_bs* bs, unsigned int bitCount, uint32_t* pResultOut)
-{
- assert(bs != NULL);
- assert(pResultOut != NULL);
- assert(bitCount > 0);
- assert(bitCount <= 32);
+ drflac_assert(bs != NULL);
+ drflac_assert(pResultOut != NULL);
+ drflac_assert(bitCount > 0);
+ drflac_assert(bitCount <= 32);
if (bs->consumedBits == DRFLAC_CACHE_L1_SIZE_BITS(bs)) {
if (!drflac__reload_cache(bs)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
}
@@ -998,165 +1448,259 @@ static dr_bool32 drflac__read_uint32(drflac_bs* bs, unsigned int bitCount, uint3
bs->consumedBits += bitCount;
bs->cache <<= bitCount;
} else {
- *pResultOut = (uint32_t)bs->cache;
+ *pResultOut = (drflac_uint32)bs->cache;
bs->consumedBits = DRFLAC_CACHE_L1_SIZE_BITS(bs);
bs->cache = 0;
}
- return DR_TRUE;
+ return DRFLAC_TRUE;
} else {
// It straddles the cached data. It will never cover more than the next chunk. We just read the number in two parts and combine them.
- size_t bitCountHi = DRFLAC_CACHE_L1_BITS_REMAINING(bs);
- size_t bitCountLo = bitCount - bitCountHi;
- uint32_t resultHi = DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, bitCountHi);
+ drflac_uint32 bitCountHi = DRFLAC_CACHE_L1_BITS_REMAINING(bs);
+ drflac_uint32 bitCountLo = bitCount - bitCountHi;
+ drflac_uint32 resultHi = DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, bitCountHi);
if (!drflac__reload_cache(bs)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
*pResultOut = (resultHi << bitCountLo) | DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, bitCountLo);
bs->consumedBits += bitCountLo;
bs->cache <<= bitCountLo;
- return DR_TRUE;
+ return DRFLAC_TRUE;
}
}
-static dr_bool32 drflac__read_int32(drflac_bs* bs, unsigned int bitCount, int32_t* pResult)
+static drflac_bool32 drflac__read_int32(drflac_bs* bs, unsigned int bitCount, drflac_int32* pResult)
{
- assert(bs != NULL);
- assert(pResult != NULL);
- assert(bitCount > 0);
- assert(bitCount <= 32);
+ drflac_assert(bs != NULL);
+ drflac_assert(pResult != NULL);
+ drflac_assert(bitCount > 0);
+ drflac_assert(bitCount <= 32);
- uint32_t result;
+ drflac_uint32 result;
if (!drflac__read_uint32(bs, bitCount, &result)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
- uint32_t signbit = ((result >> (bitCount-1)) & 0x01);
+ drflac_uint32 signbit = ((result >> (bitCount-1)) & 0x01);
result |= (~signbit + 1) << bitCount;
- *pResult = (int32_t)result;
- return DR_TRUE;
+ *pResult = (drflac_int32)result;
+ return DRFLAC_TRUE;
}
-static dr_bool32 drflac__read_uint64(drflac_bs* bs, unsigned int bitCount, uint64_t* pResultOut)
+static drflac_bool32 drflac__read_uint64(drflac_bs* bs, unsigned int bitCount, drflac_uint64* pResultOut)
{
- assert(bitCount <= 64);
- assert(bitCount > 32);
+ drflac_assert(bitCount <= 64);
+ drflac_assert(bitCount > 32);
- uint32_t resultHi;
+ drflac_uint32 resultHi;
if (!drflac__read_uint32(bs, bitCount - 32, &resultHi)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
- uint32_t resultLo;
+ drflac_uint32 resultLo;
if (!drflac__read_uint32(bs, 32, &resultLo)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
- *pResultOut = (((uint64_t)resultHi) << 32) | ((uint64_t)resultLo);
- return DR_TRUE;
+ *pResultOut = (((drflac_uint64)resultHi) << 32) | ((drflac_uint64)resultLo);
+ return DRFLAC_TRUE;
}
// Function below is unused, but leaving it here in case I need to quickly add it again.
#if 0
-static dr_bool32 drflac__read_int64(drflac_bs* bs, unsigned int bitCount, int64_t* pResultOut)
+static drflac_bool32 drflac__read_int64(drflac_bs* bs, unsigned int bitCount, drflac_int64* pResultOut)
{
- assert(bitCount <= 64);
+ drflac_assert(bitCount <= 64);
- uint64_t result;
+ drflac_uint64 result;
if (!drflac__read_uint64(bs, bitCount, &result)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
- uint64_t signbit = ((result >> (bitCount-1)) & 0x01);
+ drflac_uint64 signbit = ((result >> (bitCount-1)) & 0x01);
result |= (~signbit + 1) << bitCount;
- *pResultOut = (int64_t)result;
- return DR_TRUE;
+ *pResultOut = (drflac_int64)result;
+ return DRFLAC_TRUE;
}
#endif
-static dr_bool32 drflac__read_uint16(drflac_bs* bs, unsigned int bitCount, uint16_t* pResult)
+static drflac_bool32 drflac__read_uint16(drflac_bs* bs, unsigned int bitCount, drflac_uint16* pResult)
{
- assert(bs != NULL);
- assert(pResult != NULL);
- assert(bitCount > 0);
- assert(bitCount <= 16);
+ drflac_assert(bs != NULL);
+ drflac_assert(pResult != NULL);
+ drflac_assert(bitCount > 0);
+ drflac_assert(bitCount <= 16);
- uint32_t result;
+ drflac_uint32 result;
if (!drflac__read_uint32(bs, bitCount, &result)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
- *pResult = (uint16_t)result;
- return DR_TRUE;
+ *pResult = (drflac_uint16)result;
+ return DRFLAC_TRUE;
}
-static dr_bool32 drflac__read_int16(drflac_bs* bs, unsigned int bitCount, int16_t* pResult)
+#if 0
+static drflac_bool32 drflac__read_int16(drflac_bs* bs, unsigned int bitCount, drflac_int16* pResult)
{
- assert(bs != NULL);
- assert(pResult != NULL);
- assert(bitCount > 0);
- assert(bitCount <= 16);
+ drflac_assert(bs != NULL);
+ drflac_assert(pResult != NULL);
+ drflac_assert(bitCount > 0);
+ drflac_assert(bitCount <= 16);
- int32_t result;
+ drflac_int32 result;
if (!drflac__read_int32(bs, bitCount, &result)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
- *pResult = (int16_t)result;
- return DR_TRUE;
+ *pResult = (drflac_int16)result;
+ return DRFLAC_TRUE;
}
+#endif
-static dr_bool32 drflac__read_uint8(drflac_bs* bs, unsigned int bitCount, uint8_t* pResult)
+static drflac_bool32 drflac__read_uint8(drflac_bs* bs, unsigned int bitCount, drflac_uint8* pResult)
{
- assert(bs != NULL);
- assert(pResult != NULL);
- assert(bitCount > 0);
- assert(bitCount <= 8);
+ drflac_assert(bs != NULL);
+ drflac_assert(pResult != NULL);
+ drflac_assert(bitCount > 0);
+ drflac_assert(bitCount <= 8);
- uint32_t result;
+ drflac_uint32 result;
if (!drflac__read_uint32(bs, bitCount, &result)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
- *pResult = (uint8_t)result;
- return DR_TRUE;
+ *pResult = (drflac_uint8)result;
+ return DRFLAC_TRUE;
}
-static dr_bool32 drflac__read_int8(drflac_bs* bs, unsigned int bitCount, int8_t* pResult)
+static drflac_bool32 drflac__read_int8(drflac_bs* bs, unsigned int bitCount, drflac_int8* pResult)
{
- assert(bs != NULL);
- assert(pResult != NULL);
- assert(bitCount > 0);
- assert(bitCount <= 8);
+ drflac_assert(bs != NULL);
+ drflac_assert(pResult != NULL);
+ drflac_assert(bitCount > 0);
+ drflac_assert(bitCount <= 8);
- int32_t result;
+ drflac_int32 result;
if (!drflac__read_int32(bs, bitCount, &result)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
- *pResult = (int8_t)result;
- return DR_TRUE;
+ *pResult = (drflac_int8)result;
+ return DRFLAC_TRUE;
}
-static inline dr_bool32 drflac__seek_past_next_set_bit(drflac_bs* bs, unsigned int* pOffsetOut)
+static drflac_bool32 drflac__seek_bits(drflac_bs* bs, size_t bitsToSeek)
{
- unsigned int zeroCounter = 0;
- while (bs->cache == 0) {
- zeroCounter += (unsigned int)DRFLAC_CACHE_L1_BITS_REMAINING(bs);
- if (!drflac__reload_cache(bs)) {
- return DR_FALSE;
+ if (bitsToSeek <= DRFLAC_CACHE_L1_BITS_REMAINING(bs)) {
+ bs->consumedBits += (drflac_uint32)bitsToSeek;
+ bs->cache <<= bitsToSeek;
+ return DRFLAC_TRUE;
+ } else {
+ // It straddles the cached data. This function isn't called too frequently so I'm favouring simplicity here.
+ bitsToSeek -= DRFLAC_CACHE_L1_BITS_REMAINING(bs);
+ bs->consumedBits += DRFLAC_CACHE_L1_BITS_REMAINING(bs);
+ bs->cache = 0;
+
+ // Simple case. Seek in groups of the same number as bits that fit within a cache line.
+#ifdef DRFLAC_64BIT
+ while (bitsToSeek >= DRFLAC_CACHE_L1_SIZE_BITS(bs)) {
+ drflac_uint64 bin;
+ if (!drflac__read_uint64(bs, DRFLAC_CACHE_L1_SIZE_BITS(bs), &bin)) {
+ return DRFLAC_FALSE;
+ }
+ bitsToSeek -= DRFLAC_CACHE_L1_SIZE_BITS(bs);
+ }
+#else
+ while (bitsToSeek >= DRFLAC_CACHE_L1_SIZE_BITS(bs)) {
+ drflac_uint32 bin;
+ if (!drflac__read_uint32(bs, DRFLAC_CACHE_L1_SIZE_BITS(bs), &bin)) {
+ return DRFLAC_FALSE;
+ }
+ bitsToSeek -= DRFLAC_CACHE_L1_SIZE_BITS(bs);
+ }
+#endif
+
+ // Whole leftover bytes.
+ while (bitsToSeek >= 8) {
+ drflac_uint8 bin;
+ if (!drflac__read_uint8(bs, 8, &bin)) {
+ return DRFLAC_FALSE;
+ }
+ bitsToSeek -= 8;
+ }
+
+ // Leftover bits.
+ if (bitsToSeek > 0) {
+ drflac_uint8 bin;
+ if (!drflac__read_uint8(bs, (drflac_uint32)bitsToSeek, &bin)) {
+ return DRFLAC_FALSE;
+ }
+ bitsToSeek = 0; // <-- Necessary for the assert below.
+ }
+
+ drflac_assert(bitsToSeek == 0);
+ return DRFLAC_TRUE;
+ }
+}
+
+
+// This function moves the bit streamer to the first bit after the sync code (bit 15 of the of the frame header). It will also update the CRC-16.
+static drflac_bool32 drflac__find_and_seek_to_next_sync_code(drflac_bs* bs)
+{
+ drflac_assert(bs != NULL);
+
+ // The sync code is always aligned to 8 bits. This is convenient for us because it means we can do byte-aligned movements. The first
+ // thing to do is align to the next byte.
+ if (!drflac__seek_bits(bs, DRFLAC_CACHE_L1_BITS_REMAINING(bs) & 7)) {
+ return DRFLAC_FALSE;
+ }
+
+ for (;;) {
+#ifndef DR_FLAC_NO_CRC
+ drflac__reset_crc16(bs);
+#endif
+
+ drflac_uint8 hi;
+ if (!drflac__read_uint8(bs, 8, &hi)) {
+ return DRFLAC_FALSE;
+ }
+
+ if (hi == 0xFF) {
+ drflac_uint8 lo;
+ if (!drflac__read_uint8(bs, 6, &lo)) {
+ return DRFLAC_FALSE;
+ }
+
+ if (lo == 0x3E) {
+ return DRFLAC_TRUE;
+ } else {
+ if (!drflac__seek_bits(bs, DRFLAC_CACHE_L1_BITS_REMAINING(bs) & 7)) {
+ return DRFLAC_FALSE;
+ }
+ }
}
}
- // At this point the cache should not be zero, in which case we know the first set bit should be somewhere in here. There is
- // no need for us to perform any cache reloading logic here which should make things much faster.
- assert(bs->cache != 0);
+ // Should never get here.
+ //return DRFLAC_FALSE;
+}
- unsigned int bitOffsetTable[] = {
+
+#if !defined(DR_FLAC_NO_SIMD) && defined(DRFLAC_HAS_LZCNT_INTRINSIC)
+#define DRFLAC_IMPLEMENT_CLZ_LZCNT
+#endif
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+#define DRFLAC_IMPLEMENT_CLZ_MSVC
+#endif
+
+static DRFLAC_INLINE drflac_uint32 drflac__clz_software(drflac_cache_t x)
+{
+ static drflac_uint32 clz_table_4[] = {
0,
4,
3, 3,
@@ -1164,91 +1708,169 @@ static inline dr_bool32 drflac__seek_past_next_set_bit(drflac_bs* bs, unsigned i
1, 1, 1, 1, 1, 1, 1, 1
};
- unsigned int setBitOffsetPlus1 = bitOffsetTable[DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, 4)];
- if (setBitOffsetPlus1 == 0) {
- if (bs->cache == 1) {
- setBitOffsetPlus1 = DRFLAC_CACHE_L1_SIZE_BITS(bs);
- } else {
- setBitOffsetPlus1 = 5;
- for (;;)
- {
- if ((bs->cache & DRFLAC_CACHE_L1_SELECT(bs, setBitOffsetPlus1))) {
- break;
- }
+ drflac_uint32 n = clz_table_4[x >> (sizeof(x)*8 - 4)];
+ if (n == 0) {
+#ifdef DRFLAC_64BIT
+ if ((x & 0xFFFFFFFF00000000ULL) == 0) { n = 32; x <<= 32; }
+ if ((x & 0xFFFF000000000000ULL) == 0) { n += 16; x <<= 16; }
+ if ((x & 0xFF00000000000000ULL) == 0) { n += 8; x <<= 8; }
+ if ((x & 0xF000000000000000ULL) == 0) { n += 4; x <<= 4; }
+#else
+ if ((x & 0xFFFF0000) == 0) { n = 16; x <<= 16; }
+ if ((x & 0xFF000000) == 0) { n += 8; x <<= 8; }
+ if ((x & 0xF0000000) == 0) { n += 4; x <<= 4; }
+#endif
+ n += clz_table_4[x >> (sizeof(x)*8 - 4)];
+ }
- setBitOffsetPlus1 += 1;
- }
+ return n - 1;
+}
+
+#ifdef DRFLAC_IMPLEMENT_CLZ_LZCNT
+static DRFLAC_INLINE drflac_bool32 drflac__is_lzcnt_supported()
+{
+ // If the compiler itself does not support the intrinsic then we'll need to return false.
+#ifdef DRFLAC_HAS_LZCNT_INTRINSIC
+ return drflac__gIsLZCNTSupported;
+#else
+ return DRFLAC_FALSE;
+#endif
+}
+
+static DRFLAC_INLINE drflac_uint32 drflac__clz_lzcnt(drflac_cache_t x)
+{
+#ifdef _MSC_VER
+ #ifdef DRFLAC_64BIT
+ return (drflac_uint32)__lzcnt64(x);
+ #else
+ return (drflac_uint32)__lzcnt(x);
+ #endif
+#else
+ #if defined(__GNUC__) || defined(__clang__)
+ #ifdef DRFLAC_64BIT
+ return (drflac_uint32)__builtin_clzll((unsigned long long)x);
+ #else
+ return (drflac_uint32)__builtin_clzl((unsigned long)x);
+ #endif
+ #else
+ // Unsupported compiler.
+ #error "This compiler does not support the lzcnt intrinsic."
+ #endif
+#endif
+}
+#endif
+
+#ifdef DRFLAC_IMPLEMENT_CLZ_MSVC
+static DRFLAC_INLINE drflac_uint32 drflac__clz_msvc(drflac_cache_t x)
+{
+ drflac_uint32 n;
+#ifdef DRFLAC_64BIT
+ _BitScanReverse64((unsigned long*)&n, x);
+#else
+ _BitScanReverse((unsigned long*)&n, x);
+#endif
+ return sizeof(x)*8 - n - 1;
+}
+#endif
+
+static DRFLAC_INLINE drflac_uint32 drflac__clz(drflac_cache_t x)
+{
+ // This function assumes at least one bit is set. Checking for 0 needs to be done at a higher level, outside this function.
+#ifdef DRFLAC_IMPLEMENT_CLZ_LZCNT
+ if (drflac__is_lzcnt_supported()) {
+ return drflac__clz_lzcnt(x);
+ } else
+#endif
+ {
+ #ifdef DRFLAC_IMPLEMENT_CLZ_MSVC
+ return drflac__clz_msvc(x);
+ #else
+ return drflac__clz_software(x);
+ #endif
+ }
+}
+
+
+static inline drflac_bool32 drflac__seek_past_next_set_bit(drflac_bs* bs, unsigned int* pOffsetOut)
+{
+ drflac_uint32 zeroCounter = 0;
+ while (bs->cache == 0) {
+ zeroCounter += (drflac_uint32)DRFLAC_CACHE_L1_BITS_REMAINING(bs);
+ if (!drflac__reload_cache(bs)) {
+ return DRFLAC_FALSE;
}
}
+ drflac_uint32 setBitOffsetPlus1 = drflac__clz(bs->cache);
+ zeroCounter += setBitOffsetPlus1;
+ setBitOffsetPlus1 += 1;
+
bs->consumedBits += setBitOffsetPlus1;
bs->cache <<= setBitOffsetPlus1;
*pOffsetOut = zeroCounter + setBitOffsetPlus1 - 1;
- return DR_TRUE;
+ return DRFLAC_TRUE;
}
-static dr_bool32 drflac__seek_to_byte(drflac_bs* bs, uint64_t offsetFromStart)
+static drflac_bool32 drflac__seek_to_byte(drflac_bs* bs, drflac_uint64 offsetFromStart)
{
- assert(bs != NULL);
- assert(offsetFromStart > 0);
+ drflac_assert(bs != NULL);
+ drflac_assert(offsetFromStart > 0);
// Seeking from the start is not quite as trivial as it sounds because the onSeek callback takes a signed 32-bit integer (which
// is intentional because it simplifies the implementation of the onSeek callbacks), however offsetFromStart is unsigned 64-bit.
// To resolve we just need to do an initial seek from the start, and then a series of offset seeks to make up the remainder.
- if (offsetFromStart > 0x7FFFFFFF)
- {
- uint64_t bytesRemaining = offsetFromStart;
+ if (offsetFromStart > 0x7FFFFFFF) {
+ drflac_uint64 bytesRemaining = offsetFromStart;
if (!bs->onSeek(bs->pUserData, 0x7FFFFFFF, drflac_seek_origin_start)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
bytesRemaining -= 0x7FFFFFFF;
-
while (bytesRemaining > 0x7FFFFFFF) {
if (!bs->onSeek(bs->pUserData, 0x7FFFFFFF, drflac_seek_origin_current)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
bytesRemaining -= 0x7FFFFFFF;
}
-
if (bytesRemaining > 0) {
if (!bs->onSeek(bs->pUserData, (int)bytesRemaining, drflac_seek_origin_current)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
}
- }
- else
- {
+ } else {
if (!bs->onSeek(bs->pUserData, (int)offsetFromStart, drflac_seek_origin_start)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
}
-
// The cache should be reset to force a reload of fresh data from the client.
drflac__reset_cache(bs);
- return DR_TRUE;
+ return DRFLAC_TRUE;
}
-static dr_bool32 drflac__read_utf8_coded_number(drflac_bs* bs, uint64_t* pNumberOut)
+static drflac_result drflac__read_utf8_coded_number(drflac_bs* bs, drflac_uint64* pNumberOut, drflac_uint8* pCRCOut)
{
- assert(bs != NULL);
- assert(pNumberOut != NULL);
+ drflac_assert(bs != NULL);
+ drflac_assert(pNumberOut != NULL);
+
+ drflac_uint8 crc = *pCRCOut;
unsigned char utf8[7] = {0};
if (!drflac__read_uint8(bs, 8, utf8)) {
*pNumberOut = 0;
- return DR_FALSE;
+ return DRFLAC_END_OF_STREAM;
}
+ crc = drflac_crc8(crc, utf8[0], 8);
if ((utf8[0] & 0x80) == 0) {
*pNumberOut = utf8[0];
- return DR_TRUE;
+ *pCRCOut = crc;
+ return DRFLAC_SUCCESS;
}
int byteCount = 1;
@@ -1266,57 +1888,43 @@ static dr_bool32 drflac__read_utf8_coded_number(drflac_bs* bs, uint64_t* pNumber
byteCount = 7;
} else {
*pNumberOut = 0;
- return DR_FALSE; // Bad UTF-8 encoding.
+ return DRFLAC_CRC_MISMATCH; // Bad UTF-8 encoding.
}
// Read extra bytes.
- assert(byteCount > 1);
+ drflac_assert(byteCount > 1);
- uint64_t result = (uint64_t)(utf8[0] & (0xFF >> (byteCount + 1)));
+ drflac_uint64 result = (drflac_uint64)(utf8[0] & (0xFF >> (byteCount + 1)));
for (int i = 1; i < byteCount; ++i) {
if (!drflac__read_uint8(bs, 8, utf8 + i)) {
*pNumberOut = 0;
- return DR_FALSE;
+ return DRFLAC_END_OF_STREAM;
}
+ crc = drflac_crc8(crc, utf8[i], 8);
result = (result << 6) | (utf8[i] & 0x3F);
}
*pNumberOut = result;
- return DR_TRUE;
+ *pCRCOut = crc;
+ return DRFLAC_SUCCESS;
}
-static DRFLAC_INLINE dr_bool32 drflac__read_and_seek_rice(drflac_bs* bs, uint8_t m)
-{
- unsigned int unused;
- if (!drflac__seek_past_next_set_bit(bs, &unused)) {
- return DR_FALSE;
- }
-
- if (m > 0) {
- if (!drflac__seek_bits(bs, m)) {
- return DR_FALSE;
- }
- }
-
- return DR_TRUE;
-}
-
// The next two functions are responsible for calculating the prediction.
//
// When the bits per sample is >16 we need to use 64-bit integer arithmetic because otherwise we'll run out of precision. It's
// safe to assume this will be slower on 32-bit platforms so we use a more optimal solution when the bits per sample is <=16.
-static DRFLAC_INLINE int32_t drflac__calculate_prediction_32(uint32_t order, int32_t shift, const int16_t* coefficients, int32_t* pDecodedSamples)
+static DRFLAC_INLINE drflac_int32 drflac__calculate_prediction_32(drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pDecodedSamples)
{
- assert(order <= 32);
+ drflac_assert(order <= 32);
// 32-bit version.
// VC++ optimizes this to a single jmp. I've not yet verified this for other compilers.
- int32_t prediction = 0;
+ drflac_int32 prediction = 0;
switch (order)
{
@@ -1354,137 +1962,137 @@ static DRFLAC_INLINE int32_t drflac__calculate_prediction_32(uint32_t order, int
case 1: prediction += coefficients[ 0] * pDecodedSamples[- 1];
}
- return (int32_t)(prediction >> shift);
+ return (drflac_int32)(prediction >> shift);
}
-static DRFLAC_INLINE int32_t drflac__calculate_prediction_64(uint32_t order, int32_t shift, const int16_t* coefficients, int32_t* pDecodedSamples)
+static DRFLAC_INLINE drflac_int32 drflac__calculate_prediction_64(drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pDecodedSamples)
{
- assert(order <= 32);
+ drflac_assert(order <= 32);
// 64-bit version.
// This method is faster on the 32-bit build when compiling with VC++. See note below.
#ifndef DRFLAC_64BIT
- int64_t prediction;
+ drflac_int64 prediction;
if (order == 8)
{
- prediction = coefficients[0] * (int64_t)pDecodedSamples[-1];
- prediction += coefficients[1] * (int64_t)pDecodedSamples[-2];
- prediction += coefficients[2] * (int64_t)pDecodedSamples[-3];
- prediction += coefficients[3] * (int64_t)pDecodedSamples[-4];
- prediction += coefficients[4] * (int64_t)pDecodedSamples[-5];
- prediction += coefficients[5] * (int64_t)pDecodedSamples[-6];
- prediction += coefficients[6] * (int64_t)pDecodedSamples[-7];
- prediction += coefficients[7] * (int64_t)pDecodedSamples[-8];
+ prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
+ prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
+ prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
+ prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
+ prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
+ prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6];
+ prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7];
+ prediction += coefficients[7] * (drflac_int64)pDecodedSamples[-8];
}
else if (order == 7)
{
- prediction = coefficients[0] * (int64_t)pDecodedSamples[-1];
- prediction += coefficients[1] * (int64_t)pDecodedSamples[-2];
- prediction += coefficients[2] * (int64_t)pDecodedSamples[-3];
- prediction += coefficients[3] * (int64_t)pDecodedSamples[-4];
- prediction += coefficients[4] * (int64_t)pDecodedSamples[-5];
- prediction += coefficients[5] * (int64_t)pDecodedSamples[-6];
- prediction += coefficients[6] * (int64_t)pDecodedSamples[-7];
+ prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
+ prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
+ prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
+ prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
+ prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
+ prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6];
+ prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7];
}
else if (order == 3)
{
- prediction = coefficients[0] * (int64_t)pDecodedSamples[-1];
- prediction += coefficients[1] * (int64_t)pDecodedSamples[-2];
- prediction += coefficients[2] * (int64_t)pDecodedSamples[-3];
+ prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
+ prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
+ prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
}
else if (order == 6)
{
- prediction = coefficients[0] * (int64_t)pDecodedSamples[-1];
- prediction += coefficients[1] * (int64_t)pDecodedSamples[-2];
- prediction += coefficients[2] * (int64_t)pDecodedSamples[-3];
- prediction += coefficients[3] * (int64_t)pDecodedSamples[-4];
- prediction += coefficients[4] * (int64_t)pDecodedSamples[-5];
- prediction += coefficients[5] * (int64_t)pDecodedSamples[-6];
+ prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
+ prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
+ prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
+ prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
+ prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
+ prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6];
}
else if (order == 5)
{
- prediction = coefficients[0] * (int64_t)pDecodedSamples[-1];
- prediction += coefficients[1] * (int64_t)pDecodedSamples[-2];
- prediction += coefficients[2] * (int64_t)pDecodedSamples[-3];
- prediction += coefficients[3] * (int64_t)pDecodedSamples[-4];
- prediction += coefficients[4] * (int64_t)pDecodedSamples[-5];
+ prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
+ prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
+ prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
+ prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
+ prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
}
else if (order == 4)
{
- prediction = coefficients[0] * (int64_t)pDecodedSamples[-1];
- prediction += coefficients[1] * (int64_t)pDecodedSamples[-2];
- prediction += coefficients[2] * (int64_t)pDecodedSamples[-3];
- prediction += coefficients[3] * (int64_t)pDecodedSamples[-4];
+ prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
+ prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
+ prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
+ prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
}
else if (order == 12)
{
- prediction = coefficients[0] * (int64_t)pDecodedSamples[-1];
- prediction += coefficients[1] * (int64_t)pDecodedSamples[-2];
- prediction += coefficients[2] * (int64_t)pDecodedSamples[-3];
- prediction += coefficients[3] * (int64_t)pDecodedSamples[-4];
- prediction += coefficients[4] * (int64_t)pDecodedSamples[-5];
- prediction += coefficients[5] * (int64_t)pDecodedSamples[-6];
- prediction += coefficients[6] * (int64_t)pDecodedSamples[-7];
- prediction += coefficients[7] * (int64_t)pDecodedSamples[-8];
- prediction += coefficients[8] * (int64_t)pDecodedSamples[-9];
- prediction += coefficients[9] * (int64_t)pDecodedSamples[-10];
- prediction += coefficients[10] * (int64_t)pDecodedSamples[-11];
- prediction += coefficients[11] * (int64_t)pDecodedSamples[-12];
+ prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
+ prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
+ prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
+ prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
+ prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
+ prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6];
+ prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7];
+ prediction += coefficients[7] * (drflac_int64)pDecodedSamples[-8];
+ prediction += coefficients[8] * (drflac_int64)pDecodedSamples[-9];
+ prediction += coefficients[9] * (drflac_int64)pDecodedSamples[-10];
+ prediction += coefficients[10] * (drflac_int64)pDecodedSamples[-11];
+ prediction += coefficients[11] * (drflac_int64)pDecodedSamples[-12];
}
else if (order == 2)
{
- prediction = coefficients[0] * (int64_t)pDecodedSamples[-1];
- prediction += coefficients[1] * (int64_t)pDecodedSamples[-2];
+ prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
+ prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
}
else if (order == 1)
{
- prediction = coefficients[0] * (int64_t)pDecodedSamples[-1];
+ prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
}
else if (order == 10)
{
- prediction = coefficients[0] * (int64_t)pDecodedSamples[-1];
- prediction += coefficients[1] * (int64_t)pDecodedSamples[-2];
- prediction += coefficients[2] * (int64_t)pDecodedSamples[-3];
- prediction += coefficients[3] * (int64_t)pDecodedSamples[-4];
- prediction += coefficients[4] * (int64_t)pDecodedSamples[-5];
- prediction += coefficients[5] * (int64_t)pDecodedSamples[-6];
- prediction += coefficients[6] * (int64_t)pDecodedSamples[-7];
- prediction += coefficients[7] * (int64_t)pDecodedSamples[-8];
- prediction += coefficients[8] * (int64_t)pDecodedSamples[-9];
- prediction += coefficients[9] * (int64_t)pDecodedSamples[-10];
+ prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
+ prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
+ prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
+ prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
+ prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
+ prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6];
+ prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7];
+ prediction += coefficients[7] * (drflac_int64)pDecodedSamples[-8];
+ prediction += coefficients[8] * (drflac_int64)pDecodedSamples[-9];
+ prediction += coefficients[9] * (drflac_int64)pDecodedSamples[-10];
}
else if (order == 9)
{
- prediction = coefficients[0] * (int64_t)pDecodedSamples[-1];
- prediction += coefficients[1] * (int64_t)pDecodedSamples[-2];
- prediction += coefficients[2] * (int64_t)pDecodedSamples[-3];
- prediction += coefficients[3] * (int64_t)pDecodedSamples[-4];
- prediction += coefficients[4] * (int64_t)pDecodedSamples[-5];
- prediction += coefficients[5] * (int64_t)pDecodedSamples[-6];
- prediction += coefficients[6] * (int64_t)pDecodedSamples[-7];
- prediction += coefficients[7] * (int64_t)pDecodedSamples[-8];
- prediction += coefficients[8] * (int64_t)pDecodedSamples[-9];
+ prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
+ prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
+ prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
+ prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
+ prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
+ prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6];
+ prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7];
+ prediction += coefficients[7] * (drflac_int64)pDecodedSamples[-8];
+ prediction += coefficients[8] * (drflac_int64)pDecodedSamples[-9];
}
else if (order == 11)
{
- prediction = coefficients[0] * (int64_t)pDecodedSamples[-1];
- prediction += coefficients[1] * (int64_t)pDecodedSamples[-2];
- prediction += coefficients[2] * (int64_t)pDecodedSamples[-3];
- prediction += coefficients[3] * (int64_t)pDecodedSamples[-4];
- prediction += coefficients[4] * (int64_t)pDecodedSamples[-5];
- prediction += coefficients[5] * (int64_t)pDecodedSamples[-6];
- prediction += coefficients[6] * (int64_t)pDecodedSamples[-7];
- prediction += coefficients[7] * (int64_t)pDecodedSamples[-8];
- prediction += coefficients[8] * (int64_t)pDecodedSamples[-9];
- prediction += coefficients[9] * (int64_t)pDecodedSamples[-10];
- prediction += coefficients[10] * (int64_t)pDecodedSamples[-11];
+ prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
+ prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
+ prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
+ prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
+ prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
+ prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6];
+ prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7];
+ prediction += coefficients[7] * (drflac_int64)pDecodedSamples[-8];
+ prediction += coefficients[8] * (drflac_int64)pDecodedSamples[-9];
+ prediction += coefficients[9] * (drflac_int64)pDecodedSamples[-10];
+ prediction += coefficients[10] * (drflac_int64)pDecodedSamples[-11];
}
else
{
prediction = 0;
for (int j = 0; j < (int)order; ++j) {
- prediction += coefficients[j] * (int64_t)pDecodedSamples[-j-1];
+ prediction += coefficients[j] * (drflac_int64)pDecodedSamples[-j-1];
}
}
#endif
@@ -1492,190 +2100,268 @@ static DRFLAC_INLINE int32_t drflac__calculate_prediction_64(uint32_t order, int
// VC++ optimizes this to a single jmp instruction, but only the 64-bit build. The 32-bit build generates less efficient code for some
// reason. The ugly version above is faster so we'll just switch between the two depending on the target platform.
#ifdef DRFLAC_64BIT
- int64_t prediction = 0;
+ drflac_int64 prediction = 0;
switch (order)
{
- case 32: prediction += coefficients[31] * (int64_t)pDecodedSamples[-32];
- case 31: prediction += coefficients[30] * (int64_t)pDecodedSamples[-31];
- case 30: prediction += coefficients[29] * (int64_t)pDecodedSamples[-30];
- case 29: prediction += coefficients[28] * (int64_t)pDecodedSamples[-29];
- case 28: prediction += coefficients[27] * (int64_t)pDecodedSamples[-28];
- case 27: prediction += coefficients[26] * (int64_t)pDecodedSamples[-27];
- case 26: prediction += coefficients[25] * (int64_t)pDecodedSamples[-26];
- case 25: prediction += coefficients[24] * (int64_t)pDecodedSamples[-25];
- case 24: prediction += coefficients[23] * (int64_t)pDecodedSamples[-24];
- case 23: prediction += coefficients[22] * (int64_t)pDecodedSamples[-23];
- case 22: prediction += coefficients[21] * (int64_t)pDecodedSamples[-22];
- case 21: prediction += coefficients[20] * (int64_t)pDecodedSamples[-21];
- case 20: prediction += coefficients[19] * (int64_t)pDecodedSamples[-20];
- case 19: prediction += coefficients[18] * (int64_t)pDecodedSamples[-19];
- case 18: prediction += coefficients[17] * (int64_t)pDecodedSamples[-18];
- case 17: prediction += coefficients[16] * (int64_t)pDecodedSamples[-17];
- case 16: prediction += coefficients[15] * (int64_t)pDecodedSamples[-16];
- case 15: prediction += coefficients[14] * (int64_t)pDecodedSamples[-15];
- case 14: prediction += coefficients[13] * (int64_t)pDecodedSamples[-14];
- case 13: prediction += coefficients[12] * (int64_t)pDecodedSamples[-13];
- case 12: prediction += coefficients[11] * (int64_t)pDecodedSamples[-12];
- case 11: prediction += coefficients[10] * (int64_t)pDecodedSamples[-11];
- case 10: prediction += coefficients[ 9] * (int64_t)pDecodedSamples[-10];
- case 9: prediction += coefficients[ 8] * (int64_t)pDecodedSamples[- 9];
- case 8: prediction += coefficients[ 7] * (int64_t)pDecodedSamples[- 8];
- case 7: prediction += coefficients[ 6] * (int64_t)pDecodedSamples[- 7];
- case 6: prediction += coefficients[ 5] * (int64_t)pDecodedSamples[- 6];
- case 5: prediction += coefficients[ 4] * (int64_t)pDecodedSamples[- 5];
- case 4: prediction += coefficients[ 3] * (int64_t)pDecodedSamples[- 4];
- case 3: prediction += coefficients[ 2] * (int64_t)pDecodedSamples[- 3];
- case 2: prediction += coefficients[ 1] * (int64_t)pDecodedSamples[- 2];
- case 1: prediction += coefficients[ 0] * (int64_t)pDecodedSamples[- 1];
+ case 32: prediction += coefficients[31] * (drflac_int64)pDecodedSamples[-32];
+ case 31: prediction += coefficients[30] * (drflac_int64)pDecodedSamples[-31];
+ case 30: prediction += coefficients[29] * (drflac_int64)pDecodedSamples[-30];
+ case 29: prediction += coefficients[28] * (drflac_int64)pDecodedSamples[-29];
+ case 28: prediction += coefficients[27] * (drflac_int64)pDecodedSamples[-28];
+ case 27: prediction += coefficients[26] * (drflac_int64)pDecodedSamples[-27];
+ case 26: prediction += coefficients[25] * (drflac_int64)pDecodedSamples[-26];
+ case 25: prediction += coefficients[24] * (drflac_int64)pDecodedSamples[-25];
+ case 24: prediction += coefficients[23] * (drflac_int64)pDecodedSamples[-24];
+ case 23: prediction += coefficients[22] * (drflac_int64)pDecodedSamples[-23];
+ case 22: prediction += coefficients[21] * (drflac_int64)pDecodedSamples[-22];
+ case 21: prediction += coefficients[20] * (drflac_int64)pDecodedSamples[-21];
+ case 20: prediction += coefficients[19] * (drflac_int64)pDecodedSamples[-20];
+ case 19: prediction += coefficients[18] * (drflac_int64)pDecodedSamples[-19];
+ case 18: prediction += coefficients[17] * (drflac_int64)pDecodedSamples[-18];
+ case 17: prediction += coefficients[16] * (drflac_int64)pDecodedSamples[-17];
+ case 16: prediction += coefficients[15] * (drflac_int64)pDecodedSamples[-16];
+ case 15: prediction += coefficients[14] * (drflac_int64)pDecodedSamples[-15];
+ case 14: prediction += coefficients[13] * (drflac_int64)pDecodedSamples[-14];
+ case 13: prediction += coefficients[12] * (drflac_int64)pDecodedSamples[-13];
+ case 12: prediction += coefficients[11] * (drflac_int64)pDecodedSamples[-12];
+ case 11: prediction += coefficients[10] * (drflac_int64)pDecodedSamples[-11];
+ case 10: prediction += coefficients[ 9] * (drflac_int64)pDecodedSamples[-10];
+ case 9: prediction += coefficients[ 8] * (drflac_int64)pDecodedSamples[- 9];
+ case 8: prediction += coefficients[ 7] * (drflac_int64)pDecodedSamples[- 8];
+ case 7: prediction += coefficients[ 6] * (drflac_int64)pDecodedSamples[- 7];
+ case 6: prediction += coefficients[ 5] * (drflac_int64)pDecodedSamples[- 6];
+ case 5: prediction += coefficients[ 4] * (drflac_int64)pDecodedSamples[- 5];
+ case 4: prediction += coefficients[ 3] * (drflac_int64)pDecodedSamples[- 4];
+ case 3: prediction += coefficients[ 2] * (drflac_int64)pDecodedSamples[- 3];
+ case 2: prediction += coefficients[ 1] * (drflac_int64)pDecodedSamples[- 2];
+ case 1: prediction += coefficients[ 0] * (drflac_int64)pDecodedSamples[- 1];
}
#endif
- return (int32_t)(prediction >> shift);
+ return (drflac_int32)(prediction >> shift);
}
-
-// Reads and decodes a string of residual values as Rice codes. The decoder should be sitting on the first bit of the Rice codes.
-//
-// This is the most frequently called function in the library. It does both the Rice decoding and the prediction in a single loop
-// iteration. The prediction is done at the end, and there's an annoying branch I'd like to avoid so the main function is defined
-// as a #define - sue me!
-#define DRFLAC__DECODE_SAMPLES_WITH_RESIDULE__RICE__PROC(funcName, predictionFunc) \
-static dr_bool32 funcName (drflac_bs* bs, uint32_t count, uint8_t riceParam, uint32_t order, int32_t shift, const int16_t* coefficients, int32_t* pSamplesOut) \
-{ \
- assert(bs != NULL); \
- assert(count > 0); \
- assert(pSamplesOut != NULL); \
- \
- static unsigned int bitOffsetTable[] = { \
- 0, \
- 4, \
- 3, 3, \
- 2, 2, 2, 2, \
- 1, 1, 1, 1, 1, 1, 1, 1 \
- }; \
- \
- drflac_cache_t riceParamMask = DRFLAC_CACHE_L1_SELECTION_MASK(riceParam); \
- drflac_cache_t resultHiShift = DRFLAC_CACHE_L1_SIZE_BITS(bs) - riceParam; \
- \
- for (int i = 0; i < (int)count; ++i) \
- { \
- unsigned int zeroCounter = 0; \
- while (bs->cache == 0) { \
- zeroCounter += (unsigned int)DRFLAC_CACHE_L1_BITS_REMAINING(bs); \
- if (!drflac__reload_cache(bs)) { \
- return DR_FALSE; \
- } \
- } \
- \
- /* At this point the cache should not be zero, in which case we know the first set bit should be somewhere in here. There is \
- no need for us to perform any cache reloading logic here which should make things much faster. */ \
- assert(bs->cache != 0); \
- unsigned int decodedRice; \
- \
- unsigned int setBitOffsetPlus1 = bitOffsetTable[DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, 4)]; \
- if (setBitOffsetPlus1 > 0) { \
- decodedRice = (zeroCounter + (setBitOffsetPlus1-1)) << riceParam; \
- } else { \
- if (bs->cache == 1) { \
- setBitOffsetPlus1 = DRFLAC_CACHE_L1_SIZE_BITS(bs); \
- decodedRice = (zeroCounter + (DRFLAC_CACHE_L1_SIZE_BITS(bs)-1)) << riceParam; \
- } else { \
- setBitOffsetPlus1 = 5; \
- for (;;) \
- { \
- if ((bs->cache & DRFLAC_CACHE_L1_SELECT(bs, setBitOffsetPlus1))) { \
- decodedRice = (zeroCounter + (setBitOffsetPlus1-1)) << riceParam; \
- break; \
- } \
- \
- setBitOffsetPlus1 += 1; \
- } \
- } \
- } \
- \
- \
- unsigned int bitsLo = 0; \
- unsigned int riceLength = setBitOffsetPlus1 + riceParam; \
- if (riceLength < DRFLAC_CACHE_L1_BITS_REMAINING(bs)) \
- { \
- bitsLo = (unsigned int)((bs->cache & (riceParamMask >> setBitOffsetPlus1)) >> (DRFLAC_CACHE_L1_SIZE_BITS(bs) - riceLength)); \
- \
- bs->consumedBits += riceLength; \
- bs->cache <<= riceLength; \
- } \
- else \
- { \
- bs->consumedBits += riceLength; \
- bs->cache <<= setBitOffsetPlus1; \
- \
- /* It straddles the cached data. It will never cover more than the next chunk. We just read the number in two parts and combine them. */ \
- size_t bitCountLo = bs->consumedBits - DRFLAC_CACHE_L1_SIZE_BITS(bs); \
- drflac_cache_t resultHi = bs->cache & riceParamMask; /* <-- This mask is OK because all bits after the first bits are always zero. */ \
- \
- \
- if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) { \
- bs->cache = drflac__be2host__cache_line(bs->cacheL2[bs->nextL2Line++]); \
- } else { \
- /* Slow path. We need to fetch more data from the client. */ \
- if (!drflac__reload_cache(bs)) { \
- return DR_FALSE; \
- } \
- } \
- \
- bitsLo = (unsigned int)((resultHi >> resultHiShift) | DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, bitCountLo)); \
- bs->consumedBits = bitCountLo; \
- bs->cache <<= bitCountLo; \
- } \
- \
- decodedRice |= bitsLo; \
- decodedRice = (decodedRice >> 1) ^ (~(decodedRice & 0x01) + 1); /* <-- Ah, much faster! :) */ \
- /* \
- if ((decodedRice & 0x01)) { \
- decodedRice = ~(decodedRice >> 1); \
- } else { \
- decodedRice = (decodedRice >> 1); \
- } \
- */ \
- \
- /* In order to properly calculate the prediction when the bits per sample is >16 we need to do it using 64-bit arithmetic. We can assume this \
- is probably going to be slower on 32-bit systems so we'll do a more optimized 32-bit version when the bits per sample is low enough.*/ \
- pSamplesOut[i] = ((int)decodedRice + predictionFunc(order, shift, coefficients, pSamplesOut + i)); \
- } \
- \
- return DR_TRUE; \
-} \
-
-DRFLAC__DECODE_SAMPLES_WITH_RESIDULE__RICE__PROC(drflac__decode_samples_with_residual__rice_64, drflac__calculate_prediction_64)
-DRFLAC__DECODE_SAMPLES_WITH_RESIDULE__RICE__PROC(drflac__decode_samples_with_residual__rice_32, drflac__calculate_prediction_32)
-
-
-// Reads and seeks past a string of residual values as Rice codes. The decoder should be sitting on the first bit of the Rice codes.
-static dr_bool32 drflac__read_and_seek_residual__rice(drflac_bs* bs, uint32_t count, uint8_t riceParam)
+#if 0
+// Reference implementation for reading and decoding samples with residual. This is intentionally left unoptimized for the
+// sake of readability and should only be used as a reference.
+static drflac_bool32 drflac__decode_samples_with_residual__rice__reference(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
{
- assert(bs != NULL);
- assert(count > 0);
+ drflac_assert(bs != NULL);
+ drflac_assert(count > 0);
+ drflac_assert(pSamplesOut != NULL);
- for (uint32_t i = 0; i < count; ++i) {
- if (!drflac__read_and_seek_rice(bs, riceParam)) {
- return DR_FALSE;
+ for (drflac_uint32 i = 0; i < count; ++i) {
+ drflac_uint32 zeroCounter = 0;
+ for (;;) {
+ drflac_uint8 bit;
+ if (!drflac__read_uint8(bs, 1, &bit)) {
+ return DRFLAC_FALSE;
+ }
+
+ if (bit == 0) {
+ zeroCounter += 1;
+ } else {
+ break;
+ }
+ }
+
+ drflac_uint32 decodedRice;
+ if (riceParam > 0) {
+ if (!drflac__read_uint32(bs, riceParam, &decodedRice)) {
+ return DRFLAC_FALSE;
+ }
+ } else {
+ decodedRice = 0;
+ }
+
+ decodedRice |= (zeroCounter << riceParam);
+ if ((decodedRice & 0x01)) {
+ decodedRice = ~(decodedRice >> 1);
+ } else {
+ decodedRice = (decodedRice >> 1);
+ }
+
+
+ if (bitsPerSample > 16) {
+ pSamplesOut[i] = decodedRice + drflac__calculate_prediction_64(order, shift, coefficients, pSamplesOut + i);
+ } else {
+ pSamplesOut[i] = decodedRice + drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + i);
}
}
- return DR_TRUE;
+ return DRFLAC_TRUE;
+}
+#endif
+
+#if 0
+static drflac_bool32 drflac__read_rice_parts__reference(drflac_bs* bs, drflac_uint8 riceParam, drflac_uint32* pZeroCounterOut, drflac_uint32* pRiceParamPartOut)
+{
+ drflac_uint32 zeroCounter = 0;
+ for (;;) {
+ drflac_uint8 bit;
+ if (!drflac__read_uint8(bs, 1, &bit)) {
+ return DRFLAC_FALSE;
+ }
+
+ if (bit == 0) {
+ zeroCounter += 1;
+ } else {
+ break;
+ }
+ }
+
+ drflac_uint32 decodedRice;
+ if (riceParam > 0) {
+ if (!drflac__read_uint32(bs, riceParam, &decodedRice)) {
+ return DRFLAC_FALSE;
+ }
+ } else {
+ decodedRice = 0;
+ }
+
+ *pZeroCounterOut = zeroCounter;
+ *pRiceParamPartOut = decodedRice;
+ return DRFLAC_TRUE;
+}
+#endif
+
+static DRFLAC_INLINE drflac_bool32 drflac__read_rice_parts(drflac_bs* bs, drflac_uint8 riceParam, drflac_uint32* pZeroCounterOut, drflac_uint32* pRiceParamPartOut)
+{
+ drflac_cache_t riceParamMask = DRFLAC_CACHE_L1_SELECTION_MASK(riceParam);
+ drflac_cache_t resultHiShift = DRFLAC_CACHE_L1_SIZE_BITS(bs) - riceParam;
+
+
+ drflac_uint32 zeroCounter = 0;
+ while (bs->cache == 0) {
+ zeroCounter += (drflac_uint32)DRFLAC_CACHE_L1_BITS_REMAINING(bs);
+ if (!drflac__reload_cache(bs)) {
+ return DRFLAC_FALSE;
+ }
+ }
+
+ drflac_uint32 setBitOffsetPlus1 = drflac__clz(bs->cache);
+ zeroCounter += setBitOffsetPlus1;
+ setBitOffsetPlus1 += 1;
+
+
+ drflac_uint32 riceParamPart;
+ drflac_uint32 riceLength = setBitOffsetPlus1 + riceParam;
+ if (riceLength < DRFLAC_CACHE_L1_BITS_REMAINING(bs)) {
+ riceParamPart = (drflac_uint32)((bs->cache & (riceParamMask >> setBitOffsetPlus1)) >> (DRFLAC_CACHE_L1_SIZE_BITS(bs) - riceLength));
+
+ bs->consumedBits += riceLength;
+ bs->cache <<= riceLength;
+ } else {
+ bs->consumedBits += riceLength;
+ if (setBitOffsetPlus1 < DRFLAC_CACHE_L1_SIZE_BITS(bs)) {
+ bs->cache <<= setBitOffsetPlus1;
+ }
+
+ // It straddles the cached data. It will never cover more than the next chunk. We just read the number in two parts and combine them.
+ drflac_uint32 bitCountLo = bs->consumedBits - DRFLAC_CACHE_L1_SIZE_BITS(bs);
+ drflac_cache_t resultHi = bs->cache & riceParamMask; // <-- This mask is OK because all bits after the first bits are always zero.
+
+ if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) {
+ #ifndef DR_FLAC_NO_CRC
+ drflac__update_crc16(bs);
+ #endif
+ bs->cache = drflac__be2host__cache_line(bs->cacheL2[bs->nextL2Line++]);
+ bs->consumedBits = 0;
+ #ifndef DR_FLAC_NO_CRC
+ bs->crc16Cache = bs->cache;
+ #endif
+ } else {
+ // Slow path. We need to fetch more data from the client.
+ if (!drflac__reload_cache(bs)) {
+ return DRFLAC_FALSE;
+ }
+ }
+
+ riceParamPart = (drflac_uint32)((resultHi >> resultHiShift) | DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, bitCountLo));
+
+ bs->consumedBits += bitCountLo;
+ bs->cache <<= bitCountLo;
+ }
+
+ *pZeroCounterOut = zeroCounter;
+ *pRiceParamPartOut = riceParamPart;
+ return DRFLAC_TRUE;
}
-static dr_bool32 drflac__decode_samples_with_residual__unencoded(drflac_bs* bs, uint32_t bitsPerSample, uint32_t count, uint8_t unencodedBitsPerSample, uint32_t order, int32_t shift, const int16_t* coefficients, int32_t* pSamplesOut)
-{
- assert(bs != NULL);
- assert(count > 0);
- assert(unencodedBitsPerSample > 0 && unencodedBitsPerSample <= 32);
- assert(pSamplesOut != NULL);
- for (unsigned int i = 0; i < count; ++i)
- {
+static drflac_bool32 drflac__decode_samples_with_residual__rice__simple(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
+{
+ drflac_assert(bs != NULL);
+ drflac_assert(count > 0);
+ drflac_assert(pSamplesOut != NULL);
+
+ drflac_uint32 zeroCountPart;
+ drflac_uint32 riceParamPart;
+
+ drflac_uint32 i = 0;
+ while (i < count) {
+ // Rice extraction.
+ if (!drflac__read_rice_parts(bs, riceParam, &zeroCountPart, &riceParamPart)) {
+ return DRFLAC_FALSE;
+ }
+
+ // Rice reconstruction.
+ static drflac_uint32 t[2] = {0x00000000, 0xFFFFFFFF};
+
+ riceParamPart |= (zeroCountPart << riceParam);
+ riceParamPart = (riceParamPart >> 1) ^ t[riceParamPart & 0x01];
+ //riceParamPart = (riceParamPart >> 1) ^ (~(riceParamPart & 0x01) + 1);
+
+ // Sample reconstruction.
+ if (bitsPerSample > 16) {
+ pSamplesOut[i] = riceParamPart + drflac__calculate_prediction_64(order, shift, coefficients, pSamplesOut + i);
+ } else {
+ pSamplesOut[i] = riceParamPart + drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + i);
+ }
+
+ i += 1;
+ }
+
+ return DRFLAC_TRUE;
+}
+
+static drflac_bool32 drflac__decode_samples_with_residual__rice(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
+{
+#if 0
+ return drflac__decode_samples_with_residual__rice__reference(bs, bitsPerSample, count, riceParam, order, shift, coefficients, pSamplesOut);
+#else
+ return drflac__decode_samples_with_residual__rice__simple(bs, bitsPerSample, count, riceParam, order, shift, coefficients, pSamplesOut);
+#endif
+}
+
+// Reads and seeks past a string of residual values as Rice codes. The decoder should be sitting on the first bit of the Rice codes.
+static drflac_bool32 drflac__read_and_seek_residual__rice(drflac_bs* bs, drflac_uint32 count, drflac_uint8 riceParam)
+{
+ drflac_assert(bs != NULL);
+ drflac_assert(count > 0);
+
+ for (drflac_uint32 i = 0; i < count; ++i) {
+ drflac_uint32 zeroCountPart;
+ drflac_uint32 riceParamPart;
+ if (!drflac__read_rice_parts(bs, riceParam, &zeroCountPart, &riceParamPart)) {
+ return DRFLAC_FALSE;
+ }
+ }
+
+ return DRFLAC_TRUE;
+}
+
+static drflac_bool32 drflac__decode_samples_with_residual__unencoded(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 unencodedBitsPerSample, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
+{
+ drflac_assert(bs != NULL);
+ drflac_assert(count > 0);
+ drflac_assert(unencodedBitsPerSample > 0 && unencodedBitsPerSample <= 32);
+ drflac_assert(pSamplesOut != NULL);
+
+ for (unsigned int i = 0; i < count; ++i) {
if (!drflac__read_int32(bs, unencodedBitsPerSample, pSamplesOut + i)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
if (bitsPerSample > 16) {
@@ -1685,53 +2371,52 @@ static dr_bool32 drflac__decode_samples_with_residual__unencoded(drflac_bs* bs,
}
}
- return DR_TRUE;
+ return DRFLAC_TRUE;
}
// Reads and decodes the residual for the sub-frame the decoder is currently sitting on. This function should be called
// when the decoder is sitting at the very start of the RESIDUAL block. The first residuals will be ignored. The
// and parameters are used to determine how many residual values need to be decoded.
-static dr_bool32 drflac__decode_samples_with_residual(drflac_bs* bs, uint32_t bitsPerSample, uint32_t blockSize, uint32_t order, int32_t shift, const int16_t* coefficients, int32_t* pDecodedSamples)
+static drflac_bool32 drflac__decode_samples_with_residual(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 blockSize, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pDecodedSamples)
{
- assert(bs != NULL);
- assert(blockSize != 0);
- assert(pDecodedSamples != NULL); // <-- Should we allow NULL, in which case we just seek past the residual rather than do a full decode?
+ drflac_assert(bs != NULL);
+ drflac_assert(blockSize != 0);
+ drflac_assert(pDecodedSamples != NULL); // <-- Should we allow NULL, in which case we just seek past the residual rather than do a full decode?
- uint8_t residualMethod;
+ drflac_uint8 residualMethod;
if (!drflac__read_uint8(bs, 2, &residualMethod)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
if (residualMethod != DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE && residualMethod != DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2) {
- return DR_FALSE; // Unknown or unsupported residual coding method.
+ return DRFLAC_FALSE; // Unknown or unsupported residual coding method.
}
// Ignore the first values.
pDecodedSamples += order;
- uint8_t partitionOrder;
+ drflac_uint8 partitionOrder;
if (!drflac__read_uint8(bs, 4, &partitionOrder)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
- uint32_t samplesInPartition = (blockSize / (1 << partitionOrder)) - order;
- uint32_t partitionsRemaining = (1 << partitionOrder);
- for (;;)
- {
- uint8_t riceParam = 0;
+ drflac_uint32 samplesInPartition = (blockSize / (1 << partitionOrder)) - order;
+ drflac_uint32 partitionsRemaining = (1 << partitionOrder);
+ for (;;) {
+ drflac_uint8 riceParam = 0;
if (residualMethod == DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE) {
if (!drflac__read_uint8(bs, 4, &riceParam)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
if (riceParam == 16) {
riceParam = 0xFF;
}
} else if (residualMethod == DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2) {
if (!drflac__read_uint8(bs, 5, &riceParam)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
if (riceParam == 32) {
riceParam = 0xFF;
@@ -1739,23 +2424,17 @@ static dr_bool32 drflac__decode_samples_with_residual(drflac_bs* bs, uint32_t bi
}
if (riceParam != 0xFF) {
- if (bitsPerSample > 16) {
- if (!drflac__decode_samples_with_residual__rice_64(bs, samplesInPartition, riceParam, order, shift, coefficients, pDecodedSamples)) {
- return DR_FALSE;
- }
- } else {
- if (!drflac__decode_samples_with_residual__rice_32(bs, samplesInPartition, riceParam, order, shift, coefficients, pDecodedSamples)) {
- return DR_FALSE;
- }
+ if (!drflac__decode_samples_with_residual__rice(bs, bitsPerSample, samplesInPartition, riceParam, order, shift, coefficients, pDecodedSamples)) {
+ return DRFLAC_FALSE;
}
} else {
unsigned char unencodedBitsPerSample = 0;
if (!drflac__read_uint8(bs, 5, &unencodedBitsPerSample)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
if (!drflac__decode_samples_with_residual__unencoded(bs, bitsPerSample, samplesInPartition, unencodedBitsPerSample, order, shift, coefficients, pDecodedSamples)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
}
@@ -1770,46 +2449,46 @@ static dr_bool32 drflac__decode_samples_with_residual(drflac_bs* bs, uint32_t bi
samplesInPartition = blockSize / (1 << partitionOrder);
}
- return DR_TRUE;
+ return DRFLAC_TRUE;
}
// Reads and seeks past the residual for the sub-frame the decoder is currently sitting on. This function should be called
// when the decoder is sitting at the very start of the RESIDUAL block. The first residuals will be set to 0. The
// and parameters are used to determine how many residual values need to be decoded.
-static dr_bool32 drflac__read_and_seek_residual(drflac_bs* bs, uint32_t blockSize, uint32_t order)
+static drflac_bool32 drflac__read_and_seek_residual(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 order)
{
- assert(bs != NULL);
- assert(blockSize != 0);
+ drflac_assert(bs != NULL);
+ drflac_assert(blockSize != 0);
- uint8_t residualMethod;
+ drflac_uint8 residualMethod;
if (!drflac__read_uint8(bs, 2, &residualMethod)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
if (residualMethod != DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE && residualMethod != DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2) {
- return DR_FALSE; // Unknown or unsupported residual coding method.
+ return DRFLAC_FALSE; // Unknown or unsupported residual coding method.
}
- uint8_t partitionOrder;
+ drflac_uint8 partitionOrder;
if (!drflac__read_uint8(bs, 4, &partitionOrder)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
- uint32_t samplesInPartition = (blockSize / (1 << partitionOrder)) - order;
- uint32_t partitionsRemaining = (1 << partitionOrder);
+ drflac_uint32 samplesInPartition = (blockSize / (1 << partitionOrder)) - order;
+ drflac_uint32 partitionsRemaining = (1 << partitionOrder);
for (;;)
{
- uint8_t riceParam = 0;
+ drflac_uint8 riceParam = 0;
if (residualMethod == DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE) {
if (!drflac__read_uint8(bs, 4, &riceParam)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
if (riceParam == 16) {
riceParam = 0xFF;
}
} else if (residualMethod == DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2) {
if (!drflac__read_uint8(bs, 5, &riceParam)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
if (riceParam == 32) {
riceParam = 0xFF;
@@ -1818,16 +2497,16 @@ static dr_bool32 drflac__read_and_seek_residual(drflac_bs* bs, uint32_t blockSiz
if (riceParam != 0xFF) {
if (!drflac__read_and_seek_residual__rice(bs, samplesInPartition, riceParam)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
} else {
unsigned char unencodedBitsPerSample = 0;
if (!drflac__read_uint8(bs, 5, &unencodedBitsPerSample)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
if (!drflac__seek_bits(bs, unencodedBitsPerSample * samplesInPartition)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
}
@@ -1840,44 +2519,44 @@ static dr_bool32 drflac__read_and_seek_residual(drflac_bs* bs, uint32_t blockSiz
samplesInPartition = blockSize / (1 << partitionOrder);
}
- return DR_TRUE;
+ return DRFLAC_TRUE;
}
-static dr_bool32 drflac__decode_samples__constant(drflac_bs* bs, uint32_t blockSize, uint32_t bitsPerSample, int32_t* pDecodedSamples)
+static drflac_bool32 drflac__decode_samples__constant(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 bitsPerSample, drflac_int32* pDecodedSamples)
{
// Only a single sample needs to be decoded here.
- int32_t sample;
+ drflac_int32 sample;
if (!drflac__read_int32(bs, bitsPerSample, &sample)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
// We don't really need to expand this, but it does simplify the process of reading samples. If this becomes a performance issue (unlikely)
// we'll want to look at a more efficient way.
- for (uint32_t i = 0; i < blockSize; ++i) {
+ for (drflac_uint32 i = 0; i < blockSize; ++i) {
pDecodedSamples[i] = sample;
}
- return DR_TRUE;
+ return DRFLAC_TRUE;
}
-static dr_bool32 drflac__decode_samples__verbatim(drflac_bs* bs, uint32_t blockSize, uint32_t bitsPerSample, int32_t* pDecodedSamples)
+static drflac_bool32 drflac__decode_samples__verbatim(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 bitsPerSample, drflac_int32* pDecodedSamples)
{
- for (uint32_t i = 0; i < blockSize; ++i) {
- int32_t sample;
+ for (drflac_uint32 i = 0; i < blockSize; ++i) {
+ drflac_int32 sample;
if (!drflac__read_int32(bs, bitsPerSample, &sample)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
pDecodedSamples[i] = sample;
}
- return DR_TRUE;
+ return DRFLAC_TRUE;
}
-static dr_bool32 drflac__decode_samples__fixed(drflac_bs* bs, uint32_t blockSize, uint32_t bitsPerSample, uint8_t lpcOrder, int32_t* pDecodedSamples)
+static drflac_bool32 drflac__decode_samples__fixed(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 bitsPerSample, drflac_uint8 lpcOrder, drflac_int32* pDecodedSamples)
{
- short lpcCoefficientsTable[5][4] = {
+ drflac_int32 lpcCoefficientsTable[5][4] = {
{0, 0, 0, 0},
{1, 0, 0, 0},
{2, -1, 0, 0},
@@ -1886,10 +2565,10 @@ static dr_bool32 drflac__decode_samples__fixed(drflac_bs* bs, uint32_t blockSize
};
// Warm up samples and coefficients.
- for (uint32_t i = 0; i < lpcOrder; ++i) {
- int32_t sample;
+ for (drflac_uint32 i = 0; i < lpcOrder; ++i) {
+ drflac_int32 sample;
if (!drflac__read_int32(bs, bitsPerSample, &sample)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
pDecodedSamples[i] = sample;
@@ -1897,195 +2576,224 @@ static dr_bool32 drflac__decode_samples__fixed(drflac_bs* bs, uint32_t blockSize
if (!drflac__decode_samples_with_residual(bs, bitsPerSample, blockSize, lpcOrder, 0, lpcCoefficientsTable[lpcOrder], pDecodedSamples)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
- return DR_TRUE;
+ return DRFLAC_TRUE;
}
-static dr_bool32 drflac__decode_samples__lpc(drflac_bs* bs, uint32_t blockSize, uint32_t bitsPerSample, uint8_t lpcOrder, int32_t* pDecodedSamples)
+static drflac_bool32 drflac__decode_samples__lpc(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 bitsPerSample, drflac_uint8 lpcOrder, drflac_int32* pDecodedSamples)
{
+ drflac_uint8 i;
+
// Warm up samples.
- for (uint8_t i = 0; i < lpcOrder; ++i) {
- int32_t sample;
+ for (i = 0; i < lpcOrder; ++i) {
+ drflac_int32 sample;
if (!drflac__read_int32(bs, bitsPerSample, &sample)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
pDecodedSamples[i] = sample;
}
- uint8_t lpcPrecision;
+ drflac_uint8 lpcPrecision;
if (!drflac__read_uint8(bs, 4, &lpcPrecision)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
if (lpcPrecision == 15) {
- return DR_FALSE; // Invalid.
+ return DRFLAC_FALSE; // Invalid.
}
lpcPrecision += 1;
- int8_t lpcShift;
+ drflac_int8 lpcShift;
if (!drflac__read_int8(bs, 5, &lpcShift)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
- int16_t coefficients[32];
- for (uint8_t i = 0; i < lpcOrder; ++i) {
- if (!drflac__read_int16(bs, lpcPrecision, coefficients + i)) {
- return DR_FALSE;
+ drflac_int32 coefficients[32];
+ for (i = 0; i < lpcOrder; ++i) {
+ if (!drflac__read_int32(bs, lpcPrecision, coefficients + i)) {
+ return DRFLAC_FALSE;
}
}
if (!drflac__decode_samples_with_residual(bs, bitsPerSample, blockSize, lpcOrder, lpcShift, coefficients, pDecodedSamples)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
- return DR_TRUE;
+ return DRFLAC_TRUE;
}
-static dr_bool32 drflac__read_next_frame_header(drflac_bs* bs, uint8_t streaminfoBitsPerSample, drflac_frame_header* header)
+static drflac_bool32 drflac__read_next_frame_header(drflac_bs* bs, drflac_uint8 streaminfoBitsPerSample, drflac_frame_header* header)
{
- assert(bs != NULL);
- assert(header != NULL);
+ drflac_assert(bs != NULL);
+ drflac_assert(header != NULL);
- // At the moment the sync code is as a form of basic validation. The CRC is stored, but is unused at the moment. This
- // should probably be handled better in the future.
+ const drflac_uint32 sampleRateTable[12] = {0, 88200, 176400, 192000, 8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000};
+ const drflac_uint8 bitsPerSampleTable[8] = {0, 8, 12, (drflac_uint8)-1, 16, 20, 24, (drflac_uint8)-1}; // -1 = reserved.
- const uint32_t sampleRateTable[12] = {0, 88200, 176400, 192000, 8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000};
- const uint8_t bitsPerSampleTable[8] = {0, 8, 12, (uint8_t)-1, 16, 20, 24, (uint8_t)-1}; // -1 = reserved.
-
- uint16_t syncCode = 0;
- if (!drflac__read_uint16(bs, 14, &syncCode)) {
- return DR_FALSE;
- }
-
- if (syncCode != 0x3FFE) {
- // TODO: Try and recover by attempting to seek to and read the next frame?
- return DR_FALSE;
- }
-
- uint8_t reserved;
- if (!drflac__read_uint8(bs, 1, &reserved)) {
- return DR_FALSE;
- }
-
- uint8_t blockingStrategy = 0;
- if (!drflac__read_uint8(bs, 1, &blockingStrategy)) {
- return DR_FALSE;
- }
-
-
-
- uint8_t blockSize = 0;
- if (!drflac__read_uint8(bs, 4, &blockSize)) {
- return DR_FALSE;
- }
-
- uint8_t sampleRate = 0;
- if (!drflac__read_uint8(bs, 4, &sampleRate)) {
- return DR_FALSE;
- }
-
- uint8_t channelAssignment = 0;
- if (!drflac__read_uint8(bs, 4, &channelAssignment)) {
- return DR_FALSE;
- }
-
- uint8_t bitsPerSample = 0;
- if (!drflac__read_uint8(bs, 3, &bitsPerSample)) {
- return DR_FALSE;
- }
-
- if (!drflac__read_uint8(bs, 1, &reserved)) {
- return DR_FALSE;
- }
-
-
- dr_bool32 isVariableBlockSize = blockingStrategy == 1;
- if (isVariableBlockSize) {
- uint64_t sampleNumber;
- if (!drflac__read_utf8_coded_number(bs, &sampleNumber)) {
- return DR_FALSE;
+ // Keep looping until we find a valid sync code.
+ for (;;) {
+ if (!drflac__find_and_seek_to_next_sync_code(bs)) {
+ return DRFLAC_FALSE;
}
- header->frameNumber = 0;
- header->sampleNumber = sampleNumber;
- } else {
- uint64_t frameNumber = 0;
- if (!drflac__read_utf8_coded_number(bs, &frameNumber)) {
- return DR_FALSE;
+
+ drflac_uint8 crc8 = 0xCE; // 0xCE = drflac_crc8(0, 0x3FFE, 14);
+
+ drflac_uint8 reserved = 0;
+ if (!drflac__read_uint8(bs, 1, &reserved)) {
+ return DRFLAC_FALSE;
}
- header->frameNumber = (uint32_t)frameNumber; // <-- Safe cast.
- header->sampleNumber = 0;
+ crc8 = drflac_crc8(crc8, reserved, 1);
+
+
+ drflac_uint8 blockingStrategy = 0;
+ if (!drflac__read_uint8(bs, 1, &blockingStrategy)) {
+ return DRFLAC_FALSE;
+ }
+ crc8 = drflac_crc8(crc8, blockingStrategy, 1);
+
+
+ drflac_uint8 blockSize = 0;
+ if (!drflac__read_uint8(bs, 4, &blockSize)) {
+ return DRFLAC_FALSE;
+ }
+ crc8 = drflac_crc8(crc8, blockSize, 4);
+
+
+ drflac_uint8 sampleRate = 0;
+ if (!drflac__read_uint8(bs, 4, &sampleRate)) {
+ return DRFLAC_FALSE;
+ }
+ crc8 = drflac_crc8(crc8, sampleRate, 4);
+
+
+ drflac_uint8 channelAssignment = 0;
+ if (!drflac__read_uint8(bs, 4, &channelAssignment)) {
+ return DRFLAC_FALSE;
+ }
+ crc8 = drflac_crc8(crc8, channelAssignment, 4);
+
+
+ drflac_uint8 bitsPerSample = 0;
+ if (!drflac__read_uint8(bs, 3, &bitsPerSample)) {
+ return DRFLAC_FALSE;
+ }
+ crc8 = drflac_crc8(crc8, bitsPerSample, 3);
+
+
+ if (!drflac__read_uint8(bs, 1, &reserved)) {
+ return DRFLAC_FALSE;
+ }
+ crc8 = drflac_crc8(crc8, reserved, 1);
+
+
+ drflac_bool32 isVariableBlockSize = blockingStrategy == 1;
+ if (isVariableBlockSize) {
+ drflac_uint64 sampleNumber;
+ drflac_result result = drflac__read_utf8_coded_number(bs, &sampleNumber, &crc8);
+ if (result != DRFLAC_SUCCESS) {
+ if (result == DRFLAC_END_OF_STREAM) {
+ return DRFLAC_FALSE;
+ } else {
+ continue;
+ }
+ }
+ header->frameNumber = 0;
+ header->sampleNumber = sampleNumber;
+ } else {
+ drflac_uint64 frameNumber = 0;
+ drflac_result result = drflac__read_utf8_coded_number(bs, &frameNumber, &crc8);
+ if (result != DRFLAC_SUCCESS) {
+ if (result == DRFLAC_END_OF_STREAM) {
+ return DRFLAC_FALSE;
+ } else {
+ continue;
+ }
+ }
+ header->frameNumber = (drflac_uint32)frameNumber; // <-- Safe cast.
+ header->sampleNumber = 0;
+ }
+
+
+ if (blockSize == 1) {
+ header->blockSize = 192;
+ } else if (blockSize >= 2 && blockSize <= 5) {
+ header->blockSize = 576 * (1 << (blockSize - 2));
+ } else if (blockSize == 6) {
+ if (!drflac__read_uint16(bs, 8, &header->blockSize)) {
+ return DRFLAC_FALSE;
+ }
+ crc8 = drflac_crc8(crc8, header->blockSize, 8);
+ header->blockSize += 1;
+ } else if (blockSize == 7) {
+ if (!drflac__read_uint16(bs, 16, &header->blockSize)) {
+ return DRFLAC_FALSE;
+ }
+ crc8 = drflac_crc8(crc8, header->blockSize, 16);
+ header->blockSize += 1;
+ } else {
+ header->blockSize = 256 * (1 << (blockSize - 8));
+ }
+
+
+ if (sampleRate <= 11) {
+ header->sampleRate = sampleRateTable[sampleRate];
+ } else if (sampleRate == 12) {
+ if (!drflac__read_uint32(bs, 8, &header->sampleRate)) {
+ return DRFLAC_FALSE;
+ }
+ crc8 = drflac_crc8(crc8, header->sampleRate, 8);
+ header->sampleRate *= 1000;
+ } else if (sampleRate == 13) {
+ if (!drflac__read_uint32(bs, 16, &header->sampleRate)) {
+ return DRFLAC_FALSE;
+ }
+ crc8 = drflac_crc8(crc8, header->sampleRate, 16);
+ } else if (sampleRate == 14) {
+ if (!drflac__read_uint32(bs, 16, &header->sampleRate)) {
+ return DRFLAC_FALSE;
+ }
+ crc8 = drflac_crc8(crc8, header->sampleRate, 16);
+ header->sampleRate *= 10;
+ } else {
+ continue; // Invalid. Assume an invalid block.
+ }
+
+
+ header->channelAssignment = channelAssignment;
+
+ header->bitsPerSample = bitsPerSampleTable[bitsPerSample];
+ if (header->bitsPerSample == 0) {
+ header->bitsPerSample = streaminfoBitsPerSample;
+ }
+
+ if (!drflac__read_uint8(bs, 8, &header->crc8)) {
+ return DRFLAC_FALSE;
+ }
+
+ #ifndef DR_FLAC_NO_CRC
+ if (header->crc8 != crc8) {
+ continue; // CRC mismatch. Loop back to the top and find the next sync code.
+ }
+ #endif
+ return DRFLAC_TRUE;
}
-
-
- if (blockSize == 1) {
- header->blockSize = 192;
- } else if (blockSize >= 2 && blockSize <= 5) {
- header->blockSize = 576 * (1 << (blockSize - 2));
- } else if (blockSize == 6) {
- if (!drflac__read_uint16(bs, 8, &header->blockSize)) {
- return DR_FALSE;
- }
- header->blockSize += 1;
- } else if (blockSize == 7) {
- if (!drflac__read_uint16(bs, 16, &header->blockSize)) {
- return DR_FALSE;
- }
- header->blockSize += 1;
- } else {
- header->blockSize = 256 * (1 << (blockSize - 8));
- }
-
-
- if (sampleRate <= 11) {
- header->sampleRate = sampleRateTable[sampleRate];
- } else if (sampleRate == 12) {
- if (!drflac__read_uint32(bs, 8, &header->sampleRate)) {
- return DR_FALSE;
- }
- header->sampleRate *= 1000;
- } else if (sampleRate == 13) {
- if (!drflac__read_uint32(bs, 16, &header->sampleRate)) {
- return DR_FALSE;
- }
- } else if (sampleRate == 14) {
- if (!drflac__read_uint32(bs, 16, &header->sampleRate)) {
- return DR_FALSE;
- }
- header->sampleRate *= 10;
- } else {
- return DR_FALSE; // Invalid.
- }
-
-
- header->channelAssignment = channelAssignment;
-
- header->bitsPerSample = bitsPerSampleTable[bitsPerSample];
- if (header->bitsPerSample == 0) {
- header->bitsPerSample = streaminfoBitsPerSample;
- }
-
- if (drflac__read_uint8(bs, 8, &header->crc8) != 1) {
- return DR_FALSE;
- }
-
- return DR_TRUE;
}
-static dr_bool32 drflac__read_subframe_header(drflac_bs* bs, drflac_subframe* pSubframe)
+static drflac_bool32 drflac__read_subframe_header(drflac_bs* bs, drflac_subframe* pSubframe)
{
- uint8_t header;
+ drflac_uint8 header;
if (!drflac__read_uint8(bs, 8, &header)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
// First bit should always be 0.
if ((header & 0x80) != 0) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
int type = (header & 0x7E) >> 1;
@@ -2110,7 +2818,7 @@ static dr_bool32 drflac__read_subframe_header(drflac_bs* bs, drflac_subframe* pS
}
if (pSubframe->subframeType == DRFLAC_SUBFRAME_RESERVED) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
// Wasted bits per sample.
@@ -2118,22 +2826,22 @@ static dr_bool32 drflac__read_subframe_header(drflac_bs* bs, drflac_subframe* pS
if ((header & 0x01) == 1) {
unsigned int wastedBitsPerSample;
if (!drflac__seek_past_next_set_bit(bs, &wastedBitsPerSample)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
pSubframe->wastedBitsPerSample = (unsigned char)wastedBitsPerSample + 1;
}
- return DR_TRUE;
+ return DRFLAC_TRUE;
}
-static dr_bool32 drflac__decode_subframe(drflac_bs* bs, drflac_frame* frame, int subframeIndex, int32_t* pDecodedSamplesOut)
+static drflac_bool32 drflac__decode_subframe(drflac_bs* bs, drflac_frame* frame, int subframeIndex, drflac_int32* pDecodedSamplesOut)
{
- assert(bs != NULL);
- assert(frame != NULL);
+ drflac_assert(bs != NULL);
+ drflac_assert(frame != NULL);
drflac_subframe* pSubframe = frame->subframes + subframeIndex;
if (!drflac__read_subframe_header(bs, pSubframe)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
// Side channels require an extra bit per sample. Took a while to figure that one out...
@@ -2170,20 +2878,20 @@ static dr_bool32 drflac__decode_subframe(drflac_bs* bs, drflac_frame* frame, int
drflac__decode_samples__lpc(bs, frame->header.blockSize, pSubframe->bitsPerSample, pSubframe->lpcOrder, pSubframe->pDecodedSamples);
} break;
- default: return DR_FALSE;
+ default: return DRFLAC_FALSE;
}
- return DR_TRUE;
+ return DRFLAC_TRUE;
}
-static dr_bool32 drflac__seek_subframe(drflac_bs* bs, drflac_frame* frame, int subframeIndex)
+static drflac_bool32 drflac__seek_subframe(drflac_bs* bs, drflac_frame* frame, int subframeIndex)
{
- assert(bs != NULL);
- assert(frame != NULL);
+ drflac_assert(bs != NULL);
+ drflac_assert(frame != NULL);
drflac_subframe* pSubframe = frame->subframes + subframeIndex;
if (!drflac__read_subframe_header(bs, pSubframe)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
// Side channels require an extra bit per sample. Took a while to figure that one out...
@@ -2197,14 +2905,13 @@ static dr_bool32 drflac__seek_subframe(drflac_bs* bs, drflac_frame* frame, int s
// Need to handle wasted bits per sample.
pSubframe->bitsPerSample -= pSubframe->wastedBitsPerSample;
pSubframe->pDecodedSamples = NULL;
- //pSubframe->pDecodedSamples = pFlac->pDecodedSamples + (pFlac->currentFrame.header.blockSize * subframeIndex);
switch (pSubframe->subframeType)
{
case DRFLAC_SUBFRAME_CONSTANT:
{
if (!drflac__seek_bits(bs, pSubframe->bitsPerSample)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
} break;
@@ -2212,7 +2919,7 @@ static dr_bool32 drflac__seek_subframe(drflac_bs* bs, drflac_frame* frame, int s
{
unsigned int bitsToSeek = frame->header.blockSize * pSubframe->bitsPerSample;
if (!drflac__seek_bits(bs, bitsToSeek)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
} break;
@@ -2220,11 +2927,11 @@ static dr_bool32 drflac__seek_subframe(drflac_bs* bs, drflac_frame* frame, int s
{
unsigned int bitsToSeek = pSubframe->lpcOrder * pSubframe->bitsPerSample;
if (!drflac__seek_bits(bs, bitsToSeek)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
if (!drflac__read_and_seek_residual(bs, frame->header.blockSize, pSubframe->lpcOrder)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
} break;
@@ -2232,217 +2939,253 @@ static dr_bool32 drflac__seek_subframe(drflac_bs* bs, drflac_frame* frame, int s
{
unsigned int bitsToSeek = pSubframe->lpcOrder * pSubframe->bitsPerSample;
if (!drflac__seek_bits(bs, bitsToSeek)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
unsigned char lpcPrecision;
if (!drflac__read_uint8(bs, 4, &lpcPrecision)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
if (lpcPrecision == 15) {
- return DR_FALSE; // Invalid.
+ return DRFLAC_FALSE; // Invalid.
}
lpcPrecision += 1;
bitsToSeek = (pSubframe->lpcOrder * lpcPrecision) + 5; // +5 for shift.
if (!drflac__seek_bits(bs, bitsToSeek)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
if (!drflac__read_and_seek_residual(bs, frame->header.blockSize, pSubframe->lpcOrder)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
} break;
- default: return DR_FALSE;
+ default: return DRFLAC_FALSE;
}
- return DR_TRUE;
+ return DRFLAC_TRUE;
}
-static DRFLAC_INLINE uint8_t drflac__get_channel_count_from_channel_assignment(int8_t channelAssignment)
+static DRFLAC_INLINE drflac_uint8 drflac__get_channel_count_from_channel_assignment(drflac_int8 channelAssignment)
{
- assert(channelAssignment <= 10);
+ drflac_assert(channelAssignment <= 10);
- uint8_t lookup[] = {1, 2, 3, 4, 5, 6, 7, 8, 2, 2, 2};
+ drflac_uint8 lookup[] = {1, 2, 3, 4, 5, 6, 7, 8, 2, 2, 2};
return lookup[channelAssignment];
}
-static dr_bool32 drflac__decode_frame(drflac* pFlac)
+static drflac_result drflac__decode_frame(drflac* pFlac)
{
// This function should be called while the stream is sitting on the first byte after the frame header.
- memset(pFlac->currentFrame.subframes, 0, sizeof(pFlac->currentFrame.subframes));
+ drflac_zero_memory(pFlac->currentFrame.subframes, sizeof(pFlac->currentFrame.subframes));
int channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFrame.header.channelAssignment);
- for (int i = 0; i < channelCount; ++i)
- {
+ for (int i = 0; i < channelCount; ++i) {
if (!drflac__decode_subframe(&pFlac->bs, &pFlac->currentFrame, i, pFlac->pDecodedSamples + (pFlac->currentFrame.header.blockSize * i))) {
- return DR_FALSE;
+ return DRFLAC_ERROR;
}
}
- // At the end of the frame sits the padding and CRC. We don't use these so we can just seek past.
- if (!drflac__seek_bits(&pFlac->bs, (DRFLAC_CACHE_L1_BITS_REMAINING(&pFlac->bs) & 7) + 16)) {
- return DR_FALSE;
+ drflac_uint8 paddingSizeInBits = DRFLAC_CACHE_L1_BITS_REMAINING(&pFlac->bs) & 7;
+ if (paddingSizeInBits > 0) {
+ drflac_uint8 padding = 0;
+ if (!drflac__read_uint8(&pFlac->bs, paddingSizeInBits, &padding)) {
+ return DRFLAC_END_OF_STREAM;
+ }
}
+#ifndef DR_FLAC_NO_CRC
+ drflac_uint16 actualCRC16 = drflac__flush_crc16(&pFlac->bs);
+#endif
+ drflac_uint16 desiredCRC16;
+ if (!drflac__read_uint16(&pFlac->bs, 16, &desiredCRC16)) {
+ return DRFLAC_END_OF_STREAM;
+ }
+
+#ifndef DR_FLAC_NO_CRC
+ if (actualCRC16 != desiredCRC16) {
+ return DRFLAC_CRC_MISMATCH; // CRC mismatch.
+ }
+#endif
pFlac->currentFrame.samplesRemaining = pFlac->currentFrame.header.blockSize * channelCount;
- return DR_TRUE;
+ return DRFLAC_SUCCESS;
}
-static dr_bool32 drflac__seek_frame(drflac* pFlac)
+static drflac_result drflac__seek_frame(drflac* pFlac)
{
int channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFrame.header.channelAssignment);
- for (int i = 0; i < channelCount; ++i)
- {
+ for (int i = 0; i < channelCount; ++i) {
if (!drflac__seek_subframe(&pFlac->bs, &pFlac->currentFrame, i)) {
- return DR_FALSE;
+ return DRFLAC_ERROR;
}
}
- // Padding and CRC.
- return drflac__seek_bits(&pFlac->bs, (DRFLAC_CACHE_L1_BITS_REMAINING(&pFlac->bs) & 7) + 16);
-}
-
-static dr_bool32 drflac__read_and_decode_next_frame(drflac* pFlac)
-{
- assert(pFlac != NULL);
-
- if (!drflac__read_next_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFrame.header)) {
- return DR_FALSE;
+ // Padding.
+ if (!drflac__seek_bits(&pFlac->bs, DRFLAC_CACHE_L1_BITS_REMAINING(&pFlac->bs) & 7)) {
+ return DRFLAC_ERROR;
}
- return drflac__decode_frame(pFlac);
+ // CRC.
+#ifndef DR_FLAC_NO_CRC
+ drflac_uint16 actualCRC16 = drflac__flush_crc16(&pFlac->bs);
+#endif
+ drflac_uint16 desiredCRC16;
+ if (!drflac__read_uint16(&pFlac->bs, 16, &desiredCRC16)) {
+ return DRFLAC_END_OF_STREAM;
+ }
+
+#ifndef DR_FLAC_NO_CRC
+ if (actualCRC16 != desiredCRC16) {
+ return DRFLAC_CRC_MISMATCH; // CRC mismatch.
+ }
+#endif
+
+ return DRFLAC_SUCCESS;
+}
+
+static drflac_bool32 drflac__read_and_decode_next_frame(drflac* pFlac)
+{
+ drflac_assert(pFlac != NULL);
+
+ for (;;) {
+ if (!drflac__read_next_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFrame.header)) {
+ return DRFLAC_FALSE;
+ }
+
+ drflac_result result = drflac__decode_frame(pFlac);
+ if (result != DRFLAC_SUCCESS) {
+ if (result == DRFLAC_CRC_MISMATCH) {
+ continue; // CRC mismatch. Skip to the next frame.
+ } else {
+ return DRFLAC_FALSE;
+ }
+ }
+
+ return DRFLAC_TRUE;
+ }
}
-static void drflac__get_current_frame_sample_range(drflac* pFlac, uint64_t* pFirstSampleInFrameOut, uint64_t* pLastSampleInFrameOut)
+static void drflac__get_current_frame_sample_range(drflac* pFlac, drflac_uint64* pFirstSampleInFrameOut, drflac_uint64* pLastSampleInFrameOut)
{
- assert(pFlac != NULL);
+ drflac_assert(pFlac != NULL);
unsigned int channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFrame.header.channelAssignment);
- uint64_t firstSampleInFrame = pFlac->currentFrame.header.sampleNumber;
+ drflac_uint64 firstSampleInFrame = pFlac->currentFrame.header.sampleNumber;
if (firstSampleInFrame == 0) {
firstSampleInFrame = pFlac->currentFrame.header.frameNumber * pFlac->maxBlockSize*channelCount;
}
- uint64_t lastSampleInFrame = firstSampleInFrame + (pFlac->currentFrame.header.blockSize*channelCount);
+ drflac_uint64 lastSampleInFrame = firstSampleInFrame + (pFlac->currentFrame.header.blockSize*channelCount);
if (lastSampleInFrame > 0) {
lastSampleInFrame -= 1; // Needs to be zero based.
}
-
- if (pFirstSampleInFrameOut) {
- *pFirstSampleInFrameOut = firstSampleInFrame;
- }
- if (pLastSampleInFrameOut) {
- *pLastSampleInFrameOut = lastSampleInFrame;
- }
+ if (pFirstSampleInFrameOut) *pFirstSampleInFrameOut = firstSampleInFrame;
+ if (pLastSampleInFrameOut) *pLastSampleInFrameOut = lastSampleInFrame;
}
-static dr_bool32 drflac__seek_to_first_frame(drflac* pFlac)
+static drflac_bool32 drflac__seek_to_first_frame(drflac* pFlac)
{
- assert(pFlac != NULL);
+ drflac_assert(pFlac != NULL);
- dr_bool32 result = drflac__seek_to_byte(&pFlac->bs, pFlac->firstFramePos);
+ drflac_bool32 result = drflac__seek_to_byte(&pFlac->bs, pFlac->firstFramePos);
- memset(&pFlac->currentFrame, 0, sizeof(pFlac->currentFrame));
+ drflac_zero_memory(&pFlac->currentFrame, sizeof(pFlac->currentFrame));
return result;
}
-static DRFLAC_INLINE dr_bool32 drflac__seek_to_next_frame(drflac* pFlac)
+static DRFLAC_INLINE drflac_result drflac__seek_to_next_frame(drflac* pFlac)
{
// This function should only ever be called while the decoder is sitting on the first byte past the FRAME_HEADER section.
- assert(pFlac != NULL);
+ drflac_assert(pFlac != NULL);
return drflac__seek_frame(pFlac);
}
-static dr_bool32 drflac__seek_to_frame_containing_sample(drflac* pFlac, uint64_t sampleIndex)
+static drflac_bool32 drflac__seek_to_sample__brute_force(drflac* pFlac, drflac_uint64 sampleIndex)
{
- assert(pFlac != NULL);
-
+ // We need to find the frame that contains the sample. To do this, we iterate over each frame and inspect it's header. If based on the
+ // header we can determine that the frame contains the sample, we do a full decode of that frame.
if (!drflac__seek_to_first_frame(pFlac)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
- uint64_t firstSampleInFrame = 0;
- uint64_t lastSampleInFrame = 0;
- for (;;)
- {
- // We need to read the frame's header in order to determine the range of samples it contains.
+ drflac_uint64 runningSampleCount = 0;
+ for (;;) {
if (!drflac__read_next_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFrame.header)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
+ drflac_uint64 firstSampleInFrame = 0;
+ drflac_uint64 lastSampleInFrame = 0;
drflac__get_current_frame_sample_range(pFlac, &firstSampleInFrame, &lastSampleInFrame);
- if (sampleIndex >= firstSampleInFrame && sampleIndex <= lastSampleInFrame) {
- break; // The sample is in this frame.
- }
- if (!drflac__seek_to_next_frame(pFlac)) {
- return DR_FALSE;
+ drflac_uint64 sampleCountInThisFrame = (lastSampleInFrame - firstSampleInFrame) + 1;
+ if (sampleIndex < (runningSampleCount + sampleCountInThisFrame)) {
+ // The sample should be in this frame. We need to fully decode it, however if it's an invalid frame (a CRC mismatch), we need to pretend
+ // it never existed and keep iterating.
+ drflac_result result = drflac__decode_frame(pFlac);
+ if (result == DRFLAC_SUCCESS) {
+ // The frame is valid. We just need to skip over some samples to ensure it's sample-exact.
+ drflac_uint64 samplesToDecode = (size_t)(sampleIndex - runningSampleCount); // <-- Safe cast because the maximum number of samples in a frame is 65535.
+ if (samplesToDecode == 0) {
+ return DRFLAC_TRUE;
+ }
+ return drflac_read_s32(pFlac, samplesToDecode, NULL) != 0; // <-- If this fails, something bad has happened (it should never fail).
+ } else {
+ if (result == DRFLAC_CRC_MISMATCH) {
+ continue; // CRC mismatch. Pretend this frame never existed.
+ } else {
+ return DRFLAC_FALSE;
+ }
+ }
+ } else {
+ // It's not in this frame. We need to seek past the frame, but check if there was a CRC mismatch. If so, we pretend this
+ // frame never existed and leave the running sample count untouched.
+ drflac_result result = drflac__seek_to_next_frame(pFlac);
+ if (result == DRFLAC_SUCCESS) {
+ runningSampleCount += sampleCountInThisFrame;
+ } else {
+ if (result == DRFLAC_CRC_MISMATCH) {
+ continue; // CRC mismatch. Pretend this frame never existed.
+ } else {
+ return DRFLAC_FALSE;
+ }
+ }
}
}
-
- // If we get here we should be right at the start of the frame containing the sample.
- return DR_TRUE;
-}
-
-static dr_bool32 drflac__seek_to_sample__brute_force(drflac* pFlac, uint64_t sampleIndex)
-{
- if (!drflac__seek_to_frame_containing_sample(pFlac, sampleIndex)) {
- return DR_FALSE;
- }
-
- // At this point we should be sitting on the first byte of the frame containing the sample. We need to decode every sample up to (but
- // not including) the sample we're seeking to.
- uint64_t firstSampleInFrame = 0;
- drflac__get_current_frame_sample_range(pFlac, &firstSampleInFrame, NULL);
-
- assert(firstSampleInFrame <= sampleIndex);
- size_t samplesToDecode = (size_t)(sampleIndex - firstSampleInFrame); // <-- Safe cast because the maximum number of samples in a frame is 65535.
- if (samplesToDecode == 0) {
- return DR_TRUE;
- }
-
- // At this point we are just sitting on the byte after the frame header. We need to decode the frame before reading anything from it.
- if (!drflac__decode_frame(pFlac)) {
- return DR_FALSE;
- }
-
- return drflac_read_s32(pFlac, samplesToDecode, NULL) != 0;
}
-static dr_bool32 drflac__seek_to_sample__seek_table(drflac* pFlac, uint64_t sampleIndex)
+static drflac_bool32 drflac__seek_to_sample__seek_table(drflac* pFlac, drflac_uint64 sampleIndex)
{
- assert(pFlac != NULL);
+ drflac_assert(pFlac != NULL);
if (pFlac->seektablePos == 0) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
if (!drflac__seek_to_byte(&pFlac->bs, pFlac->seektablePos)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
// The number of seek points is derived from the size of the SEEKTABLE block.
- uint32_t seekpointCount = pFlac->seektableSize / 18; // 18 = the size of each seek point.
+ drflac_uint32 seekpointCount = pFlac->seektableSize / 18; // 18 = the size of each seek point.
if (seekpointCount == 0) {
- return DR_FALSE; // Would this ever happen?
+ return DRFLAC_FALSE; // Would this ever happen?
}
drflac_seekpoint closestSeekpoint = {0, 0, 0};
- uint32_t seekpointsRemaining = seekpointCount;
- while (seekpointsRemaining > 0)
- {
+ drflac_uint32 seekpointsRemaining = seekpointCount;
+ while (seekpointsRemaining > 0) {
drflac_seekpoint seekpoint;
if (!drflac__read_uint64(&pFlac->bs, 64, &seekpoint.firstSample)) {
break;
@@ -2454,7 +3197,9 @@ static dr_bool32 drflac__seek_to_sample__seek_table(drflac* pFlac, uint64_t samp
break;
}
- if (seekpoint.firstSample * pFlac->channels > sampleIndex) {
+ // Note that the seekpoint sample is based on a single channel. The input sample (sampleIndex) is based on interleaving, thus
+ // we need to multiple the seekpoint's sample by the channel count.
+ if (seekpoint.firstSample*pFlac->channels > sampleIndex) {
break;
}
@@ -2465,53 +3210,68 @@ static dr_bool32 drflac__seek_to_sample__seek_table(drflac* pFlac, uint64_t samp
// At this point we should have found the seekpoint closest to our sample. We need to seek to it using basically the same
// technique as we use with the brute force method.
if (!drflac__seek_to_byte(&pFlac->bs, pFlac->firstFramePos + closestSeekpoint.frameOffset)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
-
- uint64_t firstSampleInFrame = 0;
- uint64_t lastSampleInFrame = 0;
- for (;;)
- {
- // We need to read the frame's header in order to determine the range of samples it contains.
+ drflac_uint64 runningSampleCount = closestSeekpoint.firstSample*pFlac->channels;
+ for (;;) {
if (!drflac__read_next_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFrame.header)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
+ drflac_uint64 firstSampleInFrame = 0;
+ drflac_uint64 lastSampleInFrame = 0;
drflac__get_current_frame_sample_range(pFlac, &firstSampleInFrame, &lastSampleInFrame);
- if (sampleIndex >= firstSampleInFrame && sampleIndex <= lastSampleInFrame) {
- break; // The sample is in this frame.
- }
- if (!drflac__seek_to_next_frame(pFlac)) {
- return DR_FALSE;
+ drflac_uint64 sampleCountInThisFrame = (lastSampleInFrame - firstSampleInFrame) + 1;
+ if (sampleIndex < (runningSampleCount + sampleCountInThisFrame)) {
+ // The sample should be in this frame. We need to fully decode it, however if it's an invalid frame (a CRC mismatch), we need to pretend
+ // it never existed and keep iterating.
+ drflac_result result = drflac__decode_frame(pFlac);
+ if (result == DRFLAC_SUCCESS) {
+ // The frame is valid. We just need to skip over some samples to ensure it's sample-exact.
+ drflac_uint64 samplesToDecode = (size_t)(sampleIndex - runningSampleCount); // <-- Safe cast because the maximum number of samples in a frame is 65535.
+ if (samplesToDecode == 0) {
+ return DRFLAC_TRUE;
+ }
+ return drflac_read_s32(pFlac, samplesToDecode, NULL) != 0; // <-- If this fails, something bad has happened (it should never fail).
+ } else {
+ if (result == DRFLAC_CRC_MISMATCH) {
+ continue; // CRC mismatch. Pretend this frame never existed.
+ } else {
+ return DRFLAC_FALSE;
+ }
+ }
+ } else {
+ // It's not in this frame. We need to seek past the frame, but check if there was a CRC mismatch. If so, we pretend this
+ // frame never existed and leave the running sample count untouched.
+ drflac_result result = drflac__seek_to_next_frame(pFlac);
+ if (result == DRFLAC_SUCCESS) {
+ runningSampleCount += sampleCountInThisFrame;
+ } else {
+ if (result == DRFLAC_CRC_MISMATCH) {
+ continue; // CRC mismatch. Pretend this frame never existed.
+ } else {
+ return DRFLAC_FALSE;
+ }
+ }
}
}
-
- assert(firstSampleInFrame <= sampleIndex);
-
- // At this point we are just sitting on the byte after the frame header. We need to decode the frame before reading anything from it.
- if (!drflac__decode_frame(pFlac)) {
- return DR_FALSE;
- }
-
- size_t samplesToDecode = (size_t)(sampleIndex - firstSampleInFrame); // <-- Safe cast because the maximum number of samples in a frame is 65535.
- return drflac_read_s32(pFlac, samplesToDecode, NULL) == samplesToDecode;
}
#ifndef DR_FLAC_NO_OGG
typedef struct
{
- uint8_t capturePattern[4]; // Should be "OggS"
- uint8_t structureVersion; // Always 0.
- uint8_t headerType;
- uint64_t granulePosition;
- uint32_t serialNumber;
- uint32_t sequenceNumber;
- uint32_t checksum;
- uint8_t segmentCount;
- uint8_t segmentTable[255];
+ drflac_uint8 capturePattern[4]; // Should be "OggS"
+ drflac_uint8 structureVersion; // Always 0.
+ drflac_uint8 headerType;
+ drflac_uint64 granulePosition;
+ drflac_uint32 serialNumber;
+ drflac_uint32 sequenceNumber;
+ drflac_uint32 checksum;
+ drflac_uint8 segmentCount;
+ drflac_uint8 segmentTable[255];
} drflac_ogg_page_header;
#endif
@@ -2520,25 +3280,28 @@ typedef struct
drflac_read_proc onRead;
drflac_seek_proc onSeek;
drflac_meta_proc onMeta;
+ drflac_container container;
void* pUserData;
void* pUserDataMD;
- drflac_container container;
- uint32_t sampleRate;
- uint8_t channels;
- uint8_t bitsPerSample;
- uint64_t totalSampleCount;
- uint16_t maxBlockSize;
- uint64_t runningFilePos;
- dr_bool32 hasMetadataBlocks;
+ drflac_uint32 sampleRate;
+ drflac_uint8 channels;
+ drflac_uint8 bitsPerSample;
+ drflac_uint64 totalSampleCount;
+ drflac_uint16 maxBlockSize;
+ drflac_uint64 runningFilePos;
+ drflac_bool32 hasStreamInfoBlock;
+ drflac_bool32 hasMetadataBlocks;
+ drflac_bs bs; // <-- A bit streamer is required for loading data during initialization.
+ drflac_frame_header firstFrameHeader; // <-- The header of the first frame that was read during relaxed initalization. Only set if there is no STREAMINFO block.
#ifndef DR_FLAC_NO_OGG
- uint32_t oggSerial;
- uint64_t oggFirstBytePos;
+ drflac_uint32 oggSerial;
+ drflac_uint64 oggFirstBytePos;
drflac_ogg_page_header oggBosHeader;
#endif
} drflac_init_info;
-static DRFLAC_INLINE void drflac__decode_block_header(uint32_t blockHeader, uint8_t* isLastBlock, uint8_t* blockType, uint32_t* blockSize)
+static DRFLAC_INLINE void drflac__decode_block_header(drflac_uint32 blockHeader, drflac_uint8* isLastBlock, drflac_uint8* blockType, drflac_uint32* blockSize)
{
blockHeader = drflac__be2host_32(blockHeader);
*isLastBlock = (blockHeader & (0x01 << 31)) >> 31;
@@ -2546,41 +3309,41 @@ static DRFLAC_INLINE void drflac__decode_block_header(uint32_t blockHeader, uint
*blockSize = (blockHeader & 0xFFFFFF);
}
-static DRFLAC_INLINE dr_bool32 drflac__read_and_decode_block_header(drflac_read_proc onRead, void* pUserData, uint8_t* isLastBlock, uint8_t* blockType, uint32_t* blockSize)
+static DRFLAC_INLINE drflac_bool32 drflac__read_and_decode_block_header(drflac_read_proc onRead, void* pUserData, drflac_uint8* isLastBlock, drflac_uint8* blockType, drflac_uint32* blockSize)
{
- uint32_t blockHeader;
+ drflac_uint32 blockHeader;
if (onRead(pUserData, &blockHeader, 4) != 4) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
drflac__decode_block_header(blockHeader, isLastBlock, blockType, blockSize);
- return DR_TRUE;
+ return DRFLAC_TRUE;
}
-dr_bool32 drflac__read_streaminfo(drflac_read_proc onRead, void* pUserData, drflac_streaminfo* pStreamInfo)
+drflac_bool32 drflac__read_streaminfo(drflac_read_proc onRead, void* pUserData, drflac_streaminfo* pStreamInfo)
{
// min/max block size.
- uint32_t blockSizes;
+ drflac_uint32 blockSizes;
if (onRead(pUserData, &blockSizes, 4) != 4) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
// min/max frame size.
- uint64_t frameSizes = 0;
+ drflac_uint64 frameSizes = 0;
if (onRead(pUserData, &frameSizes, 6) != 6) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
// Sample rate, channels, bits per sample and total sample count.
- uint64_t importantProps;
+ drflac_uint64 importantProps;
if (onRead(pUserData, &importantProps, 8) != 8) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
// MD5
- uint8_t md5[16];
+ drflac_uint8 md5[16];
if (onRead(pUserData, md5, sizeof(md5)) != sizeof(md5)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
blockSizes = drflac__be2host_32(blockSizes);
@@ -2589,34 +3352,33 @@ dr_bool32 drflac__read_streaminfo(drflac_read_proc onRead, void* pUserData, drfl
pStreamInfo->minBlockSize = (blockSizes & 0xFFFF0000) >> 16;
pStreamInfo->maxBlockSize = blockSizes & 0x0000FFFF;
- pStreamInfo->minFrameSize = (uint32_t)((frameSizes & 0xFFFFFF0000000000ULL) >> 40ULL);
- pStreamInfo->maxFrameSize = (uint32_t)((frameSizes & 0x000000FFFFFF0000ULL) >> 16ULL);
- pStreamInfo->sampleRate = (uint32_t)((importantProps & 0xFFFFF00000000000ULL) >> 44ULL);
- pStreamInfo->channels = (uint8_t )((importantProps & 0x00000E0000000000ULL) >> 41ULL) + 1;
- pStreamInfo->bitsPerSample = (uint8_t )((importantProps & 0x000001F000000000ULL) >> 36ULL) + 1;
- pStreamInfo->totalSampleCount = (importantProps & 0x0000000FFFFFFFFFULL) * pStreamInfo->channels;
- memcpy(pStreamInfo->md5, md5, sizeof(md5));
+ pStreamInfo->minFrameSize = (drflac_uint32)((frameSizes & (drflac_uint64)0xFFFFFF0000000000) >> 40);
+ pStreamInfo->maxFrameSize = (drflac_uint32)((frameSizes & (drflac_uint64)0x000000FFFFFF0000) >> 16);
+ pStreamInfo->sampleRate = (drflac_uint32)((importantProps & (drflac_uint64)0xFFFFF00000000000) >> 44);
+ pStreamInfo->channels = (drflac_uint8 )((importantProps & (drflac_uint64)0x00000E0000000000) >> 41) + 1;
+ pStreamInfo->bitsPerSample = (drflac_uint8 )((importantProps & (drflac_uint64)0x000001F000000000) >> 36) + 1;
+ pStreamInfo->totalSampleCount = (importantProps & (drflac_uint64)0x0000000FFFFFFFFF) * pStreamInfo->channels;
+ drflac_copy_memory(pStreamInfo->md5, md5, sizeof(md5));
- return DR_TRUE;
+ return DRFLAC_TRUE;
}
-dr_bool32 drflac__read_and_decode_metadata(drflac* pFlac)
+drflac_bool32 drflac__read_and_decode_metadata(drflac* pFlac)
{
- assert(pFlac != NULL);
+ drflac_assert(pFlac != NULL);
// We want to keep track of the byte position in the stream of the seektable. At the time of calling this function we know that
// we'll be sitting on byte 42.
- uint64_t runningFilePos = 42;
- uint64_t seektablePos = 0;
- uint32_t seektableSize = 0;
+ drflac_uint64 runningFilePos = 42;
+ drflac_uint64 seektablePos = 0;
+ drflac_uint32 seektableSize = 0;
- for (;;)
- {
- uint8_t isLastBlock = 0;
- uint8_t blockType;
- uint32_t blockSize;
+ for (;;) {
+ drflac_uint8 isLastBlock = 0;
+ drflac_uint8 blockType;
+ drflac_uint32 blockSize;
if (!drflac__read_and_decode_block_header(pFlac->bs.onRead, pFlac->bs.pUserData, &isLastBlock, &blockType, &blockSize)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
runningFilePos += 4;
@@ -2631,24 +3393,24 @@ dr_bool32 drflac__read_and_decode_metadata(drflac* pFlac)
case DRFLAC_METADATA_BLOCK_TYPE_APPLICATION:
{
if (pFlac->onMeta) {
- void* pRawData = malloc(blockSize);
+ void* pRawData = DRFLAC_MALLOC(blockSize);
if (pRawData == NULL) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
if (pFlac->bs.onRead(pFlac->bs.pUserData, pRawData, blockSize) != blockSize) {
- free(pRawData);
- return DR_FALSE;
+ DRFLAC_FREE(pRawData);
+ return DRFLAC_FALSE;
}
metadata.pRawData = pRawData;
metadata.rawDataSize = blockSize;
- metadata.data.application.id = drflac__be2host_32(*(uint32_t*)pRawData);
- metadata.data.application.pData = (const void*)((uint8_t*)pRawData + sizeof(uint32_t));
- metadata.data.application.dataSize = blockSize - sizeof(uint32_t);
+ metadata.data.application.id = drflac__be2host_32(*(drflac_uint32*)pRawData);
+ metadata.data.application.pData = (const void*)((drflac_uint8*)pRawData + sizeof(drflac_uint32));
+ metadata.data.application.dataSize = blockSize - sizeof(drflac_uint32);
pFlac->onMeta(pFlac->pUserDataMD, &metadata);
- free(pRawData);
+ DRFLAC_FREE(pRawData);
}
} break;
@@ -2658,14 +3420,14 @@ dr_bool32 drflac__read_and_decode_metadata(drflac* pFlac)
seektableSize = blockSize;
if (pFlac->onMeta) {
- void* pRawData = malloc(blockSize);
+ void* pRawData = DRFLAC_MALLOC(blockSize);
if (pRawData == NULL) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
if (pFlac->bs.onRead(pFlac->bs.pUserData, pRawData, blockSize) != blockSize) {
- free(pRawData);
- return DR_FALSE;
+ DRFLAC_FREE(pRawData);
+ return DRFLAC_FALSE;
}
metadata.pRawData = pRawData;
@@ -2674,7 +3436,7 @@ dr_bool32 drflac__read_and_decode_metadata(drflac* pFlac)
metadata.data.seektable.pSeekpoints = (const drflac_seekpoint*)pRawData;
// Endian swap.
- for (uint32_t iSeekpoint = 0; iSeekpoint < metadata.data.seektable.seekpointCount; ++iSeekpoint) {
+ for (drflac_uint32 iSeekpoint = 0; iSeekpoint < metadata.data.seektable.seekpointCount; ++iSeekpoint) {
drflac_seekpoint* pSeekpoint = (drflac_seekpoint*)pRawData + iSeekpoint;
pSeekpoint->firstSample = drflac__be2host_64(pSeekpoint->firstSample);
pSeekpoint->frameOffset = drflac__be2host_64(pSeekpoint->frameOffset);
@@ -2683,96 +3445,96 @@ dr_bool32 drflac__read_and_decode_metadata(drflac* pFlac)
pFlac->onMeta(pFlac->pUserDataMD, &metadata);
- free(pRawData);
+ DRFLAC_FREE(pRawData);
}
} break;
case DRFLAC_METADATA_BLOCK_TYPE_VORBIS_COMMENT:
{
if (pFlac->onMeta) {
- void* pRawData = malloc(blockSize);
+ void* pRawData = DRFLAC_MALLOC(blockSize);
if (pRawData == NULL) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
if (pFlac->bs.onRead(pFlac->bs.pUserData, pRawData, blockSize) != blockSize) {
- free(pRawData);
- return DR_FALSE;
+ DRFLAC_FREE(pRawData);
+ return DRFLAC_FALSE;
}
metadata.pRawData = pRawData;
metadata.rawDataSize = blockSize;
const char* pRunningData = (const char*)pRawData;
- metadata.data.vorbis_comment.vendorLength = drflac__le2host_32(*(uint32_t*)pRunningData); pRunningData += 4;
- metadata.data.vorbis_comment.vendor = pRunningData; pRunningData += metadata.data.vorbis_comment.vendorLength;
- metadata.data.vorbis_comment.commentCount = drflac__le2host_32(*(uint32_t*)pRunningData); pRunningData += 4;
+ metadata.data.vorbis_comment.vendorLength = drflac__le2host_32(*(drflac_uint32*)pRunningData); pRunningData += 4;
+ metadata.data.vorbis_comment.vendor = pRunningData; pRunningData += metadata.data.vorbis_comment.vendorLength;
+ metadata.data.vorbis_comment.commentCount = drflac__le2host_32(*(drflac_uint32*)pRunningData); pRunningData += 4;
metadata.data.vorbis_comment.comments = pRunningData;
pFlac->onMeta(pFlac->pUserDataMD, &metadata);
- free(pRawData);
+ DRFLAC_FREE(pRawData);
}
} break;
case DRFLAC_METADATA_BLOCK_TYPE_CUESHEET:
{
if (pFlac->onMeta) {
- void* pRawData = malloc(blockSize);
+ void* pRawData = DRFLAC_MALLOC(blockSize);
if (pRawData == NULL) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
if (pFlac->bs.onRead(pFlac->bs.pUserData, pRawData, blockSize) != blockSize) {
- free(pRawData);
- return DR_FALSE;
+ DRFLAC_FREE(pRawData);
+ return DRFLAC_FALSE;
}
metadata.pRawData = pRawData;
metadata.rawDataSize = blockSize;
const char* pRunningData = (const char*)pRawData;
- memcpy(metadata.data.cuesheet.catalog, pRunningData, 128); pRunningData += 128;
- metadata.data.cuesheet.leadInSampleCount = drflac__be2host_64(*(uint64_t*)pRunningData); pRunningData += 4;
- metadata.data.cuesheet.isCD = ((pRunningData[0] & 0x80) >> 7) != 0; pRunningData += 259;
- metadata.data.cuesheet.trackCount = pRunningData[0]; pRunningData += 1;
- metadata.data.cuesheet.pTrackData = (const uint8_t*)pRunningData;
+ drflac_copy_memory(metadata.data.cuesheet.catalog, pRunningData, 128); pRunningData += 128;
+ metadata.data.cuesheet.leadInSampleCount = drflac__be2host_64(*(drflac_uint64*)pRunningData); pRunningData += 4;
+ metadata.data.cuesheet.isCD = ((pRunningData[0] & 0x80) >> 7) != 0; pRunningData += 259;
+ metadata.data.cuesheet.trackCount = pRunningData[0]; pRunningData += 1;
+ metadata.data.cuesheet.pTrackData = (const drflac_uint8*)pRunningData;
pFlac->onMeta(pFlac->pUserDataMD, &metadata);
- free(pRawData);
+ DRFLAC_FREE(pRawData);
}
} break;
case DRFLAC_METADATA_BLOCK_TYPE_PICTURE:
{
if (pFlac->onMeta) {
- void* pRawData = malloc(blockSize);
+ void* pRawData = DRFLAC_MALLOC(blockSize);
if (pRawData == NULL) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
if (pFlac->bs.onRead(pFlac->bs.pUserData, pRawData, blockSize) != blockSize) {
- free(pRawData);
- return DR_FALSE;
+ DRFLAC_FREE(pRawData);
+ return DRFLAC_FALSE;
}
metadata.pRawData = pRawData;
metadata.rawDataSize = blockSize;
const char* pRunningData = (const char*)pRawData;
- metadata.data.picture.type = drflac__be2host_32(*(uint32_t*)pRunningData); pRunningData += 4;
- metadata.data.picture.mimeLength = drflac__be2host_32(*(uint32_t*)pRunningData); pRunningData += 4;
- metadata.data.picture.mime = pRunningData; pRunningData += metadata.data.picture.mimeLength;
- metadata.data.picture.descriptionLength = drflac__be2host_32(*(uint32_t*)pRunningData); pRunningData += 4;
+ metadata.data.picture.type = drflac__be2host_32(*(drflac_uint32*)pRunningData); pRunningData += 4;
+ metadata.data.picture.mimeLength = drflac__be2host_32(*(drflac_uint32*)pRunningData); pRunningData += 4;
+ metadata.data.picture.mime = pRunningData; pRunningData += metadata.data.picture.mimeLength;
+ metadata.data.picture.descriptionLength = drflac__be2host_32(*(drflac_uint32*)pRunningData); pRunningData += 4;
metadata.data.picture.description = pRunningData;
- metadata.data.picture.width = drflac__be2host_32(*(uint32_t*)pRunningData); pRunningData += 4;
- metadata.data.picture.height = drflac__be2host_32(*(uint32_t*)pRunningData); pRunningData += 4;
- metadata.data.picture.colorDepth = drflac__be2host_32(*(uint32_t*)pRunningData); pRunningData += 4;
- metadata.data.picture.indexColorCount = drflac__be2host_32(*(uint32_t*)pRunningData); pRunningData += 4;
- metadata.data.picture.pictureDataSize = drflac__be2host_32(*(uint32_t*)pRunningData); pRunningData += 4;
- metadata.data.picture.pPictureData = (const uint8_t*)pRunningData;
+ metadata.data.picture.width = drflac__be2host_32(*(drflac_uint32*)pRunningData); pRunningData += 4;
+ metadata.data.picture.height = drflac__be2host_32(*(drflac_uint32*)pRunningData); pRunningData += 4;
+ metadata.data.picture.colorDepth = drflac__be2host_32(*(drflac_uint32*)pRunningData); pRunningData += 4;
+ metadata.data.picture.indexColorCount = drflac__be2host_32(*(drflac_uint32*)pRunningData); pRunningData += 4;
+ metadata.data.picture.pictureDataSize = drflac__be2host_32(*(drflac_uint32*)pRunningData); pRunningData += 4;
+ metadata.data.picture.pPictureData = (const drflac_uint8*)pRunningData;
pFlac->onMeta(pFlac->pUserDataMD, &metadata);
- free(pRawData);
+ DRFLAC_FREE(pRawData);
}
} break;
@@ -2781,12 +3543,12 @@ dr_bool32 drflac__read_and_decode_metadata(drflac* pFlac)
if (pFlac->onMeta) {
metadata.data.padding.unused = 0;
- // Padding doesn't have anything meaningful in it, so just skip over it.
+ // Padding doesn't have anything meaningful in it, so just skip over it, but make sure the caller is aware of it by firing the callback.
if (!pFlac->bs.onSeek(pFlac->bs.pUserData, blockSize, drflac_seek_origin_current)) {
- return DR_FALSE;
+ isLastBlock = DRFLAC_TRUE; // An error occured while seeking. Attempt to recover by treating this as the last block which will in turn terminate the loop.
+ } else {
+ pFlac->onMeta(pFlac->pUserDataMD, &metadata);
}
-
- pFlac->onMeta(pFlac->pUserDataMD, &metadata);
}
} break;
@@ -2795,7 +3557,7 @@ dr_bool32 drflac__read_and_decode_metadata(drflac* pFlac)
// Invalid chunk. Just skip over this one.
if (pFlac->onMeta) {
if (!pFlac->bs.onSeek(pFlac->bs.pUserData, blockSize, drflac_seek_origin_current)) {
- return DR_FALSE;
+ isLastBlock = DRFLAC_TRUE; // An error occured while seeking. Attempt to recover by treating this as the last block which will in turn terminate the loop.
}
}
}
@@ -2805,29 +3567,29 @@ dr_bool32 drflac__read_and_decode_metadata(drflac* pFlac)
// It's an unknown chunk, but not necessarily invalid. There's a chance more metadata blocks might be defined later on, so we
// can at the very least report the chunk to the application and let it look at the raw data.
if (pFlac->onMeta) {
- void* pRawData = malloc(blockSize);
+ void* pRawData = DRFLAC_MALLOC(blockSize);
if (pRawData == NULL) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
if (pFlac->bs.onRead(pFlac->bs.pUserData, pRawData, blockSize) != blockSize) {
- free(pRawData);
- return DR_FALSE;
+ DRFLAC_FREE(pRawData);
+ return DRFLAC_FALSE;
}
metadata.pRawData = pRawData;
metadata.rawDataSize = blockSize;
pFlac->onMeta(pFlac->pUserDataMD, &metadata);
- free(pRawData);
+ DRFLAC_FREE(pRawData);
}
} break;
}
// If we're not handling metadata, just skip over the block. If we are, it will have been handled earlier in the switch statement above.
- if (pFlac->onMeta == NULL) {
+ if (pFlac->onMeta == NULL && blockSize > 0) {
if (!pFlac->bs.onSeek(pFlac->bs.pUserData, blockSize, drflac_seek_origin_current)) {
- return DR_FALSE;
+ isLastBlock = DRFLAC_TRUE;
}
}
@@ -2841,10 +3603,10 @@ dr_bool32 drflac__read_and_decode_metadata(drflac* pFlac)
pFlac->seektableSize = seektableSize;
pFlac->firstFramePos = runningFilePos;
- return DR_TRUE;
+ return DRFLAC_TRUE;
}
-dr_bool32 drflac__init_private__native(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD)
+drflac_bool32 drflac__init_private__native(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD, drflac_bool32 relaxed)
{
(void)onSeek;
@@ -2853,56 +3615,193 @@ dr_bool32 drflac__init_private__native(drflac_init_info* pInit, drflac_read_proc
pInit->container = drflac_container_native;
// The first metadata block should be the STREAMINFO block.
- uint8_t isLastBlock;
- uint8_t blockType;
- uint32_t blockSize;
+ drflac_uint8 isLastBlock;
+ drflac_uint8 blockType;
+ drflac_uint32 blockSize;
if (!drflac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
if (blockType != DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO || blockSize != 34) {
- return DR_FALSE; // Invalid block type. First block must be the STREAMINFO block.
+ if (!relaxed) {
+ // We're opening in strict mode and the first block is not the STREAMINFO block. Error.
+ return DRFLAC_FALSE;
+ } else {
+ // Relaxed mode. To open from here we need to just find the first frame and set the sample rate, etc. to whatever is defined
+ // for that frame.
+ pInit->hasStreamInfoBlock = DRFLAC_FALSE;
+ pInit->hasMetadataBlocks = DRFLAC_FALSE;
+
+ if (!drflac__read_next_frame_header(&pInit->bs, 0, &pInit->firstFrameHeader)) {
+ return DRFLAC_FALSE; // Couldn't find a frame.
+ }
+
+ if (pInit->firstFrameHeader.bitsPerSample == 0) {
+ return DRFLAC_FALSE; // Failed to initialize because the first frame depends on the STREAMINFO block, which does not exist.
+ }
+
+ pInit->sampleRate = pInit->firstFrameHeader.sampleRate;
+ pInit->channels = drflac__get_channel_count_from_channel_assignment(pInit->firstFrameHeader.channelAssignment);
+ pInit->bitsPerSample = pInit->firstFrameHeader.bitsPerSample;
+ pInit->maxBlockSize = 65535; // <-- See notes here: https://xiph.org/flac/format.html#metadata_block_streaminfo
+ return DRFLAC_TRUE;
+ }
+ } else {
+ drflac_streaminfo streaminfo;
+ if (!drflac__read_streaminfo(onRead, pUserData, &streaminfo)) {
+ return DRFLAC_FALSE;
+ }
+
+ pInit->hasStreamInfoBlock = DRFLAC_TRUE;
+ pInit->sampleRate = streaminfo.sampleRate;
+ pInit->channels = streaminfo.channels;
+ pInit->bitsPerSample = streaminfo.bitsPerSample;
+ pInit->totalSampleCount = streaminfo.totalSampleCount;
+ pInit->maxBlockSize = streaminfo.maxBlockSize; // Don't care about the min block size - only the max (used for determining the size of the memory allocation).
+ pInit->hasMetadataBlocks = !isLastBlock;
+
+ if (onMeta) {
+ drflac_metadata metadata;
+ metadata.type = DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO;
+ metadata.pRawData = NULL;
+ metadata.rawDataSize = 0;
+ metadata.data.streaminfo = streaminfo;
+ onMeta(pUserDataMD, &metadata);
+ }
+
+ return DRFLAC_TRUE;
}
-
-
- drflac_streaminfo streaminfo;
- if (!drflac__read_streaminfo(onRead, pUserData, &streaminfo)) {
- return DR_FALSE;
- }
-
- pInit->sampleRate = streaminfo.sampleRate;
- pInit->channels = streaminfo.channels;
- pInit->bitsPerSample = streaminfo.bitsPerSample;
- pInit->totalSampleCount = streaminfo.totalSampleCount;
- pInit->maxBlockSize = streaminfo.maxBlockSize; // Don't care about the min block size - only the max (used for determining the size of the memory allocation).
-
- if (onMeta) {
- drflac_metadata metadata;
- metadata.type = DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO;
- metadata.pRawData = NULL;
- metadata.rawDataSize = 0;
- metadata.data.streaminfo = streaminfo;
- onMeta(pUserDataMD, &metadata);
- }
-
- pInit->hasMetadataBlocks = !isLastBlock;
- return DR_TRUE;
}
#ifndef DR_FLAC_NO_OGG
-static DRFLAC_INLINE dr_bool32 drflac_ogg__is_capture_pattern(uint8_t pattern[4])
+#define DRFLAC_OGG_MAX_PAGE_SIZE 65307
+#define DRFLAC_OGG_CAPTURE_PATTERN_CRC32 1605413199 // CRC-32 of "OggS".
+
+typedef enum
+{
+ drflac_ogg_recover_on_crc_mismatch,
+ drflac_ogg_fail_on_crc_mismatch
+} drflac_ogg_crc_mismatch_recovery;
+
+
+static drflac_uint32 drflac__crc32_table[] = {
+ 0x00000000L, 0x04C11DB7L, 0x09823B6EL, 0x0D4326D9L,
+ 0x130476DCL, 0x17C56B6BL, 0x1A864DB2L, 0x1E475005L,
+ 0x2608EDB8L, 0x22C9F00FL, 0x2F8AD6D6L, 0x2B4BCB61L,
+ 0x350C9B64L, 0x31CD86D3L, 0x3C8EA00AL, 0x384FBDBDL,
+ 0x4C11DB70L, 0x48D0C6C7L, 0x4593E01EL, 0x4152FDA9L,
+ 0x5F15ADACL, 0x5BD4B01BL, 0x569796C2L, 0x52568B75L,
+ 0x6A1936C8L, 0x6ED82B7FL, 0x639B0DA6L, 0x675A1011L,
+ 0x791D4014L, 0x7DDC5DA3L, 0x709F7B7AL, 0x745E66CDL,
+ 0x9823B6E0L, 0x9CE2AB57L, 0x91A18D8EL, 0x95609039L,
+ 0x8B27C03CL, 0x8FE6DD8BL, 0x82A5FB52L, 0x8664E6E5L,
+ 0xBE2B5B58L, 0xBAEA46EFL, 0xB7A96036L, 0xB3687D81L,
+ 0xAD2F2D84L, 0xA9EE3033L, 0xA4AD16EAL, 0xA06C0B5DL,
+ 0xD4326D90L, 0xD0F37027L, 0xDDB056FEL, 0xD9714B49L,
+ 0xC7361B4CL, 0xC3F706FBL, 0xCEB42022L, 0xCA753D95L,
+ 0xF23A8028L, 0xF6FB9D9FL, 0xFBB8BB46L, 0xFF79A6F1L,
+ 0xE13EF6F4L, 0xE5FFEB43L, 0xE8BCCD9AL, 0xEC7DD02DL,
+ 0x34867077L, 0x30476DC0L, 0x3D044B19L, 0x39C556AEL,
+ 0x278206ABL, 0x23431B1CL, 0x2E003DC5L, 0x2AC12072L,
+ 0x128E9DCFL, 0x164F8078L, 0x1B0CA6A1L, 0x1FCDBB16L,
+ 0x018AEB13L, 0x054BF6A4L, 0x0808D07DL, 0x0CC9CDCAL,
+ 0x7897AB07L, 0x7C56B6B0L, 0x71159069L, 0x75D48DDEL,
+ 0x6B93DDDBL, 0x6F52C06CL, 0x6211E6B5L, 0x66D0FB02L,
+ 0x5E9F46BFL, 0x5A5E5B08L, 0x571D7DD1L, 0x53DC6066L,
+ 0x4D9B3063L, 0x495A2DD4L, 0x44190B0DL, 0x40D816BAL,
+ 0xACA5C697L, 0xA864DB20L, 0xA527FDF9L, 0xA1E6E04EL,
+ 0xBFA1B04BL, 0xBB60ADFCL, 0xB6238B25L, 0xB2E29692L,
+ 0x8AAD2B2FL, 0x8E6C3698L, 0x832F1041L, 0x87EE0DF6L,
+ 0x99A95DF3L, 0x9D684044L, 0x902B669DL, 0x94EA7B2AL,
+ 0xE0B41DE7L, 0xE4750050L, 0xE9362689L, 0xEDF73B3EL,
+ 0xF3B06B3BL, 0xF771768CL, 0xFA325055L, 0xFEF34DE2L,
+ 0xC6BCF05FL, 0xC27DEDE8L, 0xCF3ECB31L, 0xCBFFD686L,
+ 0xD5B88683L, 0xD1799B34L, 0xDC3ABDEDL, 0xD8FBA05AL,
+ 0x690CE0EEL, 0x6DCDFD59L, 0x608EDB80L, 0x644FC637L,
+ 0x7A089632L, 0x7EC98B85L, 0x738AAD5CL, 0x774BB0EBL,
+ 0x4F040D56L, 0x4BC510E1L, 0x46863638L, 0x42472B8FL,
+ 0x5C007B8AL, 0x58C1663DL, 0x558240E4L, 0x51435D53L,
+ 0x251D3B9EL, 0x21DC2629L, 0x2C9F00F0L, 0x285E1D47L,
+ 0x36194D42L, 0x32D850F5L, 0x3F9B762CL, 0x3B5A6B9BL,
+ 0x0315D626L, 0x07D4CB91L, 0x0A97ED48L, 0x0E56F0FFL,
+ 0x1011A0FAL, 0x14D0BD4DL, 0x19939B94L, 0x1D528623L,
+ 0xF12F560EL, 0xF5EE4BB9L, 0xF8AD6D60L, 0xFC6C70D7L,
+ 0xE22B20D2L, 0xE6EA3D65L, 0xEBA91BBCL, 0xEF68060BL,
+ 0xD727BBB6L, 0xD3E6A601L, 0xDEA580D8L, 0xDA649D6FL,
+ 0xC423CD6AL, 0xC0E2D0DDL, 0xCDA1F604L, 0xC960EBB3L,
+ 0xBD3E8D7EL, 0xB9FF90C9L, 0xB4BCB610L, 0xB07DABA7L,
+ 0xAE3AFBA2L, 0xAAFBE615L, 0xA7B8C0CCL, 0xA379DD7BL,
+ 0x9B3660C6L, 0x9FF77D71L, 0x92B45BA8L, 0x9675461FL,
+ 0x8832161AL, 0x8CF30BADL, 0x81B02D74L, 0x857130C3L,
+ 0x5D8A9099L, 0x594B8D2EL, 0x5408ABF7L, 0x50C9B640L,
+ 0x4E8EE645L, 0x4A4FFBF2L, 0x470CDD2BL, 0x43CDC09CL,
+ 0x7B827D21L, 0x7F436096L, 0x7200464FL, 0x76C15BF8L,
+ 0x68860BFDL, 0x6C47164AL, 0x61043093L, 0x65C52D24L,
+ 0x119B4BE9L, 0x155A565EL, 0x18197087L, 0x1CD86D30L,
+ 0x029F3D35L, 0x065E2082L, 0x0B1D065BL, 0x0FDC1BECL,
+ 0x3793A651L, 0x3352BBE6L, 0x3E119D3FL, 0x3AD08088L,
+ 0x2497D08DL, 0x2056CD3AL, 0x2D15EBE3L, 0x29D4F654L,
+ 0xC5A92679L, 0xC1683BCEL, 0xCC2B1D17L, 0xC8EA00A0L,
+ 0xD6AD50A5L, 0xD26C4D12L, 0xDF2F6BCBL, 0xDBEE767CL,
+ 0xE3A1CBC1L, 0xE760D676L, 0xEA23F0AFL, 0xEEE2ED18L,
+ 0xF0A5BD1DL, 0xF464A0AAL, 0xF9278673L, 0xFDE69BC4L,
+ 0x89B8FD09L, 0x8D79E0BEL, 0x803AC667L, 0x84FBDBD0L,
+ 0x9ABC8BD5L, 0x9E7D9662L, 0x933EB0BBL, 0x97FFAD0CL,
+ 0xAFB010B1L, 0xAB710D06L, 0xA6322BDFL, 0xA2F33668L,
+ 0xBCB4666DL, 0xB8757BDAL, 0xB5365D03L, 0xB1F740B4L
+};
+
+static DRFLAC_INLINE drflac_uint32 drflac_crc32_byte(drflac_uint32 crc32, drflac_uint8 data)
+{
+#ifndef DR_FLAC_NO_CRC
+ return (crc32 << 8) ^ drflac__crc32_table[(drflac_uint8)((crc32 >> 24) & 0xFF) ^ data];
+#else
+ (void)data;
+ return crc32;
+#endif
+}
+
+#if 0
+static DRFLAC_INLINE drflac_uint32 drflac_crc32_uint32(drflac_uint32 crc32, drflac_uint32 data)
+{
+ crc32 = drflac_crc32_byte(crc32, (drflac_uint8)((data >> 24) & 0xFF));
+ crc32 = drflac_crc32_byte(crc32, (drflac_uint8)((data >> 16) & 0xFF));
+ crc32 = drflac_crc32_byte(crc32, (drflac_uint8)((data >> 8) & 0xFF));
+ crc32 = drflac_crc32_byte(crc32, (drflac_uint8)((data >> 0) & 0xFF));
+ return crc32;
+}
+
+static DRFLAC_INLINE drflac_uint32 drflac_crc32_uint64(drflac_uint32 crc32, drflac_uint64 data)
+{
+ crc32 = drflac_crc32_uint32(crc32, (drflac_uint32)((data >> 32) & 0xFFFFFFFF));
+ crc32 = drflac_crc32_uint32(crc32, (drflac_uint32)((data >> 0) & 0xFFFFFFFF));
+ return crc32;
+}
+#endif
+
+static DRFLAC_INLINE drflac_uint32 drflac_crc32_buffer(drflac_uint32 crc32, drflac_uint8* pData, drflac_uint32 dataSize)
+{
+ // This can be optimized.
+ for (drflac_uint32 i = 0; i < dataSize; ++i) {
+ crc32 = drflac_crc32_byte(crc32, pData[i]);
+ }
+ return crc32;
+}
+
+
+static DRFLAC_INLINE drflac_bool32 drflac_ogg__is_capture_pattern(drflac_uint8 pattern[4])
{
return pattern[0] == 'O' && pattern[1] == 'g' && pattern[2] == 'g' && pattern[3] == 'S';
}
-static DRFLAC_INLINE uint32_t drflac_ogg__get_page_header_size(drflac_ogg_page_header* pHeader)
+static DRFLAC_INLINE drflac_uint32 drflac_ogg__get_page_header_size(drflac_ogg_page_header* pHeader)
{
return 27 + pHeader->segmentCount;
}
-static DRFLAC_INLINE uint32_t drflac_ogg__get_page_body_size(drflac_ogg_page_header* pHeader)
+static DRFLAC_INLINE drflac_uint32 drflac_ogg__get_page_body_size(drflac_ogg_page_header* pHeader)
{
- uint32_t pageBodySize = 0;
+ drflac_uint32 pageBodySize = 0;
for (int i = 0; i < pHeader->segmentCount; ++i) {
pageBodySize += pHeader->segmentTable[i];
}
@@ -2910,49 +3809,84 @@ static DRFLAC_INLINE uint32_t drflac_ogg__get_page_body_size(drflac_ogg_page_hea
return pageBodySize;
}
-dr_bool32 drflac_ogg__read_page_header_after_capture_pattern(drflac_read_proc onRead, void* pUserData, drflac_ogg_page_header* pHeader, uint32_t* pHeaderSize)
+drflac_result drflac_ogg__read_page_header_after_capture_pattern(drflac_read_proc onRead, void* pUserData, drflac_ogg_page_header* pHeader, drflac_uint32* pBytesRead, drflac_uint32* pCRC32)
{
- if (onRead(pUserData, &pHeader->structureVersion, 1) != 1 || pHeader->structureVersion != 0) {
- return DR_FALSE; // Unknown structure version. Possibly corrupt stream.
+ drflac_assert(*pCRC32 == DRFLAC_OGG_CAPTURE_PATTERN_CRC32);
+
+ drflac_uint8 data[23];
+ if (onRead(pUserData, data, 23) != 23) {
+ return DRFLAC_END_OF_STREAM;
}
- if (onRead(pUserData, &pHeader->headerType, 1) != 1) {
- return DR_FALSE;
- }
- if (onRead(pUserData, &pHeader->granulePosition, 8) != 8) {
- return DR_FALSE;
- }
- if (onRead(pUserData, &pHeader->serialNumber, 4) != 4) {
- return DR_FALSE;
- }
- if (onRead(pUserData, &pHeader->sequenceNumber, 4) != 4) {
- return DR_FALSE;
- }
- if (onRead(pUserData, &pHeader->checksum, 4) != 4) {
- return DR_FALSE;
- }
- if (onRead(pUserData, &pHeader->segmentCount, 1) != 1 || pHeader->segmentCount == 0) {
- return DR_FALSE; // Should not have a segment count of 0.
- }
- if (onRead(pUserData, &pHeader->segmentTable, pHeader->segmentCount) != pHeader->segmentCount) {
- return DR_FALSE;
+ *pBytesRead += 23;
+
+ pHeader->structureVersion = data[0];
+ pHeader->headerType = data[1];
+ drflac_copy_memory(&pHeader->granulePosition, &data[ 2], 8);
+ drflac_copy_memory(&pHeader->serialNumber, &data[10], 4);
+ drflac_copy_memory(&pHeader->sequenceNumber, &data[14], 4);
+ drflac_copy_memory(&pHeader->checksum, &data[18], 4);
+ pHeader->segmentCount = data[22];
+
+ // Calculate the CRC. Note that for the calculation the checksum part of the page needs to be set to 0.
+ data[18] = 0;
+ data[19] = 0;
+ data[20] = 0;
+ data[21] = 0;
+
+ drflac_uint32 i;
+ for (i = 0; i < 23; ++i) {
+ *pCRC32 = drflac_crc32_byte(*pCRC32, data[i]);
}
- if (pHeaderSize) *pHeaderSize = (27 + pHeader->segmentCount);
- return DR_TRUE;
+
+ if (onRead(pUserData, pHeader->segmentTable, pHeader->segmentCount) != pHeader->segmentCount) {
+ return DRFLAC_END_OF_STREAM;
+ }
+ *pBytesRead += pHeader->segmentCount;
+
+ for (i = 0; i < pHeader->segmentCount; ++i) {
+ *pCRC32 = drflac_crc32_byte(*pCRC32, pHeader->segmentTable[i]);
+ }
+
+ return DRFLAC_SUCCESS;
}
-dr_bool32 drflac_ogg__read_page_header(drflac_read_proc onRead, void* pUserData, drflac_ogg_page_header* pHeader, uint32_t* pHeaderSize)
+drflac_result drflac_ogg__read_page_header(drflac_read_proc onRead, void* pUserData, drflac_ogg_page_header* pHeader, drflac_uint32* pBytesRead, drflac_uint32* pCRC32)
{
- uint8_t id[4];
+ *pBytesRead = 0;
+
+ drflac_uint8 id[4];
if (onRead(pUserData, id, 4) != 4) {
- return DR_FALSE;
+ return DRFLAC_END_OF_STREAM;
}
+ *pBytesRead += 4;
- if (id[0] != 'O' || id[1] != 'g' || id[2] != 'g' || id[3] != 'S') {
- return DR_FALSE;
+ // We need to read byte-by-byte until we find the OggS capture pattern.
+ for (;;) {
+ if (drflac_ogg__is_capture_pattern(id)) {
+ *pCRC32 = DRFLAC_OGG_CAPTURE_PATTERN_CRC32;
+
+ drflac_result result = drflac_ogg__read_page_header_after_capture_pattern(onRead, pUserData, pHeader, pBytesRead, pCRC32);
+ if (result == DRFLAC_SUCCESS) {
+ return DRFLAC_SUCCESS;
+ } else {
+ if (result == DRFLAC_CRC_MISMATCH) {
+ continue;
+ } else {
+ return result;
+ }
+ }
+ } else {
+ // The first 4 bytes did not equal the capture pattern. Read the next byte and try again.
+ id[0] = id[1];
+ id[1] = id[2];
+ id[2] = id[3];
+ if (onRead(pUserData, &id[3], 1) != 1) {
+ return DRFLAC_END_OF_STREAM;
+ }
+ *pBytesRead += 1;
+ }
}
-
- return drflac_ogg__read_page_header_after_capture_pattern(onRead, pUserData, pHeader, pHeaderSize);
}
@@ -2966,12 +3900,14 @@ typedef struct
drflac_read_proc onRead; // The original onRead callback from drflac_open() and family.
drflac_seek_proc onSeek; // The original onSeek callback from drflac_open() and family.
void* pUserData; // The user data passed on onRead and onSeek. This is the user data that was passed on drflac_open() and family.
- uint64_t currentBytePos; // The position of the byte we are sitting on in the physical byte stream. Used for efficient seeking.
- uint64_t firstBytePos; // The position of the first byte in the physical bitstream. Points to the start of the "OggS" identifier of the FLAC bos page.
- uint32_t serialNumber; // The serial number of the FLAC audio pages. This is determined by the initial header page that was read during initialization.
+ drflac_uint64 currentBytePos; // The position of the byte we are sitting on in the physical byte stream. Used for efficient seeking.
+ drflac_uint64 firstBytePos; // The position of the first byte in the physical bitstream. Points to the start of the "OggS" identifier of the FLAC bos page.
+ drflac_uint32 serialNumber; // The serial number of the FLAC audio pages. This is determined by the initial header page that was read during initialization.
drflac_ogg_page_header bosPageHeader; // Used for seeking.
drflac_ogg_page_header currentPageHeader;
- uint32_t bytesRemainingInPage;
+ drflac_uint32 bytesRemainingInPage;
+ drflac_uint32 pageDataSize;
+ drflac_uint8 pageData[DRFLAC_OGG_MAX_PAGE_SIZE];
} drflac_oggbs; // oggbs = Ogg Bitstream
static size_t drflac_oggbs__read_physical(drflac_oggbs* oggbs, void* bufferOut, size_t bytesToRead)
@@ -2982,82 +3918,103 @@ static size_t drflac_oggbs__read_physical(drflac_oggbs* oggbs, void* bufferOut,
return bytesActuallyRead;
}
-static dr_bool32 drflac_oggbs__seek_physical(drflac_oggbs* oggbs, uint64_t offset, drflac_seek_origin origin)
+static drflac_bool32 drflac_oggbs__seek_physical(drflac_oggbs* oggbs, drflac_uint64 offset, drflac_seek_origin origin)
{
- if (origin == drflac_seek_origin_start)
- {
+ if (origin == drflac_seek_origin_start) {
if (offset <= 0x7FFFFFFF) {
if (!oggbs->onSeek(oggbs->pUserData, (int)offset, drflac_seek_origin_start)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
oggbs->currentBytePos = offset;
- return DR_TRUE;
+ return DRFLAC_TRUE;
} else {
if (!oggbs->onSeek(oggbs->pUserData, 0x7FFFFFFF, drflac_seek_origin_start)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
oggbs->currentBytePos = offset;
return drflac_oggbs__seek_physical(oggbs, offset - 0x7FFFFFFF, drflac_seek_origin_current);
}
- }
- else
- {
+ } else {
while (offset > 0x7FFFFFFF) {
if (!oggbs->onSeek(oggbs->pUserData, 0x7FFFFFFF, drflac_seek_origin_current)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
oggbs->currentBytePos += 0x7FFFFFFF;
offset -= 0x7FFFFFFF;
}
if (!oggbs->onSeek(oggbs->pUserData, (int)offset, drflac_seek_origin_current)) { // <-- Safe cast thanks to the loop above.
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
oggbs->currentBytePos += offset;
- return DR_TRUE;
+ return DRFLAC_TRUE;
}
}
-static dr_bool32 drflac_oggbs__goto_next_page(drflac_oggbs* oggbs)
+static drflac_bool32 drflac_oggbs__goto_next_page(drflac_oggbs* oggbs, drflac_ogg_crc_mismatch_recovery recoveryMethod)
{
drflac_ogg_page_header header;
- for (;;)
- {
- uint32_t headerSize;
- if (!drflac_ogg__read_page_header(oggbs->onRead, oggbs->pUserData, &header, &headerSize)) {
- return DR_FALSE;
+ for (;;) {
+ drflac_uint32 crc32 = 0;
+ drflac_uint32 bytesRead;
+ if (drflac_ogg__read_page_header(oggbs->onRead, oggbs->pUserData, &header, &bytesRead, &crc32) != DRFLAC_SUCCESS) {
+ return DRFLAC_FALSE;
}
- oggbs->currentBytePos += headerSize;
+ oggbs->currentBytePos += bytesRead;
-
- uint32_t pageBodySize = drflac_ogg__get_page_body_size(&header);
-
- if (header.serialNumber == oggbs->serialNumber) {
- oggbs->currentPageHeader = header;
- oggbs->bytesRemainingInPage = pageBodySize;
- return DR_TRUE;
+ drflac_uint32 pageBodySize = drflac_ogg__get_page_body_size(&header);
+ if (pageBodySize > DRFLAC_OGG_MAX_PAGE_SIZE) {
+ continue; // Invalid page size. Assume it's corrupted and just move to the next page.
}
- // If we get here it means the page is not a FLAC page - skip it.
- if (pageBodySize > 0 && !drflac_oggbs__seek_physical(oggbs, pageBodySize, drflac_seek_origin_current)) { // <-- Safe cast - maximum size of a page is way below that of an int.
- return DR_FALSE;
+ if (header.serialNumber != oggbs->serialNumber) {
+ // It's not a FLAC page. Skip it.
+ if (pageBodySize > 0 && !drflac_oggbs__seek_physical(oggbs, pageBodySize, drflac_seek_origin_current)) {
+ return DRFLAC_FALSE;
+ }
+ continue;
}
+
+
+ // We need to read the entire page and then do a CRC check on it. If there's a CRC mismatch we need to skip this page.
+ if (drflac_oggbs__read_physical(oggbs, oggbs->pageData, pageBodySize) != pageBodySize) {
+ return DRFLAC_FALSE;
+ }
+ oggbs->pageDataSize = pageBodySize;
+
+#ifndef DR_FLAC_NO_CRC
+ drflac_uint32 actualCRC32 = drflac_crc32_buffer(crc32, oggbs->pageData, oggbs->pageDataSize);
+ if (actualCRC32 != header.checksum) {
+ if (recoveryMethod == drflac_ogg_recover_on_crc_mismatch) {
+ continue; // CRC mismatch. Skip this page.
+ } else {
+ // Even though we are failing on a CRC mismatch, we still want our stream to be in a good state. Therefore we
+ // go to the next valid page to ensure we're in a good state, but return false to let the caller know that the
+ // seek did not fully complete.
+ drflac_oggbs__goto_next_page(oggbs, drflac_ogg_recover_on_crc_mismatch);
+ return DRFLAC_FALSE;
+ }
+ }
+#endif
+
+ oggbs->currentPageHeader = header;
+ oggbs->bytesRemainingInPage = pageBodySize;
+ return DRFLAC_TRUE;
}
}
// Function below is unused at the moment, but I might be re-adding it later.
#if 0
-static uint8_t drflac_oggbs__get_current_segment_index(drflac_oggbs* oggbs, uint8_t* pBytesRemainingInSeg)
+static drflac_uint8 drflac_oggbs__get_current_segment_index(drflac_oggbs* oggbs, drflac_uint8* pBytesRemainingInSeg)
{
- uint32_t bytesConsumedInPage = drflac_ogg__get_page_body_size(&oggbs->currentPageHeader) - oggbs->bytesRemainingInPage;
- uint8_t iSeg = 0;
- uint32_t iByte = 0;
- while (iByte < bytesConsumedInPage)
- {
- uint8_t segmentSize = oggbs->currentPageHeader.segmentTable[iSeg];
+ drflac_uint32 bytesConsumedInPage = drflac_ogg__get_page_body_size(&oggbs->currentPageHeader) - oggbs->bytesRemainingInPage;
+ drflac_uint8 iSeg = 0;
+ drflac_uint32 iByte = 0;
+ while (iByte < bytesConsumedInPage) {
+ drflac_uint8 segmentSize = oggbs->currentPageHeader.segmentTable[iSeg];
if (iByte + segmentSize > bytesConsumedInPage) {
break;
} else {
@@ -3066,26 +4023,25 @@ static uint8_t drflac_oggbs__get_current_segment_index(drflac_oggbs* oggbs, uint
}
}
- *pBytesRemainingInSeg = oggbs->currentPageHeader.segmentTable[iSeg] - (uint8_t)(bytesConsumedInPage - iByte);
+ *pBytesRemainingInSeg = oggbs->currentPageHeader.segmentTable[iSeg] - (drflac_uint8)(bytesConsumedInPage - iByte);
return iSeg;
}
-static dr_bool32 drflac_oggbs__seek_to_next_packet(drflac_oggbs* oggbs)
+static drflac_bool32 drflac_oggbs__seek_to_next_packet(drflac_oggbs* oggbs)
{
// The current packet ends when we get to the segment with a lacing value of < 255 which is not at the end of a page.
- for (;;) // <-- Loop over pages.
- {
- dr_bool32 atEndOfPage = DR_FALSE;
+ for (;;) {
+ drflac_bool32 atEndOfPage = DRFLAC_FALSE;
- uint8_t bytesRemainingInSeg;
- uint8_t iFirstSeg = drflac_oggbs__get_current_segment_index(oggbs, &bytesRemainingInSeg);
+ drflac_uint8 bytesRemainingInSeg;
+ drflac_uint8 iFirstSeg = drflac_oggbs__get_current_segment_index(oggbs, &bytesRemainingInSeg);
- uint32_t bytesToEndOfPacketOrPage = bytesRemainingInSeg;
- for (uint8_t iSeg = iFirstSeg; iSeg < oggbs->currentPageHeader.segmentCount; ++iSeg) {
- uint8_t segmentSize = oggbs->currentPageHeader.segmentTable[iSeg];
+ drflac_uint32 bytesToEndOfPacketOrPage = bytesRemainingInSeg;
+ for (drflac_uint8 iSeg = iFirstSeg; iSeg < oggbs->currentPageHeader.segmentCount; ++iSeg) {
+ drflac_uint8 segmentSize = oggbs->currentPageHeader.segmentTable[iSeg];
if (segmentSize < 255) {
if (iSeg == oggbs->currentPageHeader.segmentCount-1) {
- atEndOfPage = DR_TRUE;
+ atEndOfPage = DRFLAC_TRUE;
}
break;
@@ -3095,32 +4051,29 @@ static dr_bool32 drflac_oggbs__seek_to_next_packet(drflac_oggbs* oggbs)
}
// At this point we will have found either the packet or the end of the page. If were at the end of the page we'll
- // want to load the next page and keep searching for the end of the frame.
+ // want to load the next page and keep searching for the end of the packet.
drflac_oggbs__seek_physical(oggbs, bytesToEndOfPacketOrPage, drflac_seek_origin_current);
oggbs->bytesRemainingInPage -= bytesToEndOfPacketOrPage;
- if (atEndOfPage)
- {
+ if (atEndOfPage) {
// We're potentially at the next packet, but we need to check the next page first to be sure because the packet may
// straddle pages.
if (!drflac_oggbs__goto_next_page(oggbs)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
// If it's a fresh packet it most likely means we're at the next packet.
if ((oggbs->currentPageHeader.headerType & 0x01) == 0) {
- return DR_TRUE;
+ return DRFLAC_TRUE;
}
- }
- else
- {
- // We're at the next frame.
- return DR_TRUE;
+ } else {
+ // We're at the next packet.
+ return DRFLAC_TRUE;
}
}
}
-static dr_bool32 drflac_oggbs__seek_to_next_frame(drflac_oggbs* oggbs)
+static drflac_bool32 drflac_oggbs__seek_to_next_frame(drflac_oggbs* oggbs)
{
// The bitstream should be sitting on the first byte just after the header of the frame.
@@ -3132,76 +4085,67 @@ static dr_bool32 drflac_oggbs__seek_to_next_frame(drflac_oggbs* oggbs)
static size_t drflac__on_read_ogg(void* pUserData, void* bufferOut, size_t bytesToRead)
{
drflac_oggbs* oggbs = (drflac_oggbs*)pUserData;
- assert(oggbs != NULL);
+ drflac_assert(oggbs != NULL);
- uint8_t* pRunningBufferOut = (uint8_t*)bufferOut;
+ drflac_uint8* pRunningBufferOut = (drflac_uint8*)bufferOut;
// Reading is done page-by-page. If we've run out of bytes in the page we need to move to the next one.
size_t bytesRead = 0;
- while (bytesRead < bytesToRead)
- {
+ while (bytesRead < bytesToRead) {
size_t bytesRemainingToRead = bytesToRead - bytesRead;
if (oggbs->bytesRemainingInPage >= bytesRemainingToRead) {
- bytesRead += oggbs->onRead(oggbs->pUserData, pRunningBufferOut, bytesRemainingToRead);
- oggbs->bytesRemainingInPage -= (uint32_t)bytesRemainingToRead;
+ drflac_copy_memory(pRunningBufferOut, oggbs->pageData + (oggbs->pageDataSize - oggbs->bytesRemainingInPage), bytesRemainingToRead);
+ bytesRead += bytesRemainingToRead;
+ oggbs->bytesRemainingInPage -= (drflac_uint32)bytesRemainingToRead;
break;
}
// If we get here it means some of the requested data is contained in the next pages.
if (oggbs->bytesRemainingInPage > 0) {
- size_t bytesJustRead = oggbs->onRead(oggbs->pUserData, pRunningBufferOut, oggbs->bytesRemainingInPage);
- bytesRead += bytesJustRead;
- pRunningBufferOut += bytesJustRead;
-
- if (bytesJustRead != oggbs->bytesRemainingInPage) {
- break; // Ran out of data.
- }
+ drflac_copy_memory(pRunningBufferOut, oggbs->pageData + (oggbs->pageDataSize - oggbs->bytesRemainingInPage), oggbs->bytesRemainingInPage);
+ bytesRead += oggbs->bytesRemainingInPage;
+ pRunningBufferOut += oggbs->bytesRemainingInPage;
+ oggbs->bytesRemainingInPage = 0;
}
- assert(bytesRemainingToRead > 0);
- if (!drflac_oggbs__goto_next_page(oggbs)) {
- break; // Failed to go to the next chunk. Might have simply hit the end of the stream.
+ drflac_assert(bytesRemainingToRead > 0);
+ if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_recover_on_crc_mismatch)) {
+ break; // Failed to go to the next page. Might have simply hit the end of the stream.
}
}
- oggbs->currentBytePos += bytesRead;
return bytesRead;
}
-static dr_bool32 drflac__on_seek_ogg(void* pUserData, int offset, drflac_seek_origin origin)
+static drflac_bool32 drflac__on_seek_ogg(void* pUserData, int offset, drflac_seek_origin origin)
{
drflac_oggbs* oggbs = (drflac_oggbs*)pUserData;
- assert(oggbs != NULL);
- assert(offset > 0 || (offset == 0 && origin == drflac_seek_origin_start));
+ drflac_assert(oggbs != NULL);
+ drflac_assert(offset > 0 || (offset == 0 && origin == drflac_seek_origin_start));
// Seeking is always forward which makes things a lot simpler.
if (origin == drflac_seek_origin_start) {
- int startBytePos = (int)oggbs->firstBytePos + (79-42); // 79 = size of bos page; 42 = size of FLAC header data. Seek up to the first byte of the native FLAC data.
- if (!drflac_oggbs__seek_physical(oggbs, startBytePos, drflac_seek_origin_start)) {
- return DR_FALSE;
+ if (!drflac_oggbs__seek_physical(oggbs, (int)oggbs->firstBytePos, drflac_seek_origin_start)) {
+ return DRFLAC_FALSE;
}
- oggbs->currentPageHeader = oggbs->bosPageHeader;
- oggbs->bytesRemainingInPage = 42; // 42 = size of the native FLAC header data. That's our start point for seeking.
+ if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_fail_on_crc_mismatch)) {
+ return DRFLAC_FALSE;
+ }
return drflac__on_seek_ogg(pUserData, offset, drflac_seek_origin_current);
}
- assert(origin == drflac_seek_origin_current);
+ drflac_assert(origin == drflac_seek_origin_current);
int bytesSeeked = 0;
- while (bytesSeeked < offset)
- {
+ while (bytesSeeked < offset) {
int bytesRemainingToSeek = offset - bytesSeeked;
- assert(bytesRemainingToSeek >= 0);
+ drflac_assert(bytesRemainingToSeek >= 0);
if (oggbs->bytesRemainingInPage >= (size_t)bytesRemainingToSeek) {
- if (!drflac_oggbs__seek_physical(oggbs, bytesRemainingToSeek, drflac_seek_origin_current)) {
- return DR_FALSE;
- }
-
bytesSeeked += bytesRemainingToSeek;
oggbs->bytesRemainingInPage -= bytesRemainingToSeek;
break;
@@ -3209,45 +4153,42 @@ static dr_bool32 drflac__on_seek_ogg(void* pUserData, int offset, drflac_seek_or
// If we get here it means some of the requested data is contained in the next pages.
if (oggbs->bytesRemainingInPage > 0) {
- if (!drflac_oggbs__seek_physical(oggbs, oggbs->bytesRemainingInPage, drflac_seek_origin_current)) {
- return DR_FALSE;
- }
-
bytesSeeked += (int)oggbs->bytesRemainingInPage;
+ oggbs->bytesRemainingInPage = 0;
}
- assert(bytesRemainingToSeek > 0);
- if (!drflac_oggbs__goto_next_page(oggbs)) {
- break; // Failed to go to the next chunk. Might have simply hit the end of the stream.
+ drflac_assert(bytesRemainingToSeek > 0);
+ if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_fail_on_crc_mismatch)) {
+ // Failed to go to the next page. We either hit the end of the stream or had a CRC mismatch.
+ return DRFLAC_FALSE;
}
}
- return DR_TRUE;
+ return DRFLAC_TRUE;
}
-dr_bool32 drflac_ogg__seek_to_sample(drflac* pFlac, uint64_t sample)
+drflac_bool32 drflac_ogg__seek_to_sample(drflac* pFlac, drflac_uint64 sampleIndex)
{
- drflac_oggbs* oggbs = (drflac_oggbs*)(((int32_t*)pFlac->pExtraData) + pFlac->maxBlockSize*pFlac->channels);
+ drflac_oggbs* oggbs = (drflac_oggbs*)pFlac->_oggbs;
- uint64_t originalBytePos = oggbs->currentBytePos; // For recovery.
+ drflac_uint64 originalBytePos = oggbs->currentBytePos; // For recovery.
// First seek to the first frame.
if (!drflac__seek_to_byte(&pFlac->bs, pFlac->firstFramePos)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
oggbs->bytesRemainingInPage = 0;
- uint64_t runningGranulePosition = 0;
- uint64_t runningFrameBytePos = oggbs->currentBytePos; // <-- Points to the OggS identifier.
- for (;;)
- {
- if (!drflac_oggbs__goto_next_page(oggbs)) {
+ drflac_uint64 runningGranulePosition = 0;
+ drflac_uint64 runningFrameBytePos = oggbs->currentBytePos; // <-- Points to the OggS identifier.
+ for (;;) {
+ if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_recover_on_crc_mismatch)) {
drflac_oggbs__seek_physical(oggbs, originalBytePos, drflac_seek_origin_start);
- return DR_FALSE; // Never did find that sample...
+ return DRFLAC_FALSE; // Never did find that sample...
}
- runningFrameBytePos = oggbs->currentBytePos - drflac_ogg__get_page_header_size(&oggbs->currentPageHeader);
- if (oggbs->currentPageHeader.granulePosition*pFlac->channels >= sample) {
+ runningFrameBytePos = oggbs->currentBytePos - drflac_ogg__get_page_header_size(&oggbs->currentPageHeader) - oggbs->pageDataSize;
+ if (oggbs->currentPageHeader.granulePosition*pFlac->channels >= sampleIndex) {
break; // The sample is somewhere in the previous page.
}
@@ -3256,28 +4197,17 @@ dr_bool32 drflac_ogg__seek_to_sample(drflac* pFlac, uint64_t sample)
// disregard any pages that do not begin a fresh packet.
if ((oggbs->currentPageHeader.headerType & 0x01) == 0) { // <-- Is it a fresh page?
if (oggbs->currentPageHeader.segmentTable[0] >= 2) {
- uint8_t firstBytesInPage[2];
- if (drflac_oggbs__read_physical(oggbs, firstBytesInPage, 2) != 2) {
- drflac_oggbs__seek_physical(oggbs, originalBytePos, drflac_seek_origin_start);
- return DR_FALSE;
- }
+ drflac_uint8 firstBytesInPage[2];
+ firstBytesInPage[0] = oggbs->pageData[0];
+ firstBytesInPage[1] = oggbs->pageData[1];
+
if ((firstBytesInPage[0] == 0xFF) && (firstBytesInPage[1] & 0xFC) == 0xF8) { // <-- Does the page begin with a frame's sync code?
runningGranulePosition = oggbs->currentPageHeader.granulePosition*pFlac->channels;
}
- if (!drflac_oggbs__seek_physical(oggbs, (int)oggbs->bytesRemainingInPage-2, drflac_seek_origin_current)) {
- drflac_oggbs__seek_physical(oggbs, originalBytePos, drflac_seek_origin_start);
- return DR_FALSE;
- }
-
continue;
}
}
-
- if (!drflac_oggbs__seek_physical(oggbs, (int)oggbs->bytesRemainingInPage, drflac_seek_origin_current)) {
- drflac_oggbs__seek_physical(oggbs, originalBytePos, drflac_seek_origin_start);
- return DR_FALSE;
- }
}
@@ -3286,71 +4216,85 @@ dr_bool32 drflac_ogg__seek_to_sample(drflac* pFlac, uint64_t sample)
// a new frame. This property means that after we've seeked to the page we can immediately start looping over frames until
// we find the one containing the target sample.
if (!drflac_oggbs__seek_physical(oggbs, runningFrameBytePos, drflac_seek_origin_start)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
- if (!drflac_oggbs__goto_next_page(oggbs)) {
- return DR_FALSE;
+ if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_recover_on_crc_mismatch)) {
+ return DRFLAC_FALSE;
}
// At this point we'll be sitting on the first byte of the frame header of the first frame in the page. We just keep
// looping over these frames until we find the one containing the sample we're after.
- uint64_t firstSampleInFrame = runningGranulePosition;
- for (;;)
- {
- // NOTE for later: When using Ogg's page/segment based seeking later on we can't use this function (or any drflac__*
- // reading functions) because otherwise it will pull extra data for use in it's own internal caches which will then
- // break the positioning of the read pointer for the Ogg bitstream.
+ drflac_uint64 runningSampleCount = runningGranulePosition;
+ for (;;) {
+ // There are two ways to find the sample and seek past irrelevant frames:
+ // 1) Use the native FLAC decoder.
+ // 2) Use Ogg's framing system.
+ //
+ // Both of these options have their own pros and cons. Using the native FLAC decoder is slower because it needs to
+ // do a full decode of the frame. Using Ogg's framing system is faster, but more complicated and involves some code
+ // duplication for the decoding of frame headers.
+ //
+ // Another thing to consider is that using the Ogg framing system will perform direct seeking of the physical Ogg
+ // bitstream. This is important to consider because it means we cannot read data from the drflac_bs object using the
+ // standard drflac__*() APIs because that will read in extra data for it's own internal caching which in turn breaks
+ // the positioning of the read pointer of the physical Ogg bitstream. Therefore, anything that would normally be read
+ // using the native FLAC decoding APIs, such as drflac__read_next_frame_header(), need to be re-implemented so as to
+ // avoid the use of the drflac_bs object.
+ //
+ // Considering these issues, I have decided to use the slower native FLAC decoding method for the following reasons:
+ // 1) Seeking is already partially accellerated using Ogg's paging system in the code block above.
+ // 2) Seeking in an Ogg encapsulated FLAC stream is probably quite uncommon.
+ // 3) Simplicity.
if (!drflac__read_next_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFrame.header)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
- int channels = drflac__get_channel_count_from_channel_assignment(pFlac->currentFrame.header.channelAssignment);
- uint64_t lastSampleInFrame = firstSampleInFrame + (pFlac->currentFrame.header.blockSize*channels);
- lastSampleInFrame -= 1; // <-- Zero based.
+ drflac_uint64 firstSampleInFrame = 0;
+ drflac_uint64 lastSampleInFrame = 0;
+ drflac__get_current_frame_sample_range(pFlac, &firstSampleInFrame, &lastSampleInFrame);
- if (sample >= firstSampleInFrame && sample <= lastSampleInFrame) {
- break; // The sample is in this frame.
+ drflac_uint64 sampleCountInThisFrame = (lastSampleInFrame - firstSampleInFrame) + 1;
+ if (sampleIndex < (runningSampleCount + sampleCountInThisFrame)) {
+ // The sample should be in this frame. We need to fully decode it, however if it's an invalid frame (a CRC mismatch), we need to pretend
+ // it never existed and keep iterating.
+ drflac_result result = drflac__decode_frame(pFlac);
+ if (result == DRFLAC_SUCCESS) {
+ // The frame is valid. We just need to skip over some samples to ensure it's sample-exact.
+ drflac_uint64 samplesToDecode = (size_t)(sampleIndex - runningSampleCount); // <-- Safe cast because the maximum number of samples in a frame is 65535.
+ if (samplesToDecode == 0) {
+ return DRFLAC_TRUE;
+ }
+ return drflac_read_s32(pFlac, samplesToDecode, NULL) != 0; // <-- If this fails, something bad has happened (it should never fail).
+ } else {
+ if (result == DRFLAC_CRC_MISMATCH) {
+ continue; // CRC mismatch. Pretend this frame never existed.
+ } else {
+ return DRFLAC_FALSE;
+ }
+ }
+ } else {
+ // It's not in this frame. We need to seek past the frame, but check if there was a CRC mismatch. If so, we pretend this
+ // frame never existed and leave the running sample count untouched.
+ drflac_result result = drflac__seek_to_next_frame(pFlac);
+ if (result == DRFLAC_SUCCESS) {
+ runningSampleCount += sampleCountInThisFrame;
+ } else {
+ if (result == DRFLAC_CRC_MISMATCH) {
+ continue; // CRC mismatch. Pretend this frame never existed.
+ } else {
+ return DRFLAC_FALSE;
+ }
+ }
}
-
-
- // If we get here it means the sample is not in this frame so we need to move to the next one. Now the cool thing
- // with Ogg is that we can efficiently seek past the frame by looking at the lacing values of each segment in
- // the page.
- firstSampleInFrame = lastSampleInFrame+1;
-
-#if 1
- // Slow way. This uses the native FLAC decoder to seek past the frame. This is slow because it needs to do a partial
- // decode of the frame. Although this is how the native version works, we can use Ogg's framing system to make it
- // more efficient. Leaving this here for reference and to use as a basis for debugging purposes.
- if (!drflac__seek_to_next_frame(pFlac)) {
- return DR_FALSE;
- }
-#else
- // TODO: This is not yet complete. See note at the top of this loop body.
-
- // Fast(er) way. This uses Ogg's framing system to seek past the frame. This should be much more efficient than the
- // native FLAC seeking.
- if (!drflac_oggbs__seek_to_next_frame(oggbs)) {
- return DR_FALSE;
- }
-#endif
}
-
- assert(firstSampleInFrame <= sample);
-
- if (!drflac__decode_frame(pFlac)) {
- return DR_FALSE;
- }
-
- size_t samplesToDecode = (size_t)(sample - firstSampleInFrame); // <-- Safe cast because the maximum number of samples in a frame is 65535.
- return drflac_read_s32(pFlac, samplesToDecode, NULL) == samplesToDecode;
}
-dr_bool32 drflac__init_private__ogg(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD)
+drflac_bool32 drflac__init_private__ogg(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD, drflac_bool32 relaxed)
{
// Pre: The bit stream should be sitting just past the 4-byte OggS capture pattern.
+ (void)relaxed;
pInit->container = drflac_container_ogg;
pInit->oggFirstBytePos = 0;
@@ -3360,88 +4304,85 @@ dr_bool32 drflac__init_private__ogg(drflac_init_info* pInit, drflac_read_proc on
// any match the FLAC specification. Important to keep in mind that the stream may be multiplexed.
drflac_ogg_page_header header;
- uint32_t headerSize;
- if (!drflac_ogg__read_page_header_after_capture_pattern(onRead, pUserData, &header, &headerSize)) {
- return DR_FALSE;
+ drflac_uint32 crc32 = DRFLAC_OGG_CAPTURE_PATTERN_CRC32;
+ drflac_uint32 bytesRead = 0;
+ if (drflac_ogg__read_page_header_after_capture_pattern(onRead, pUserData, &header, &bytesRead, &crc32) != DRFLAC_SUCCESS) {
+ return DRFLAC_FALSE;
}
- pInit->runningFilePos = headerSize;
+ pInit->runningFilePos += bytesRead;
- for (;;)
- {
+ for (;;) {
// Break if we're past the beginning of stream page.
if ((header.headerType & 0x02) == 0) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
// Check if it's a FLAC header.
int pageBodySize = drflac_ogg__get_page_body_size(&header);
- if (pageBodySize == 51) // 51 = the lacing value of the FLAC header packet.
- {
+ if (pageBodySize == 51) { // 51 = the lacing value of the FLAC header packet.
// It could be a FLAC page...
- uint32_t bytesRemainingInPage = pageBodySize;
+ drflac_uint32 bytesRemainingInPage = pageBodySize;
- uint8_t packetType;
+ drflac_uint8 packetType;
if (onRead(pUserData, &packetType, 1) != 1) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
bytesRemainingInPage -= 1;
- if (packetType == 0x7F)
- {
+ if (packetType == 0x7F) {
// Increasingly more likely to be a FLAC page...
- uint8_t sig[4];
+ drflac_uint8 sig[4];
if (onRead(pUserData, sig, 4) != 4) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
bytesRemainingInPage -= 4;
- if (sig[0] == 'F' && sig[1] == 'L' && sig[2] == 'A' && sig[3] == 'C')
- {
+ if (sig[0] == 'F' && sig[1] == 'L' && sig[2] == 'A' && sig[3] == 'C') {
// Almost certainly a FLAC page...
- uint8_t mappingVersion[2];
+ drflac_uint8 mappingVersion[2];
if (onRead(pUserData, mappingVersion, 2) != 2) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
if (mappingVersion[0] != 1) {
- return DR_FALSE; // Only supporting version 1.x of the Ogg mapping.
+ return DRFLAC_FALSE; // Only supporting version 1.x of the Ogg mapping.
}
// The next 2 bytes are the non-audio packets, not including this one. We don't care about this because we're going to
// be handling it in a generic way based on the serial number and packet types.
if (!onSeek(pUserData, 2, drflac_seek_origin_current)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
// Expecting the native FLAC signature "fLaC".
if (onRead(pUserData, sig, 4) != 4) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
- if (sig[0] == 'f' && sig[1] == 'L' && sig[2] == 'a' && sig[3] == 'C')
- {
+ if (sig[0] == 'f' && sig[1] == 'L' && sig[2] == 'a' && sig[3] == 'C') {
// The remaining data in the page should be the STREAMINFO block.
- uint8_t isLastBlock;
- uint8_t blockType;
- uint32_t blockSize;
+ drflac_uint8 isLastBlock;
+ drflac_uint8 blockType;
+ drflac_uint32 blockSize;
if (!drflac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
if (blockType != DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO || blockSize != 34) {
- return DR_FALSE; // Invalid block type. First block must be the STREAMINFO block.
+ return DRFLAC_FALSE; // Invalid block type. First block must be the STREAMINFO block.
}
drflac_streaminfo streaminfo;
- if (drflac__read_streaminfo(onRead, pUserData, &streaminfo))
- {
+ if (drflac__read_streaminfo(onRead, pUserData, &streaminfo)) {
// Success!
- pInit->sampleRate = streaminfo.sampleRate;
- pInit->channels = streaminfo.channels;
- pInit->bitsPerSample = streaminfo.bitsPerSample;
- pInit->totalSampleCount = streaminfo.totalSampleCount;
- pInit->maxBlockSize = streaminfo.maxBlockSize;
+ pInit->hasStreamInfoBlock = DRFLAC_TRUE;
+ pInit->sampleRate = streaminfo.sampleRate;
+ pInit->channels = streaminfo.channels;
+ pInit->bitsPerSample = streaminfo.bitsPerSample;
+ pInit->totalSampleCount = streaminfo.totalSampleCount;
+ pInit->maxBlockSize = streaminfo.maxBlockSize;
+ pInit->hasMetadataBlocks = !isLastBlock;
if (onMeta) {
drflac_metadata metadata;
@@ -3457,39 +4398,29 @@ dr_bool32 drflac__init_private__ogg(drflac_init_info* pInit, drflac_read_proc on
pInit->oggSerial = header.serialNumber;
pInit->oggBosHeader = header;
break;
- }
- else
- {
+ } else {
// Failed to read STREAMINFO block. Aww, so close...
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
- }
- else
- {
+ } else {
// Invalid file.
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
- }
- else
- {
+ } else {
// Not a FLAC header. Skip it.
if (!onSeek(pUserData, bytesRemainingInPage, drflac_seek_origin_current)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
}
- }
- else
- {
+ } else {
// Not a FLAC header. Seek past the entire page and move on to the next.
if (!onSeek(pUserData, bytesRemainingInPage, drflac_seek_origin_current)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
}
- }
- else
- {
+ } else {
if (!onSeek(pUserData, pageBodySize, drflac_seek_origin_current)) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
}
@@ -3497,85 +4428,153 @@ dr_bool32 drflac__init_private__ogg(drflac_init_info* pInit, drflac_read_proc on
// Read the header of the next page.
- if (!drflac_ogg__read_page_header(onRead, pUserData, &header, &headerSize)) {
- return DR_FALSE;
+ if (drflac_ogg__read_page_header(onRead, pUserData, &header, &bytesRead, &crc32) != DRFLAC_SUCCESS) {
+ return DRFLAC_FALSE;
}
- pInit->runningFilePos += headerSize;
+ pInit->runningFilePos += bytesRead;
}
// If we get here it means we found a FLAC audio stream. We should be sitting on the first byte of the header of the next page. The next
// packets in the FLAC logical stream contain the metadata. The only thing left to do in the initialiation phase for Ogg is to create the
// Ogg bistream object.
- pInit->hasMetadataBlocks = DR_TRUE; // <-- Always have at least VORBIS_COMMENT metadata block.
- return DR_TRUE;
+ pInit->hasMetadataBlocks = DRFLAC_TRUE; // <-- Always have at least VORBIS_COMMENT metadata block.
+ return DRFLAC_TRUE;
}
#endif
-dr_bool32 drflac__init_private(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD)
+drflac_bool32 drflac__init_private(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, drflac_container container, void* pUserData, void* pUserDataMD)
{
if (pInit == NULL || onRead == NULL || onSeek == NULL) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
- pInit->onRead = onRead;
- pInit->onSeek = onSeek;
- pInit->onMeta = onMeta;
- pInit->pUserData = pUserData;
- pInit->pUserDataMD = pUserDataMD;
+ drflac_zero_memory(pInit, sizeof(*pInit));
+ pInit->onRead = onRead;
+ pInit->onSeek = onSeek;
+ pInit->onMeta = onMeta;
+ pInit->container = container;
+ pInit->pUserData = pUserData;
+ pInit->pUserDataMD = pUserDataMD;
- uint8_t id[4];
- if (onRead(pUserData, id, 4) != 4) {
- return DR_FALSE;
+ pInit->bs.onRead = onRead;
+ pInit->bs.onSeek = onSeek;
+ pInit->bs.pUserData = pUserData;
+ drflac__reset_cache(&pInit->bs);
+
+
+ // If the container is explicitly defined then we can try opening in relaxed mode.
+ drflac_bool32 relaxed = container != drflac_container_unknown;
+
+ drflac_uint8 id[4];
+
+ // Skip over any ID3 tags.
+ for (;;) {
+ if (onRead(pUserData, id, 4) != 4) {
+ return DRFLAC_FALSE; // Ran out of data.
+ }
+ pInit->runningFilePos += 4;
+
+ if (id[0] == 'I' && id[1] == 'D' && id[2] == '3') {
+ drflac_uint8 header[6];
+ if (onRead(pUserData, header, 6) != 6) {
+ return DRFLAC_FALSE; // Ran out of data.
+ }
+ pInit->runningFilePos += 6;
+
+ drflac_uint8 flags = header[1];
+ drflac_uint32 headerSize;
+ drflac_copy_memory(&headerSize, header+2, 4);
+ headerSize = drflac__unsynchsafe_32(drflac__be2host_32(headerSize));
+ if (flags & 0x10) {
+ headerSize += 10;
+ }
+
+ if (!onSeek(pUserData, headerSize, drflac_seek_origin_current)) {
+ return DRFLAC_FALSE; // Failed to seek past the tag.
+ }
+ pInit->runningFilePos += headerSize;
+ } else {
+ break;
+ }
}
if (id[0] == 'f' && id[1] == 'L' && id[2] == 'a' && id[3] == 'C') {
- return drflac__init_private__native(pInit, onRead, onSeek, onMeta, pUserData, pUserDataMD);
+ return drflac__init_private__native(pInit, onRead, onSeek, onMeta, pUserData, pUserDataMD, relaxed);
}
-
#ifndef DR_FLAC_NO_OGG
if (id[0] == 'O' && id[1] == 'g' && id[2] == 'g' && id[3] == 'S') {
- return drflac__init_private__ogg(pInit, onRead, onSeek, onMeta, pUserData, pUserDataMD);
+ return drflac__init_private__ogg(pInit, onRead, onSeek, onMeta, pUserData, pUserDataMD, relaxed);
}
#endif
+ // If we get here it means we likely don't have a header. Try opening in relaxed mode, if applicable.
+ if (relaxed) {
+ if (container == drflac_container_native) {
+ return drflac__init_private__native(pInit, onRead, onSeek, onMeta, pUserData, pUserDataMD, relaxed);
+ }
+#ifndef DR_FLAC_NO_OGG
+ if (container == drflac_container_ogg) {
+ return drflac__init_private__ogg(pInit, onRead, onSeek, onMeta, pUserData, pUserDataMD, relaxed);
+ }
+#endif
+ }
+
// Unsupported container.
- return DR_FALSE;
+ return DRFLAC_FALSE;
}
void drflac__init_from_info(drflac* pFlac, drflac_init_info* pInit)
{
- assert(pFlac != NULL);
- assert(pInit != NULL);
-
- memset(pFlac, 0, sizeof(*pFlac));
- pFlac->bs.onRead = pInit->onRead;
- pFlac->bs.onSeek = pInit->onSeek;
- pFlac->bs.pUserData = pInit->pUserData;
- pFlac->bs.nextL2Line = sizeof(pFlac->bs.cacheL2) / sizeof(pFlac->bs.cacheL2[0]); // <-- Initialize to this to force a client-side data retrieval right from the start.
- pFlac->bs.consumedBits = sizeof(pFlac->bs.cache)*8;
+ drflac_assert(pFlac != NULL);
+ drflac_assert(pInit != NULL);
+ drflac_zero_memory(pFlac, sizeof(*pFlac));
+ pFlac->bs = pInit->bs;
pFlac->onMeta = pInit->onMeta;
pFlac->pUserDataMD = pInit->pUserDataMD;
pFlac->maxBlockSize = pInit->maxBlockSize;
pFlac->sampleRate = pInit->sampleRate;
- pFlac->channels = (uint8_t)pInit->channels;
- pFlac->bitsPerSample = (uint8_t)pInit->bitsPerSample;
+ pFlac->channels = (drflac_uint8)pInit->channels;
+ pFlac->bitsPerSample = (drflac_uint8)pInit->bitsPerSample;
pFlac->totalSampleCount = pInit->totalSampleCount;
pFlac->container = pInit->container;
}
-drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD)
+drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, drflac_container container, void* pUserData, void* pUserDataMD)
{
+#ifndef DRFLAC_NO_CPUID
+ // CPU support first.
+ drflac__init_cpu_caps();
+#endif
+
drflac_init_info init;
- if (!drflac__init_private(&init, onRead, onSeek, onMeta, pUserData, pUserDataMD)) {
+ if (!drflac__init_private(&init, onRead, onSeek, onMeta, container, pUserData, pUserDataMD)) {
return NULL;
}
- size_t allocationSize = sizeof(drflac);
- allocationSize += init.maxBlockSize * init.channels * sizeof(int32_t);
- //allocationSize += init.seektableSize;
+ // The size of the allocation for the drflac object needs to be large enough to fit the following:
+ // 1) The main members of the drflac structure
+ // 2) A block of memory large enough to store the decoded samples of the largest frame in the stream
+ // 3) If the container is Ogg, a drflac_oggbs object
+ //
+ // The complicated part of the allocation is making sure there's enough room the decoded samples, taking into consideration
+ // the different SIMD instruction sets.
+ drflac_uint32 allocationSize = sizeof(drflac);
+ // The allocation size for decoded frames depends on the number of 32-bit integers that fit inside the largest SIMD vector
+ // we are supporting.
+ drflac_uint32 wholeSIMDVectorCountPerChannel;
+ if ((init.maxBlockSize % (DRFLAC_MAX_SIMD_VECTOR_SIZE / sizeof(drflac_int32))) == 0) {
+ wholeSIMDVectorCountPerChannel = (init.maxBlockSize / (DRFLAC_MAX_SIMD_VECTOR_SIZE / sizeof(drflac_int32)));
+ } else {
+ wholeSIMDVectorCountPerChannel = (init.maxBlockSize / (DRFLAC_MAX_SIMD_VECTOR_SIZE / sizeof(drflac_int32))) + 1;
+ }
+
+ drflac_uint32 decodedSamplesAllocationSize = wholeSIMDVectorCountPerChannel * DRFLAC_MAX_SIMD_VECTOR_SIZE * init.channels;
+
+ allocationSize += decodedSamplesAllocationSize;
+ allocationSize += DRFLAC_MAX_SIMD_VECTOR_SIZE; // Allocate extra bytes to ensure we have enough for alignment.
#ifndef DR_FLAC_NO_OGG
// There's additional data required for Ogg streams.
@@ -3584,13 +4583,13 @@ drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac_seek_p
}
#endif
- drflac* pFlac = (drflac*)malloc(allocationSize);
+ drflac* pFlac = (drflac*)DRFLAC_MALLOC(allocationSize);
drflac__init_from_info(pFlac, &init);
- pFlac->pDecodedSamples = (int32_t*)pFlac->pExtraData;
+ pFlac->pDecodedSamples = (drflac_int32*)drflac_align((size_t)pFlac->pExtraData, DRFLAC_MAX_SIMD_VECTOR_SIZE);
#ifndef DR_FLAC_NO_OGG
if (init.container == drflac_container_ogg) {
- drflac_oggbs* oggbs = (drflac_oggbs*)(((int32_t*)pFlac->pExtraData) + init.maxBlockSize*init.channels);
+ drflac_oggbs* oggbs = (drflac_oggbs*)((drflac_uint8*)pFlac->pDecodedSamples + decodedSamplesAllocationSize);
oggbs->onRead = onRead;
oggbs->onSeek = onSeek;
oggbs->pUserData = pUserData;
@@ -3604,17 +4603,42 @@ drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac_seek_p
pFlac->bs.onRead = drflac__on_read_ogg;
pFlac->bs.onSeek = drflac__on_seek_ogg;
pFlac->bs.pUserData = (void*)oggbs;
+ pFlac->_oggbs = (void*)oggbs;
}
#endif
// Decode metadata before returning.
if (init.hasMetadataBlocks) {
if (!drflac__read_and_decode_metadata(pFlac)) {
- free(pFlac);
+ DRFLAC_FREE(pFlac);
return NULL;
}
}
+ // If we get here, but don't have a STREAMINFO block, it means we've opened the stream in relaxed mode and need to decode
+ // the first frame.
+ if (!init.hasStreamInfoBlock) {
+ pFlac->currentFrame.header = init.firstFrameHeader;
+ do
+ {
+ drflac_result result = drflac__decode_frame(pFlac);
+ if (result == DRFLAC_SUCCESS) {
+ break;
+ } else {
+ if (result == DRFLAC_CRC_MISMATCH) {
+ if (!drflac__read_next_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFrame.header)) {
+ DRFLAC_FREE(pFlac);
+ return NULL;
+ }
+ continue;
+ } else {
+ DRFLAC_FREE(pFlac);
+ return NULL;
+ }
+ }
+ } while (1);
+ }
+
return pFlac;
}
@@ -3631,9 +4655,9 @@ static size_t drflac__on_read_stdio(void* pUserData, void* bufferOut, size_t byt
return fread(bufferOut, 1, bytesToRead, (FILE*)pUserData);
}
-static dr_bool32 drflac__on_seek_stdio(void* pUserData, int offset, drflac_seek_origin origin)
+static drflac_bool32 drflac__on_seek_stdio(void* pUserData, int offset, drflac_seek_origin origin)
{
- assert(offset > 0 || (offset == 0 && origin == drflac_seek_origin_start));
+ drflac_assert(offset > 0 || (offset == 0 && origin == drflac_seek_origin_start));
return fseek((FILE*)pUserData, offset, (origin == drflac_seek_origin_current) ? SEEK_CUR : SEEK_SET) == 0;
}
@@ -3662,9 +4686,14 @@ static void drflac__close_file_handle(drflac_file file)
#else
#include
+// This doesn't seem to be defined for VC6.
+#ifndef INVALID_SET_FILE_POINTER
+#define INVALID_SET_FILE_POINTER ((DWORD)-1)
+#endif
+
static size_t drflac__on_read_stdio(void* pUserData, void* bufferOut, size_t bytesToRead)
{
- assert(bytesToRead < 0xFFFFFFFF); // dr_flac will never request huge amounts of data at a time. This is a safe assertion.
+ drflac_assert(bytesToRead < 0xFFFFFFFF); // dr_flac will never request huge amounts of data at a time. This is a safe assertion.
DWORD bytesRead;
ReadFile((HANDLE)pUserData, bufferOut, (DWORD)bytesToRead, &bytesRead, NULL);
@@ -3672,9 +4701,9 @@ static size_t drflac__on_read_stdio(void* pUserData, void* bufferOut, size_t byt
return (size_t)bytesRead;
}
-static dr_bool32 drflac__on_seek_stdio(void* pUserData, int offset, drflac_seek_origin origin)
+static drflac_bool32 drflac__on_seek_stdio(void* pUserData, int offset, drflac_seek_origin origin)
{
- assert(offset > 0 || (offset == 0 && origin == drflac_seek_origin_start));
+ drflac_assert(offset > 0 || (offset == 0 && origin == drflac_seek_origin_start));
return SetFilePointer((HANDLE)pUserData, offset, NULL, (origin == drflac_seek_origin_current) ? FILE_CURRENT : FILE_BEGIN) != INVALID_SET_FILE_POINTER;
}
@@ -3719,7 +4748,7 @@ drflac* drflac_open_file_with_metadata(const char* filename, drflac_meta_proc on
return NULL;
}
- drflac* pFlac = drflac_open_with_metadata_private(drflac__on_read_stdio, drflac__on_seek_stdio, onMeta, (void*)file, pUserData);
+ drflac* pFlac = drflac_open_with_metadata_private(drflac__on_read_stdio, drflac__on_seek_stdio, onMeta, drflac_container_unknown, (void*)file, pUserData);
if (pFlac == NULL) {
drflac__close_file_handle(file);
return pFlac;
@@ -3732,8 +4761,8 @@ drflac* drflac_open_file_with_metadata(const char* filename, drflac_meta_proc on
static size_t drflac__on_read_memory(void* pUserData, void* bufferOut, size_t bytesToRead)
{
drflac__memory_stream* memoryStream = (drflac__memory_stream*)pUserData;
- assert(memoryStream != NULL);
- assert(memoryStream->dataSize >= memoryStream->currentReadPos);
+ drflac_assert(memoryStream != NULL);
+ drflac_assert(memoryStream->dataSize >= memoryStream->currentReadPos);
size_t bytesRemaining = memoryStream->dataSize - memoryStream->currentReadPos;
if (bytesToRead > bytesRemaining) {
@@ -3741,18 +4770,18 @@ static size_t drflac__on_read_memory(void* pUserData, void* bufferOut, size_t by
}
if (bytesToRead > 0) {
- memcpy(bufferOut, memoryStream->data + memoryStream->currentReadPos, bytesToRead);
+ drflac_copy_memory(bufferOut, memoryStream->data + memoryStream->currentReadPos, bytesToRead);
memoryStream->currentReadPos += bytesToRead;
}
return bytesToRead;
}
-static dr_bool32 drflac__on_seek_memory(void* pUserData, int offset, drflac_seek_origin origin)
+static drflac_bool32 drflac__on_seek_memory(void* pUserData, int offset, drflac_seek_origin origin)
{
drflac__memory_stream* memoryStream = (drflac__memory_stream*)pUserData;
- assert(memoryStream != NULL);
- assert(offset > 0 || (offset == 0 && origin == drflac_seek_origin_start));
+ drflac_assert(memoryStream != NULL);
+ drflac_assert(offset > 0 || (offset == 0 && origin == drflac_seek_origin_start));
if (origin == drflac_seek_origin_current) {
if (memoryStream->currentReadPos + offset <= memoryStream->dataSize) {
@@ -3761,14 +4790,14 @@ static dr_bool32 drflac__on_seek_memory(void* pUserData, int offset, drflac_seek
memoryStream->currentReadPos = memoryStream->dataSize; // Trying to seek too far forward.
}
} else {
- if ((uint32_t)offset <= memoryStream->dataSize) {
+ if ((drflac_uint32)offset <= memoryStream->dataSize) {
memoryStream->currentReadPos = offset;
} else {
memoryStream->currentReadPos = memoryStream->dataSize; // Trying to seek too far forward.
}
}
- return DR_TRUE;
+ return DRFLAC_TRUE;
}
drflac* drflac_open_memory(const void* data, size_t dataSize)
@@ -3788,7 +4817,7 @@ drflac* drflac_open_memory(const void* data, size_t dataSize)
#ifndef DR_FLAC_NO_OGG
if (pFlac->container == drflac_container_ogg)
{
- drflac_oggbs* oggbs = (drflac_oggbs*)(((int32_t*)pFlac->pExtraData) + pFlac->maxBlockSize*pFlac->channels);
+ drflac_oggbs* oggbs = (drflac_oggbs*)pFlac->_oggbs;
oggbs->pUserData = &pFlac->memoryStream;
}
else
@@ -3806,7 +4835,7 @@ drflac* drflac_open_memory_with_metadata(const void* data, size_t dataSize, drfl
memoryStream.data = (const unsigned char*)data;
memoryStream.dataSize = dataSize;
memoryStream.currentReadPos = 0;
- drflac* pFlac = drflac_open_with_metadata_private(drflac__on_read_memory, drflac__on_seek_memory, onMeta, &memoryStream, pUserData);
+ drflac* pFlac = drflac_open_with_metadata_private(drflac__on_read_memory, drflac__on_seek_memory, onMeta, drflac_container_unknown, &memoryStream, pUserData);
if (pFlac == NULL) {
return NULL;
}
@@ -3817,7 +4846,7 @@ drflac* drflac_open_memory_with_metadata(const void* data, size_t dataSize, drfl
#ifndef DR_FLAC_NO_OGG
if (pFlac->container == drflac_container_ogg)
{
- drflac_oggbs* oggbs = (drflac_oggbs*)(((int32_t*)pFlac->pExtraData) + pFlac->maxBlockSize*pFlac->channels);
+ drflac_oggbs* oggbs = (drflac_oggbs*)pFlac->_oggbs;
oggbs->pUserData = &pFlac->memoryStream;
}
else
@@ -3833,12 +4862,20 @@ drflac* drflac_open_memory_with_metadata(const void* data, size_t dataSize, drfl
drflac* drflac_open(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData)
{
- return drflac_open_with_metadata_private(onRead, onSeek, NULL, pUserData, pUserData);
+ return drflac_open_with_metadata_private(onRead, onSeek, NULL, drflac_container_unknown, pUserData, pUserData);
+}
+drflac* drflac_open_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_container container, void* pUserData)
+{
+ return drflac_open_with_metadata_private(onRead, onSeek, NULL, container, pUserData, pUserData);
}
drflac* drflac_open_with_metadata(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData)
{
- return drflac_open_with_metadata_private(onRead, onSeek, onMeta, pUserData, pUserData);
+ return drflac_open_with_metadata_private(onRead, onSeek, onMeta, drflac_container_unknown, pUserData, pUserData);
+}
+drflac* drflac_open_with_metadata_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, drflac_container container, void* pUserData)
+{
+ return drflac_open_with_metadata_private(onRead, onSeek, onMeta, container, pUserData, pUserData);
}
void drflac_close(drflac* pFlac)
@@ -3857,8 +4894,8 @@ void drflac_close(drflac* pFlac)
#ifndef DR_FLAC_NO_OGG
// Need to clean up Ogg streams a bit differently due to the way the bit streaming is chained.
if (pFlac->container == drflac_container_ogg) {
- assert(pFlac->bs.onRead == drflac__on_read_ogg);
- drflac_oggbs* oggbs = (drflac_oggbs*)((int32_t*)pFlac->pExtraData + pFlac->maxBlockSize*pFlac->channels);
+ drflac_assert(pFlac->bs.onRead == drflac__on_read_ogg);
+ drflac_oggbs* oggbs = (drflac_oggbs*)pFlac->_oggbs;
if (oggbs->onRead == drflac__on_read_stdio) {
drflac__close_file_handle((drflac_file)oggbs->pUserData);
}
@@ -3866,26 +4903,25 @@ void drflac_close(drflac* pFlac)
#endif
#endif
- free(pFlac);
+ DRFLAC_FREE(pFlac);
}
-uint64_t drflac__read_s32__misaligned(drflac* pFlac, uint64_t samplesToRead, int32_t* bufferOut)
+drflac_uint64 drflac__read_s32__misaligned(drflac* pFlac, drflac_uint64 samplesToRead, drflac_int32* bufferOut)
{
unsigned int channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFrame.header.channelAssignment);
// We should never be calling this when the number of samples to read is >= the sample count.
- assert(samplesToRead < channelCount);
- assert(pFlac->currentFrame.samplesRemaining > 0 && samplesToRead <= pFlac->currentFrame.samplesRemaining);
+ drflac_assert(samplesToRead < channelCount);
+ drflac_assert(pFlac->currentFrame.samplesRemaining > 0 && samplesToRead <= pFlac->currentFrame.samplesRemaining);
- uint64_t samplesRead = 0;
- while (samplesToRead > 0)
- {
- uint64_t totalSamplesInFrame = pFlac->currentFrame.header.blockSize * channelCount;
- uint64_t samplesReadFromFrameSoFar = totalSamplesInFrame - pFlac->currentFrame.samplesRemaining;
- unsigned int channelIndex = samplesReadFromFrameSoFar % channelCount;
+ drflac_uint64 samplesRead = 0;
+ while (samplesToRead > 0) {
+ drflac_uint64 totalSamplesInFrame = pFlac->currentFrame.header.blockSize * channelCount;
+ drflac_uint64 samplesReadFromFrameSoFar = totalSamplesInFrame - pFlac->currentFrame.samplesRemaining;
+ drflac_uint64 channelIndex = samplesReadFromFrameSoFar % channelCount;
- uint64_t nextSampleInFrame = samplesReadFromFrameSoFar / channelCount;
+ drflac_uint64 nextSampleInFrame = samplesReadFromFrameSoFar / channelCount;
int decodedSample = 0;
switch (pFlac->currentFrame.header.channelAssignment)
@@ -3899,7 +4935,6 @@ uint64_t drflac__read_s32__misaligned(drflac* pFlac, uint64_t samplesToRead, int
int left = pFlac->currentFrame.subframes[channelIndex - 1].pDecodedSamples[nextSampleInFrame];
decodedSample = left - side;
}
-
} break;
case DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE:
@@ -3911,7 +4946,6 @@ uint64_t drflac__read_s32__misaligned(drflac* pFlac, uint64_t samplesToRead, int
} else {
decodedSample = pFlac->currentFrame.subframes[channelIndex].pDecodedSamples[nextSampleInFrame];
}
-
} break;
case DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE:
@@ -3931,7 +4965,6 @@ uint64_t drflac__read_s32__misaligned(drflac* pFlac, uint64_t samplesToRead, int
mid = (((unsigned int)mid) << 1) | (side & 0x01);
decodedSample = (mid - side) >> 1;
}
-
} break;
case DRFLAC_CHANNEL_ASSIGNMENT_INDEPENDENT:
@@ -3956,19 +4989,15 @@ uint64_t drflac__read_s32__misaligned(drflac* pFlac, uint64_t samplesToRead, int
return samplesRead;
}
-uint64_t drflac__seek_forward_by_samples(drflac* pFlac, uint64_t samplesToRead)
+drflac_uint64 drflac__seek_forward_by_samples(drflac* pFlac, drflac_uint64 samplesToRead)
{
- uint64_t samplesRead = 0;
- while (samplesToRead > 0)
- {
- if (pFlac->currentFrame.samplesRemaining == 0)
- {
+ drflac_uint64 samplesRead = 0;
+ while (samplesToRead > 0) {
+ if (pFlac->currentFrame.samplesRemaining == 0) {
if (!drflac__read_and_decode_next_frame(pFlac)) {
break; // Couldn't read the next frame, so just break from the loop and return.
}
- }
- else
- {
+ } else {
samplesRead += 1;
pFlac->currentFrame.samplesRemaining -= 1;
samplesToRead -= 1;
@@ -3978,7 +5007,7 @@ uint64_t drflac__seek_forward_by_samples(drflac* pFlac, uint64_t samplesToRead)
return samplesRead;
}
-uint64_t drflac_read_s32(drflac* pFlac, uint64_t samplesToRead, int32_t* bufferOut)
+drflac_uint64 drflac_read_s32(drflac* pFlac, drflac_uint64 samplesToRead, drflac_int32* bufferOut)
{
// Note that is allowed to be null, in which case this will be treated as something like a seek.
if (pFlac == NULL || samplesToRead == 0) {
@@ -3990,27 +5019,23 @@ uint64_t drflac_read_s32(drflac* pFlac, uint64_t samplesToRead, int32_t* bufferO
}
- uint64_t samplesRead = 0;
- while (samplesToRead > 0)
- {
+ drflac_uint64 samplesRead = 0;
+ while (samplesToRead > 0) {
// If we've run out of samples in this frame, go to the next.
- if (pFlac->currentFrame.samplesRemaining == 0)
- {
+ if (pFlac->currentFrame.samplesRemaining == 0) {
if (!drflac__read_and_decode_next_frame(pFlac)) {
break; // Couldn't read the next frame, so just break from the loop and return.
}
- }
- else
- {
+ } else {
// Here is where we grab the samples and interleave them.
unsigned int channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFrame.header.channelAssignment);
- uint64_t totalSamplesInFrame = pFlac->currentFrame.header.blockSize * channelCount;
- uint64_t samplesReadFromFrameSoFar = totalSamplesInFrame - pFlac->currentFrame.samplesRemaining;
+ drflac_uint64 totalSamplesInFrame = pFlac->currentFrame.header.blockSize * channelCount;
+ drflac_uint64 samplesReadFromFrameSoFar = totalSamplesInFrame - pFlac->currentFrame.samplesRemaining;
- int misalignedSampleCount = samplesReadFromFrameSoFar % channelCount;
+ drflac_uint64 misalignedSampleCount = samplesReadFromFrameSoFar % channelCount;
if (misalignedSampleCount > 0) {
- uint64_t misalignedSamplesRead = drflac__read_s32__misaligned(pFlac, misalignedSampleCount, bufferOut);
+ drflac_uint64 misalignedSamplesRead = drflac__read_s32__misaligned(pFlac, misalignedSampleCount, bufferOut);
samplesRead += misalignedSamplesRead;
samplesReadFromFrameSoFar += misalignedSamplesRead;
bufferOut += misalignedSamplesRead;
@@ -4018,22 +5043,22 @@ uint64_t drflac_read_s32(drflac* pFlac, uint64_t samplesToRead, int32_t* bufferO
}
- uint64_t alignedSampleCountPerChannel = samplesToRead / channelCount;
+ drflac_uint64 alignedSampleCountPerChannel = samplesToRead / channelCount;
if (alignedSampleCountPerChannel > pFlac->currentFrame.samplesRemaining / channelCount) {
alignedSampleCountPerChannel = pFlac->currentFrame.samplesRemaining / channelCount;
}
- uint64_t firstAlignedSampleInFrame = samplesReadFromFrameSoFar / channelCount;
+ drflac_uint64 firstAlignedSampleInFrame = samplesReadFromFrameSoFar / channelCount;
unsigned int unusedBitsPerSample = 32 - pFlac->bitsPerSample;
switch (pFlac->currentFrame.header.channelAssignment)
{
case DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE:
{
- const int* pDecodedSamples0 = pFlac->currentFrame.subframes[0].pDecodedSamples + firstAlignedSampleInFrame;
- const int* pDecodedSamples1 = pFlac->currentFrame.subframes[1].pDecodedSamples + firstAlignedSampleInFrame;
+ const drflac_int32* pDecodedSamples0 = pFlac->currentFrame.subframes[0].pDecodedSamples + firstAlignedSampleInFrame;
+ const drflac_int32* pDecodedSamples1 = pFlac->currentFrame.subframes[1].pDecodedSamples + firstAlignedSampleInFrame;
- for (uint64_t i = 0; i < alignedSampleCountPerChannel; ++i) {
+ for (drflac_uint64 i = 0; i < alignedSampleCountPerChannel; ++i) {
int left = pDecodedSamples0[i];
int side = pDecodedSamples1[i];
int right = left - side;
@@ -4045,10 +5070,10 @@ uint64_t drflac_read_s32(drflac* pFlac, uint64_t samplesToRead, int32_t* bufferO
case DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE:
{
- const int* pDecodedSamples0 = pFlac->currentFrame.subframes[0].pDecodedSamples + firstAlignedSampleInFrame;
- const int* pDecodedSamples1 = pFlac->currentFrame.subframes[1].pDecodedSamples + firstAlignedSampleInFrame;
+ const drflac_int32* pDecodedSamples0 = pFlac->currentFrame.subframes[0].pDecodedSamples + firstAlignedSampleInFrame;
+ const drflac_int32* pDecodedSamples1 = pFlac->currentFrame.subframes[1].pDecodedSamples + firstAlignedSampleInFrame;
- for (uint64_t i = 0; i < alignedSampleCountPerChannel; ++i) {
+ for (drflac_uint64 i = 0; i < alignedSampleCountPerChannel; ++i) {
int side = pDecodedSamples0[i];
int right = pDecodedSamples1[i];
int left = right + side;
@@ -4060,12 +5085,12 @@ uint64_t drflac_read_s32(drflac* pFlac, uint64_t samplesToRead, int32_t* bufferO
case DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE:
{
- const int* pDecodedSamples0 = pFlac->currentFrame.subframes[0].pDecodedSamples + firstAlignedSampleInFrame;
- const int* pDecodedSamples1 = pFlac->currentFrame.subframes[1].pDecodedSamples + firstAlignedSampleInFrame;
+ const drflac_int32* pDecodedSamples0 = pFlac->currentFrame.subframes[0].pDecodedSamples + firstAlignedSampleInFrame;
+ const drflac_int32* pDecodedSamples1 = pFlac->currentFrame.subframes[1].pDecodedSamples + firstAlignedSampleInFrame;
- for (uint64_t i = 0; i < alignedSampleCountPerChannel; ++i) {
+ for (drflac_uint64 i = 0; i < alignedSampleCountPerChannel; ++i) {
int side = pDecodedSamples1[i];
- int mid = (((uint32_t)pDecodedSamples0[i]) << 1) | (side & 0x01);
+ int mid = (((drflac_uint32)pDecodedSamples0[i]) << 1) | (side & 0x01);
bufferOut[i*2+0] = ((mid + side) >> 1) << (unusedBitsPerSample + pFlac->currentFrame.subframes[0].wastedBitsPerSample);
bufferOut[i*2+1] = ((mid - side) >> 1) << (unusedBitsPerSample + pFlac->currentFrame.subframes[1].wastedBitsPerSample);
@@ -4078,10 +5103,10 @@ uint64_t drflac_read_s32(drflac* pFlac, uint64_t samplesToRead, int32_t* bufferO
if (pFlac->currentFrame.header.channelAssignment == 1) // 1 = Stereo
{
// Stereo optimized inner loop unroll.
- const int* pDecodedSamples0 = pFlac->currentFrame.subframes[0].pDecodedSamples + firstAlignedSampleInFrame;
- const int* pDecodedSamples1 = pFlac->currentFrame.subframes[1].pDecodedSamples + firstAlignedSampleInFrame;
+ const drflac_int32* pDecodedSamples0 = pFlac->currentFrame.subframes[0].pDecodedSamples + firstAlignedSampleInFrame;
+ const drflac_int32* pDecodedSamples1 = pFlac->currentFrame.subframes[1].pDecodedSamples + firstAlignedSampleInFrame;
- for (uint64_t i = 0; i < alignedSampleCountPerChannel; ++i) {
+ for (drflac_uint64 i = 0; i < alignedSampleCountPerChannel; ++i) {
bufferOut[i*2+0] = pDecodedSamples0[i] << (unusedBitsPerSample + pFlac->currentFrame.subframes[0].wastedBitsPerSample);
bufferOut[i*2+1] = pDecodedSamples1[i] << (unusedBitsPerSample + pFlac->currentFrame.subframes[1].wastedBitsPerSample);
}
@@ -4089,7 +5114,7 @@ uint64_t drflac_read_s32(drflac* pFlac, uint64_t samplesToRead, int32_t* bufferO
else
{
// Generic interleaving.
- for (uint64_t i = 0; i < alignedSampleCountPerChannel; ++i) {
+ for (drflac_uint64 i = 0; i < alignedSampleCountPerChannel; ++i) {
for (unsigned int j = 0; j < channelCount; ++j) {
bufferOut[(i*channelCount)+j] = (pFlac->currentFrame.subframes[j].pDecodedSamples[firstAlignedSampleInFrame + i]) << (unusedBitsPerSample + pFlac->currentFrame.subframes[j].wastedBitsPerSample);
}
@@ -4098,7 +5123,7 @@ uint64_t drflac_read_s32(drflac* pFlac, uint64_t samplesToRead, int32_t* bufferO
} break;
}
- uint64_t alignedSamplesRead = alignedSampleCountPerChannel * channelCount;
+ drflac_uint64 alignedSamplesRead = alignedSampleCountPerChannel * channelCount;
samplesRead += alignedSamplesRead;
samplesReadFromFrameSoFar += alignedSamplesRead;
bufferOut += alignedSamplesRead;
@@ -4108,9 +5133,8 @@ uint64_t drflac_read_s32(drflac* pFlac, uint64_t samplesToRead, int32_t* bufferO
// At this point we may still have some excess samples left to read.
- if (samplesToRead > 0 && pFlac->currentFrame.samplesRemaining > 0)
- {
- uint64_t excessSamplesRead = 0;
+ if (samplesToRead > 0 && pFlac->currentFrame.samplesRemaining > 0) {
+ drflac_uint64 excessSamplesRead = 0;
if (samplesToRead < pFlac->currentFrame.samplesRemaining) {
excessSamplesRead = drflac__read_s32__misaligned(pFlac, samplesToRead, bufferOut);
} else {
@@ -4128,35 +5152,66 @@ uint64_t drflac_read_s32(drflac* pFlac, uint64_t samplesToRead, int32_t* bufferO
return samplesRead;
}
-uint64_t drflac_read_s16(drflac* pFlac, uint64_t samplesToRead, int16_t* pBufferOut)
+drflac_uint64 drflac_read_s16(drflac* pFlac, drflac_uint64 samplesToRead, drflac_int16* pBufferOut)
{
// This reads samples in 2 passes and can probably be optimized.
- uint64_t samplesRead = 0;
+ drflac_uint64 totalSamplesRead = 0;
while (samplesToRead > 0) {
- int32_t samples32[4096];
- uint64_t samplesJustRead = drflac_read_s32(pFlac, samplesToRead > 4096 ? 4096 : samplesToRead, samples32);
+ drflac_int32 samples32[4096];
+ drflac_uint64 samplesJustRead = drflac_read_s32(pFlac, (samplesToRead > 4096) ? 4096 : samplesToRead, samples32);
if (samplesJustRead == 0) {
break; // Reached the end.
}
// s32 -> s16
- for (uint64_t i = 0; i < samplesJustRead; ++i) {
- pBufferOut[i] = (int16_t)(samples32[i] >> 16);
+ for (drflac_uint64 i = 0; i < samplesJustRead; ++i) {
+ pBufferOut[i] = (drflac_int16)(samples32[i] >> 16);
}
- samplesRead += samplesJustRead;
+ totalSamplesRead += samplesJustRead;
samplesToRead -= samplesJustRead;
pBufferOut += samplesJustRead;
}
- return samplesRead;
+ return totalSamplesRead;
}
-dr_bool32 drflac_seek_to_sample(drflac* pFlac, uint64_t sampleIndex)
+drflac_uint64 drflac_read_f32(drflac* pFlac, drflac_uint64 samplesToRead, float* pBufferOut)
+{
+ // This reads samples in 2 passes and can probably be optimized.
+ drflac_uint64 totalSamplesRead = 0;
+
+ while (samplesToRead > 0) {
+ drflac_int32 samples32[4096];
+ drflac_uint64 samplesJustRead = drflac_read_s32(pFlac, (samplesToRead > 4096) ? 4096 : samplesToRead, samples32);
+ if (samplesJustRead == 0) {
+ break; // Reached the end.
+ }
+
+ // s32 -> f32
+ for (drflac_uint64 i = 0; i < samplesJustRead; ++i) {
+ pBufferOut[i] = (float)(samples32[i] / 2147483648.0);
+ }
+
+ totalSamplesRead += samplesJustRead;
+ samplesToRead -= samplesJustRead;
+ pBufferOut += samplesJustRead;
+ }
+
+ return totalSamplesRead;
+}
+
+drflac_bool32 drflac_seek_to_sample(drflac* pFlac, drflac_uint64 sampleIndex)
{
if (pFlac == NULL) {
- return DR_FALSE;
+ return DRFLAC_FALSE;
+ }
+
+ // If we don't know where the first frame begins then we can't seek. This will happen when the STREAMINFO block was not present
+ // when the decoder was opened.
+ if (pFlac->firstFramePos == 0) {
+ return DRFLAC_FALSE;
}
if (sampleIndex == 0) {
@@ -4186,156 +5241,91 @@ dr_bool32 drflac_seek_to_sample(drflac* pFlac, uint64_t sampleIndex)
}
- return DR_TRUE;
+ return DRFLAC_TRUE;
}
//// High Level APIs ////
-int32_t* drflac__full_decode_and_close_s32(drflac* pFlac, unsigned int* channelsOut, unsigned int* sampleRateOut, uint64_t* totalSampleCountOut)
-{
- assert(pFlac != NULL);
+// I couldn't figure out where SIZE_MAX was defined for VC6. If anybody knows, let me know.
+#if defined(_MSC_VER) && _MSC_VER <= 1200
+#ifdef DRFLAC_64BIT
+#define SIZE_MAX ((drflac_uint64)0xFFFFFFFFFFFFFFFF)
+#else
+#define SIZE_MAX 0xFFFFFFFF
+#endif
+#endif
- int32_t* pSampleData = NULL;
- uint64_t totalSampleCount = pFlac->totalSampleCount;
-
- if (totalSampleCount == 0)
- {
- int32_t buffer[4096];
-
- size_t sampleDataBufferSize = sizeof(buffer);
- pSampleData = (int32_t*)malloc(sampleDataBufferSize);
- if (pSampleData == NULL) {
- goto on_error;
- }
-
- uint64_t samplesRead;
- while ((samplesRead = (uint64_t)drflac_read_s32(pFlac, sizeof(buffer)/sizeof(buffer[0]), buffer)) > 0)
- {
- if (((totalSampleCount + samplesRead) * sizeof(int32_t)) > sampleDataBufferSize) {
- sampleDataBufferSize *= 2;
- int32_t* pNewSampleData = (int32_t*)realloc(pSampleData, sampleDataBufferSize);
- if (pNewSampleData == NULL) {
- free(pSampleData);
- goto on_error;
- }
-
- pSampleData = pNewSampleData;
- }
-
- memcpy(pSampleData + totalSampleCount, buffer, (size_t)(samplesRead*sizeof(int32_t)));
- totalSampleCount += samplesRead;
- }
-
- // At this point everything should be decoded, but we just want to fill the unused part buffer with silence - need to
- // protect those ears from random noise!
- memset(pSampleData + totalSampleCount, 0, (size_t)(sampleDataBufferSize - totalSampleCount*sizeof(int32_t)));
- }
- else
- {
- uint64_t dataSize = totalSampleCount * sizeof(int32_t);
- if (dataSize > SIZE_MAX) {
- goto on_error; // The decoded data is too big.
- }
-
- pSampleData = (int32_t*)malloc((size_t)dataSize); // <-- Safe cast as per the check above.
- if (pSampleData == NULL) {
- goto on_error;
- }
-
- uint64_t samplesDecoded = drflac_read_s32(pFlac, pFlac->totalSampleCount, pSampleData);
- if (samplesDecoded != pFlac->totalSampleCount) {
- free(pSampleData);
- goto on_error; // Something went wrong when decoding the FLAC stream.
- }
- }
-
-
- if (sampleRateOut) *sampleRateOut = pFlac->sampleRate;
- if (channelsOut) *channelsOut = pFlac->channels;
- if (totalSampleCountOut) *totalSampleCountOut = totalSampleCount;
-
- drflac_close(pFlac);
- return pSampleData;
-
-on_error:
- drflac_close(pFlac);
- return NULL;
+// Using a macro as the definition of the drflac__full_decode_and_close_*() API family. Sue me.
+#define DRFLAC_DEFINE_FULL_DECODE_AND_CLOSE(extension, type) \
+static type* drflac__full_decode_and_close_ ## extension (drflac* pFlac, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalSampleCountOut)\
+{ \
+ drflac_assert(pFlac != NULL); \
+ \
+ type* pSampleData = NULL; \
+ drflac_uint64 totalSampleCount = pFlac->totalSampleCount; \
+ \
+ if (totalSampleCount == 0) { \
+ type buffer[4096]; \
+ \
+ size_t sampleDataBufferSize = sizeof(buffer); \
+ pSampleData = (type*)DRFLAC_MALLOC(sampleDataBufferSize); \
+ if (pSampleData == NULL) { \
+ goto on_error; \
+ } \
+ \
+ drflac_uint64 samplesRead; \
+ while ((samplesRead = (drflac_uint64)drflac_read_##extension(pFlac, sizeof(buffer)/sizeof(buffer[0]), buffer)) > 0) { \
+ if (((totalSampleCount + samplesRead) * sizeof(type)) > sampleDataBufferSize) { \
+ sampleDataBufferSize *= 2; \
+ type* pNewSampleData = (type*)DRFLAC_REALLOC(pSampleData, sampleDataBufferSize); \
+ if (pNewSampleData == NULL) { \
+ DRFLAC_FREE(pSampleData); \
+ goto on_error; \
+ } \
+ \
+ pSampleData = pNewSampleData; \
+ } \
+ \
+ drflac_copy_memory(pSampleData + totalSampleCount, buffer, (size_t)(samplesRead*sizeof(type))); \
+ totalSampleCount += samplesRead; \
+ } \
+ \
+ /* At this point everything should be decoded, but we just want to fill the unused part buffer with silence - need to \
+ protect those ears from random noise! */ \
+ drflac_zero_memory(pSampleData + totalSampleCount, (size_t)(sampleDataBufferSize - totalSampleCount*sizeof(type))); \
+ } else { \
+ drflac_uint64 dataSize = totalSampleCount * sizeof(type); \
+ if (dataSize > SIZE_MAX) { \
+ goto on_error; /* The decoded data is too big. */ \
+ } \
+ \
+ pSampleData = (type*)DRFLAC_MALLOC((size_t)dataSize); /* <-- Safe cast as per the check above. */ \
+ if (pSampleData == NULL) { \
+ goto on_error; \
+ } \
+ \
+ totalSampleCount = drflac_read_##extension(pFlac, pFlac->totalSampleCount, pSampleData); \
+ } \
+ \
+ if (sampleRateOut) *sampleRateOut = pFlac->sampleRate; \
+ if (channelsOut) *channelsOut = pFlac->channels; \
+ if (totalSampleCountOut) *totalSampleCountOut = totalSampleCount; \
+ \
+ drflac_close(pFlac); \
+ return pSampleData; \
+ \
+on_error: \
+ drflac_close(pFlac); \
+ return NULL; \
}
-int16_t* drflac__full_decode_and_close_s16(drflac* pFlac, unsigned int* channelsOut, unsigned int* sampleRateOut, uint64_t* totalSampleCountOut)
-{
- assert(pFlac != NULL);
+DRFLAC_DEFINE_FULL_DECODE_AND_CLOSE(s32, drflac_int32)
+DRFLAC_DEFINE_FULL_DECODE_AND_CLOSE(s16, drflac_int16)
+DRFLAC_DEFINE_FULL_DECODE_AND_CLOSE(f32, float)
- int16_t* pSampleData = NULL;
- uint64_t totalSampleCount = pFlac->totalSampleCount;
-
- if (totalSampleCount == 0)
- {
- int16_t buffer[4096];
-
- size_t sampleDataBufferSize = sizeof(buffer);
- pSampleData = (int16_t*)malloc(sampleDataBufferSize);
- if (pSampleData == NULL) {
- goto on_error;
- }
-
- uint64_t samplesRead;
- while ((samplesRead = (uint64_t)drflac_read_s16(pFlac, sizeof(buffer)/sizeof(buffer[0]), buffer)) > 0)
- {
- if (((totalSampleCount + samplesRead) * sizeof(int16_t)) > sampleDataBufferSize) {
- sampleDataBufferSize *= 2;
- int16_t* pNewSampleData = (int16_t*)realloc(pSampleData, sampleDataBufferSize);
- if (pNewSampleData == NULL) {
- free(pSampleData);
- goto on_error;
- }
-
- pSampleData = pNewSampleData;
- }
-
- memcpy(pSampleData + totalSampleCount, buffer, (size_t)(samplesRead*sizeof(int16_t)));
- totalSampleCount += samplesRead;
- }
-
- // At this point everything should be decoded, but we just want to fill the unused part buffer with silence - need to
- // protect those ears from random noise!
- memset(pSampleData + totalSampleCount, 0, (size_t)(sampleDataBufferSize - totalSampleCount*sizeof(int16_t)));
- }
- else
- {
- uint64_t dataSize = totalSampleCount * sizeof(int16_t);
- if (dataSize > SIZE_MAX) {
- goto on_error; // The decoded data is too big.
- }
-
- pSampleData = (int16_t*)malloc((size_t)dataSize); // <-- Safe cast as per the check above.
- if (pSampleData == NULL) {
- goto on_error;
- }
-
- uint64_t samplesDecoded = drflac_read_s16(pFlac, pFlac->totalSampleCount, pSampleData);
- if (samplesDecoded != pFlac->totalSampleCount) {
- free(pSampleData);
- goto on_error; // Something went wrong when decoding the FLAC stream.
- }
- }
-
-
- if (sampleRateOut) *sampleRateOut = pFlac->sampleRate;
- if (channelsOut) *channelsOut = pFlac->channels;
- if (totalSampleCountOut) *totalSampleCountOut = totalSampleCount;
-
- drflac_close(pFlac);
- return pSampleData;
-
-on_error:
- drflac_close(pFlac);
- return NULL;
-}
-
-int32_t* drflac_open_and_decode_s32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount)
+drflac_int32* drflac_open_and_decode_s32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount)
{
// Safety.
if (sampleRate) *sampleRate = 0;
@@ -4350,7 +5340,7 @@ int32_t* drflac_open_and_decode_s32(drflac_read_proc onRead, drflac_seek_proc on
return drflac__full_decode_and_close_s32(pFlac, channels, sampleRate, totalSampleCount);
}
-int16_t* drflac_open_and_decode_s16(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount)
+drflac_int16* drflac_open_and_decode_s16(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount)
{
// Safety.
if (sampleRate) *sampleRate = 0;
@@ -4365,8 +5355,23 @@ int16_t* drflac_open_and_decode_s16(drflac_read_proc onRead, drflac_seek_proc on
return drflac__full_decode_and_close_s16(pFlac, channels, sampleRate, totalSampleCount);
}
+float* drflac_open_and_decode_f32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount)
+{
+ // Safety.
+ if (sampleRate) *sampleRate = 0;
+ if (channels) *channels = 0;
+ if (totalSampleCount) *totalSampleCount = 0;
+
+ drflac* pFlac = drflac_open(onRead, onSeek, pUserData);
+ if (pFlac == NULL) {
+ return NULL;
+ }
+
+ return drflac__full_decode_and_close_f32(pFlac, channels, sampleRate, totalSampleCount);
+}
+
#ifndef DR_FLAC_NO_STDIO
-int32_t* drflac_open_and_decode_file_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount)
+drflac_int32* drflac_open_and_decode_file_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount)
{
if (sampleRate) *sampleRate = 0;
if (channels) *channels = 0;
@@ -4380,7 +5385,7 @@ int32_t* drflac_open_and_decode_file_s32(const char* filename, unsigned int* cha
return drflac__full_decode_and_close_s32(pFlac, channels, sampleRate, totalSampleCount);
}
-int16_t* drflac_open_and_decode_file_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount)
+drflac_int16* drflac_open_and_decode_file_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount)
{
if (sampleRate) *sampleRate = 0;
if (channels) *channels = 0;
@@ -4393,9 +5398,23 @@ int16_t* drflac_open_and_decode_file_s16(const char* filename, unsigned int* cha
return drflac__full_decode_and_close_s16(pFlac, channels, sampleRate, totalSampleCount);
}
+
+float* drflac_open_and_decode_file_f32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount)
+{
+ if (sampleRate) *sampleRate = 0;
+ if (channels) *channels = 0;
+ if (totalSampleCount) *totalSampleCount = 0;
+
+ drflac* pFlac = drflac_open_file(filename);
+ if (pFlac == NULL) {
+ return NULL;
+ }
+
+ return drflac__full_decode_and_close_f32(pFlac, channels, sampleRate, totalSampleCount);
+}
#endif
-int32_t* drflac_open_and_decode_memory_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount)
+drflac_int32* drflac_open_and_decode_memory_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount)
{
if (sampleRate) *sampleRate = 0;
if (channels) *channels = 0;
@@ -4409,7 +5428,7 @@ int32_t* drflac_open_and_decode_memory_s32(const void* data, size_t dataSize, un
return drflac__full_decode_and_close_s32(pFlac, channels, sampleRate, totalSampleCount);
}
-int16_t* drflac_open_and_decode_memory_s16(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount)
+drflac_int16* drflac_open_and_decode_memory_s16(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount)
{
if (sampleRate) *sampleRate = 0;
if (channels) *channels = 0;
@@ -4423,15 +5442,29 @@ int16_t* drflac_open_and_decode_memory_s16(const void* data, size_t dataSize, un
return drflac__full_decode_and_close_s16(pFlac, channels, sampleRate, totalSampleCount);
}
+float* drflac_open_and_decode_memory_f32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount)
+{
+ if (sampleRate) *sampleRate = 0;
+ if (channels) *channels = 0;
+ if (totalSampleCount) *totalSampleCount = 0;
+
+ drflac* pFlac = drflac_open_memory(data, dataSize);
+ if (pFlac == NULL) {
+ return NULL;
+ }
+
+ return drflac__full_decode_and_close_f32(pFlac, channels, sampleRate, totalSampleCount);
+}
+
void drflac_free(void* pSampleDataReturnedByOpenAndDecode)
{
- free(pSampleDataReturnedByOpenAndDecode);
+ DRFLAC_FREE(pSampleDataReturnedByOpenAndDecode);
}
-void drflac_init_vorbis_comment_iterator(drflac_vorbis_comment_iterator* pIter, uint32_t commentCount, const char* pComments)
+void drflac_init_vorbis_comment_iterator(drflac_vorbis_comment_iterator* pIter, drflac_uint32 commentCount, const char* pComments)
{
if (pIter == NULL) {
return;
@@ -4441,7 +5474,7 @@ void drflac_init_vorbis_comment_iterator(drflac_vorbis_comment_iterator* pIter,
pIter->pRunningData = pComments;
}
-const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, uint32_t* pCommentLengthOut)
+const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, drflac_uint32* pCommentLengthOut)
{
// Safety.
if (pCommentLengthOut) *pCommentLengthOut = 0;
@@ -4450,7 +5483,7 @@ const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, ui
return NULL;
}
- uint32_t length = drflac__le2host_32(*(uint32_t*)pIter->pRunningData);
+ drflac_uint32 length = drflac__le2host_32(*(drflac_uint32*)pIter->pRunningData);
pIter->pRunningData += 4;
const char* pComment = pIter->pRunningData;
@@ -4465,20 +5498,63 @@ const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, ui
// REVISION HISTORY
//
+// v0.8d - 2017-09-22
+// - Add support for decoding streams with ID3 tags. ID3 tags are just skipped.
+//
+// v0.8c - 2017-09-07
+// - Fix warning on non-x86/x64 architectures.
+//
+// v0.8b - 2017-08-19
+// - Fix build on non-x86/x64 architectures.
+//
+// v0.8a - 2017-08-13
+// - A small optimization for the Clang build.
+//
+// v0.8 - 2017-08-12
+// - API CHANGE: Rename dr_* types to drflac_*.
+// - Optimizations. This brings dr_flac back to about the same class of efficiency as the reference implementation.
+// - Add support for custom implementations of malloc(), realloc(), etc.
+// - Add CRC checking to Ogg encapsulated streams.
+// - Fix VC++ 6 build. This is only for the C++ compiler. The C compiler is not currently supported.
+// - Bug fixes.
+//
+// v0.7 - 2017-07-23
+// - Add support for opening a stream without a header block. To do this, use drflac_open_relaxed() / drflac_open_with_metadata_relaxed().
+//
+// v0.6 - 2017-07-22
+// - Add support for recovering from invalid frames. With this change, dr_flac will simply skip over invalid frames as if they
+// never existed. Frames are checked against their sync code, the CRC-8 of the frame header and the CRC-16 of the whole frame.
+//
+// v0.5 - 2017-07-16
+// - Fix typos.
+// - Change drflac_bool* types to unsigned.
+// - Add CRC checking. This makes dr_flac slower, but can be disabled with #define DR_FLAC_NO_CRC.
+//
+// v0.4f - 2017-03-10
+// - Fix a couple of bugs with the bitstreaming code.
+//
+// v0.4e - 2017-02-17
+// - Fix some warnings.
+//
+// v0.4d - 2016-12-26
+// - Add support for 32-bit floating-point PCM decoding.
+// - Use drflac_int*/drflac_uint* sized types to improve compiler support.
+// - Minor improvements to documentation.
+//
// v0.4c - 2016-12-26
// - Add support for signed 16-bit integer PCM decoding.
//
// v0.4b - 2016-10-23
-// - A minor change to dr_bool8 and dr_bool32 types.
+// - A minor change to drflac_bool8 and drflac_bool32 types.
//
// v0.4a - 2016-10-11
-// - Rename drBool32 to dr_bool32 for styling consistency.
+// - Rename drBool32 to drflac_bool32 for styling consistency.
//
// v0.4 - 2016-09-29
// - API/ABI CHANGE: Use fixed size 32-bit booleans instead of the built-in bool type.
-// - API CHANGE: Rename drflac_open_and_decode*() to drflac_open_and_decode*_s32()
+// - API CHANGE: Rename drflac_open_and_decode*() to drflac_open_and_decode*_s32().
// - API CHANGE: Swap the order of "channels" and "sampleRate" parameters in drflac_open_and_decode*(). Rationale for this is to
-// keep it consistent with dr_audio.
+// keep it consistent with drflac_audio.
//
// v0.3f - 2016-09-21
// - Fix a warning with GCC.
@@ -4531,11 +5607,6 @@ const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, ui
// - Initial versioned release.
-// TODO
-// - Add support for initializing the decoder without a header STREAMINFO block.
-// - Test CUESHEET metadata blocks.
-
-
/*
This is free and unencumbered software released into the public domain.
diff --git a/src/external/dr_wav.h b/src/external/dr_wav.h
new file mode 100644
index 000000000..536df8f3f
--- /dev/null
+++ b/src/external/dr_wav.h
@@ -0,0 +1,3455 @@
+// WAV audio loader and writer. Public domain. See "unlicense" statement at the end of this file.
+// dr_wav - v0.7a - 2017-11-17
+//
+// David Reid - mackron@gmail.com
+
+// USAGE
+//
+// This is a single-file library. To use it, do something like the following in one .c file.
+// #define DR_WAV_IMPLEMENTATION
+// #include "dr_wav.h"
+//
+// You can then #include this file in other parts of the program as you would with any other header file. Do something
+// like the following to read audio data:
+//
+// drwav wav;
+// if (!drwav_init_file(&wav, "my_song.wav")) {
+// // Error opening WAV file.
+// }
+//
+// drwav_int32* pDecodedInterleavedSamples = malloc(wav.totalSampleCount * sizeof(drwav_int32));
+// size_t numberOfSamplesActuallyDecoded = drwav_read_s32(&wav, wav.totalSampleCount, pDecodedInterleavedSamples);
+//
+// ...
+//
+// drwav_uninit(&wav);
+//
+// You can also use drwav_open() to allocate and initialize the loader for you:
+//
+// drwav* pWav = drwav_open_file("my_song.wav");
+// if (pWav == NULL) {
+// // Error opening WAV file.
+// }
+//
+// ...
+//
+// drwav_close(pWav);
+//
+// If you just want to quickly open and read the audio data in a single operation you can do something like this:
+//
+// unsigned int channels;
+// unsigned int sampleRate;
+// drwav_uint64 totalSampleCount;
+// float* pSampleData = drwav_open_and_read_file_s32("my_song.wav", &channels, &sampleRate, &totalSampleCount);
+// if (pSampleData == NULL) {
+// // Error opening and reading WAV file.
+// }
+//
+// ...
+//
+// drwav_free(pSampleData);
+//
+// The examples above use versions of the API that convert the audio data to a consistent format (32-bit signed PCM, in
+// this case), but you can still output the audio data in it's internal format (see notes below for supported formats):
+//
+// size_t samplesRead = drwav_read(&wav, wav.totalSampleCount, pDecodedInterleavedSamples);
+//
+// You can also read the raw bytes of audio data, which could be useful if dr_wav does not have native support for
+// a particular data format:
+//
+// size_t bytesRead = drwav_read_raw(&wav, bytesToRead, pRawDataBuffer);
+//
+//
+// dr_wav has seamless support the Sony Wave64 format. The decoder will automatically detect it and it should Just Work
+// without any manual intervention.
+//
+//
+// dr_wav can also be used to output WAV files. This does not currently support compressed formats. To use this, look at
+// drwav_open_write(), drwav_open_file_write(), etc. Use drwav_write() to write samples, or drwav_write_raw() to write
+// raw data in the "data" chunk.
+//
+// drwav_data_format format;
+// format.container = drwav_container_riff; // <-- drwav_container_riff = normal WAV files, drwav_container_w64 = Sony Wave64.
+// format.format = DR_WAVE_FORMAT_PCM; // <-- Any of the DR_WAVE_FORMAT_* codes.
+// format.channels = 2;
+// format.sampleRate = 44100;
+// format.bitsPerSample = 16;
+// drwav* pWav = drwav_open_file_write("data/recording.wav", &format);
+//
+// ...
+//
+// drwav_uint64 samplesWritten = drwav_write(pWav, sampleCount, pSamples);
+//
+//
+//
+// OPTIONS
+// #define these options before including this file.
+//
+// #define DR_WAV_NO_CONVERSION_API
+// Disables conversion APIs such as drwav_read_f32() and drwav_s16_to_f32().
+//
+// #define DR_WAV_NO_STDIO
+// Disables drwav_open_file(), drwav_open_file_write(), etc.
+//
+//
+//
+// QUICK NOTES
+// - Samples are always interleaved.
+// - The default read function does not do any data conversion. Use drwav_read_f32() to read and convert audio data
+// to IEEE 32-bit floating point samples, drwav_read_s32() to read samples as signed 32-bit PCM and drwav_read_s16()
+// to read samples as signed 16-bit PCM. Tested and supported internal formats include the following:
+// - Unsigned 8-bit PCM
+// - Signed 12-bit PCM
+// - Signed 16-bit PCM
+// - Signed 24-bit PCM
+// - Signed 32-bit PCM
+// - IEEE 32-bit floating point.
+// - IEEE 64-bit floating point.
+// - A-law and u-law
+// - Microsoft ADPCM
+// - IMA ADPCM (DVI, format code 0x11)
+// - dr_wav will try to read the WAV file as best it can, even if it's not strictly conformant to the WAV format.
+
+
+#ifndef dr_wav_h
+#define dr_wav_h
+
+#include
+
+#if defined(_MSC_VER) && _MSC_VER < 1600
+typedef signed char drwav_int8;
+typedef unsigned char drwav_uint8;
+typedef signed short drwav_int16;
+typedef unsigned short drwav_uint16;
+typedef signed int drwav_int32;
+typedef unsigned int drwav_uint32;
+typedef signed __int64 drwav_int64;
+typedef unsigned __int64 drwav_uint64;
+#else
+#include
+typedef int8_t drwav_int8;
+typedef uint8_t drwav_uint8;
+typedef int16_t drwav_int16;
+typedef uint16_t drwav_uint16;
+typedef int32_t drwav_int32;
+typedef uint32_t drwav_uint32;
+typedef int64_t drwav_int64;
+typedef uint64_t drwav_uint64;
+#endif
+typedef drwav_uint8 drwav_bool8;
+typedef drwav_uint32 drwav_bool32;
+#define DRWAV_TRUE 1
+#define DRWAV_FALSE 0
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Common data formats.
+#define DR_WAVE_FORMAT_PCM 0x1
+#define DR_WAVE_FORMAT_ADPCM 0x2
+#define DR_WAVE_FORMAT_IEEE_FLOAT 0x3
+#define DR_WAVE_FORMAT_ALAW 0x6
+#define DR_WAVE_FORMAT_MULAW 0x7
+#define DR_WAVE_FORMAT_DVI_ADPCM 0x11
+#define DR_WAVE_FORMAT_EXTENSIBLE 0xFFFE
+
+typedef enum
+{
+ drwav_seek_origin_start,
+ drwav_seek_origin_current
+} drwav_seek_origin;
+
+typedef enum
+{
+ drwav_container_riff,
+ drwav_container_w64
+} drwav_container;
+
+// Callback for when data is read. Return value is the number of bytes actually read.
+//
+// pUserData [in] The user data that was passed to drwav_init(), drwav_open() and family.
+// pBufferOut [out] The output buffer.
+// bytesToRead [in] The number of bytes to read.
+//
+// Returns the number of bytes actually read.
+//
+// A return value of less than bytesToRead indicates the end of the stream. Do _not_ return from this callback until
+// either the entire bytesToRead is filled or you have reached the end of the stream.
+typedef size_t (* drwav_read_proc)(void* pUserData, void* pBufferOut, size_t bytesToRead);
+
+// Callback for when data is written. Returns value is the number of bytes actually written.
+//
+// pUserData [in] The user data that was passed to drwav_init_write(), drwav_open_write() and family.
+// pData [out] A pointer to the data to write.
+// bytesToWrite [in] The number of bytes to write.
+//
+// Returns the number of bytes actually written.
+//
+// If the return value differs from bytesToWrite, it indicates an error.
+typedef size_t (* drwav_write_proc)(void* pUserData, const void* pData, size_t bytesToWrite);
+
+// Callback for when data needs to be seeked.
+//
+// pUserData [in] The user data that was passed to drwav_init(), drwav_open() and family.
+// offset [in] The number of bytes to move, relative to the origin. Will never be negative.
+// origin [in] The origin of the seek - the current position or the start of the stream.
+//
+// Returns whether or not the seek was successful.
+//
+// Whether or not it is relative to the beginning or current position is determined by the "origin" parameter which
+// will be either drwav_seek_origin_start or drwav_seek_origin_current.
+typedef drwav_bool32 (* drwav_seek_proc)(void* pUserData, int offset, drwav_seek_origin origin);
+
+// Structure for internal use. Only used for loaders opened with drwav_open_memory().
+typedef struct
+{
+ const drwav_uint8* data;
+ size_t dataSize;
+ size_t currentReadPos;
+} drwav__memory_stream;
+
+// Structure for internal use. Only used for writers opened with drwav_open_memory_write().
+typedef struct
+{
+ void** ppData;
+ size_t* pDataSize;
+ size_t dataSize;
+ size_t dataCapacity;
+ size_t currentWritePos;
+} drwav__memory_stream_write;
+
+typedef struct
+{
+ drwav_container container; // RIFF, W64.
+ drwav_uint32 format; // DR_WAVE_FORMAT_*
+ drwav_uint32 channels;
+ drwav_uint32 sampleRate;
+ drwav_uint32 bitsPerSample;
+} drwav_data_format;
+
+typedef struct
+{
+ // The format tag exactly as specified in the wave file's "fmt" chunk. This can be used by applications
+ // that require support for data formats not natively supported by dr_wav.
+ drwav_uint16 formatTag;
+
+ // The number of channels making up the audio data. When this is set to 1 it is mono, 2 is stereo, etc.
+ drwav_uint16 channels;
+
+ // The sample rate. Usually set to something like 44100.
+ drwav_uint32 sampleRate;
+
+ // Average bytes per second. You probably don't need this, but it's left here for informational purposes.
+ drwav_uint32 avgBytesPerSec;
+
+ // Block align. This is equal to the number of channels * bytes per sample.
+ drwav_uint16 blockAlign;
+
+ // Bit's per sample.
+ drwav_uint16 bitsPerSample;
+
+ // The size of the extended data. Only used internally for validation, but left here for informational purposes.
+ drwav_uint16 extendedSize;
+
+ // The number of valid bits per sample. When is equal to WAVE_FORMAT_EXTENSIBLE,
+ // is always rounded up to the nearest multiple of 8. This variable contains information about exactly how
+ // many bits a valid per sample. Mainly used for informational purposes.
+ drwav_uint16 validBitsPerSample;
+
+ // The channel mask. Not used at the moment.
+ drwav_uint32 channelMask;
+
+ // The sub-format, exactly as specified by the wave file.
+ drwav_uint8 subFormat[16];
+} drwav_fmt;
+
+typedef struct
+{
+ // A pointer to the function to call when more data is needed.
+ drwav_read_proc onRead;
+
+ // A pointer to the function to call when data needs to be written. Only used when the drwav object is opened in write mode.
+ drwav_write_proc onWrite;
+
+ // A pointer to the function to call when the wav file needs to be seeked.
+ drwav_seek_proc onSeek;
+
+ // The user data to pass to callbacks.
+ void* pUserData;
+
+
+ // Whether or not the WAV file is formatted as a standard RIFF file or W64.
+ drwav_container container;
+
+
+ // Structure containing format information exactly as specified by the wav file.
+ drwav_fmt fmt;
+
+ // The sample rate. Will be set to something like 44100.
+ drwav_uint32 sampleRate;
+
+ // The number of channels. This will be set to 1 for monaural streams, 2 for stereo, etc.
+ drwav_uint16 channels;
+
+ // The bits per sample. Will be set to somthing like 16, 24, etc.
+ drwav_uint16 bitsPerSample;
+
+ // The number of bytes per sample.
+ drwav_uint16 bytesPerSample;
+
+ // Equal to fmt.formatTag, or the value specified by fmt.subFormat if fmt.formatTag is equal to 65534 (WAVE_FORMAT_EXTENSIBLE).
+ drwav_uint16 translatedFormatTag;
+
+ // The total number of samples making up the audio data. Use * to calculate
+ // the required size of a buffer to hold the entire audio data.
+ drwav_uint64 totalSampleCount;
+
+
+ // The size in bytes of the data chunk.
+ drwav_uint64 dataChunkDataSize;
+
+ // The position in the stream of the first byte of the data chunk. This is used for seeking.
+ drwav_uint64 dataChunkDataPos;
+
+ // The number of bytes remaining in the data chunk.
+ drwav_uint64 bytesRemaining;
+
+
+ // A hack to avoid a DRWAV_MALLOC() when opening a decoder with drwav_open_memory().
+ drwav__memory_stream memoryStream;
+ drwav__memory_stream_write memoryStreamWrite;
+
+ // Generic data for compressed formats. This data is shared across all block-compressed formats.
+ struct
+ {
+ drwav_uint64 iCurrentSample; // The index of the next sample that will be read by drwav_read_*(). This is used with "totalSampleCount" to ensure we don't read excess samples at the end of the last block.
+ } compressed;
+
+ // Microsoft ADPCM specific data.
+ struct
+ {
+ drwav_uint32 bytesRemainingInBlock;
+ drwav_uint16 predictor[2];
+ drwav_int32 delta[2];
+ drwav_int32 cachedSamples[4]; // Samples are stored in this cache during decoding.
+ drwav_uint32 cachedSampleCount;
+ drwav_int32 prevSamples[2][2]; // The previous 2 samples for each channel (2 channels at most).
+ } msadpcm;
+
+ // IMA ADPCM specific data.
+ struct
+ {
+ drwav_uint32 bytesRemainingInBlock;
+ drwav_int32 predictor[2];
+ drwav_int32 stepIndex[2];
+ drwav_int32 cachedSamples[16]; // Samples are stored in this cache during decoding.
+ drwav_uint32 cachedSampleCount;
+ } ima;
+} drwav;
+
+
+// Initializes a pre-allocated drwav object.
+//
+// onRead [in] The function to call when data needs to be read from the client.
+// onSeek [in] The function to call when the read position of the client data needs to move.
+// pUserData [in, optional] A pointer to application defined data that will be passed to onRead and onSeek.
+//
+// Returns true if successful; false otherwise.
+//
+// Close the loader with drwav_uninit().
+//
+// This is the lowest level function for initializing a WAV file. You can also use drwav_init_file() and drwav_init_memory()
+// to open the stream from a file or from a block of memory respectively.
+//
+// If you want dr_wav to manage the memory allocation for you, consider using drwav_open() instead. This will allocate
+// a drwav object on the heap and return a pointer to it.
+//
+// See also: drwav_init_file(), drwav_init_memory(), drwav_uninit()
+drwav_bool32 drwav_init(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData);
+
+// Initializes a pre-allocated drwav object for writing.
+//
+// onWrite [in] The function to call when data needs to be written.
+// onSeek [in] The function to call when the write position needs to move.
+// pUserData [in, optional] A pointer to application defined data that will be passed to onWrite and onSeek.
+//
+// Returns true if successful; false otherwise.
+//
+// Close the writer with drwav_uninit().
+//
+// This is the lowest level function for initializing a WAV file. You can also use drwav_init_file() and drwav_init_memory()
+// to open the stream from a file or from a block of memory respectively.
+//
+// If you want dr_wav to manage the memory allocation for you, consider using drwav_open() instead. This will allocate
+// a drwav object on the heap and return a pointer to it.
+//
+// See also: drwav_init_file_write(), drwav_init_memory_write(), drwav_uninit()
+drwav_bool32 drwav_init_write(drwav* pWav, const drwav_data_format* pFormat, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData);
+
+// Uninitializes the given drwav object.
+//
+// Use this only for objects initialized with drwav_init().
+void drwav_uninit(drwav* pWav);
+
+
+// Opens a wav file using the given callbacks.
+//
+// onRead [in] The function to call when data needs to be read from the client.
+// onSeek [in] The function to call when the read position of the client data needs to move.
+// pUserData [in, optional] A pointer to application defined data that will be passed to onRead and onSeek.
+//
+// Returns null on error.
+//
+// Close the loader with drwav_close().
+//
+// This is the lowest level function for opening a WAV file. You can also use drwav_open_file() and drwav_open_memory()
+// to open the stream from a file or from a block of memory respectively.
+//
+// This is different from drwav_init() in that it will allocate the drwav object for you via DRWAV_MALLOC() before
+// initializing it.
+//
+// See also: drwav_open_file(), drwav_open_memory(), drwav_close()
+drwav* drwav_open(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData);
+
+// Opens a wav file for writing using the given callbacks.
+//
+// onWrite [in] The function to call when data needs to be written.
+// onSeek [in] The function to call when the write position needs to move.
+// pUserData [in, optional] A pointer to application defined data that will be passed to onWrite and onSeek.
+//
+// Returns null on error.
+//
+// Close the loader with drwav_close().
+//
+// This is the lowest level function for opening a WAV file. You can also use drwav_open_file_write() and drwav_open_memory_write()
+// to open the stream from a file or from a block of memory respectively.
+//
+// This is different from drwav_init_write() in that it will allocate the drwav object for you via DRWAV_MALLOC() before
+// initializing it.
+//
+// See also: drwav_open_file_write(), drwav_open_memory_write(), drwav_close()
+drwav* drwav_open_write(const drwav_data_format* pFormat, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData);
+
+// Uninitializes and deletes the the given drwav object.
+//
+// Use this only for objects created with drwav_open().
+void drwav_close(drwav* pWav);
+
+
+// Reads raw audio data.
+//
+// This is the lowest level function for reading audio data. It simply reads the given number of
+// bytes of the raw internal sample data.
+//
+// Consider using drwav_read_s16(), drwav_read_s32() or drwav_read_f32() for reading sample data in
+// a consistent format.
+//
+// Returns the number of bytes actually read.
+size_t drwav_read_raw(drwav* pWav, size_t bytesToRead, void* pBufferOut);
+
+// Reads a chunk of audio data in the native internal format.
+//
+// This is typically the most efficient way to retrieve audio data, but it does not do any format
+// conversions which means you'll need to convert the data manually if required.
+//
+// If the return value is less than it means the end of the file has been reached or
+// you have requested more samples than can possibly fit in the output buffer.
+//
+// This function will only work when sample data is of a fixed size and uncompressed. If you are
+// using a compressed format consider using drwav_read_raw() or drwav_read_s16/s32/f32/etc().
+drwav_uint64 drwav_read(drwav* pWav, drwav_uint64 samplesToRead, void* pBufferOut);
+
+// Seeks to the given sample.
+//
+// Returns true if successful; false otherwise.
+drwav_bool32 drwav_seek_to_sample(drwav* pWav, drwav_uint64 sample);
+
+
+// Writes raw audio data.
+//
+// Returns the number of bytes actually written. If this differs from bytesToWrite, it indicates an error.
+size_t drwav_write_raw(drwav* pWav, size_t bytesToWrite, const void* pData);
+
+// Writes audio data based on sample counts.
+//
+// Returns the number of samples written.
+drwav_uint64 drwav_write(drwav* pWav, drwav_uint64 samplesToWrite, const void* pData);
+
+
+
+//// Convertion Utilities ////
+#ifndef DR_WAV_NO_CONVERSION_API
+
+// Reads a chunk of audio data and converts it to signed 16-bit PCM samples.
+//
+// Returns the number of samples actually read.
+//
+// If the return value is less than it means the end of the file has been reached.
+drwav_uint64 drwav_read_s16(drwav* pWav, drwav_uint64 samplesToRead, drwav_int16* pBufferOut);
+
+// Low-level function for converting unsigned 8-bit PCM samples to signed 16-bit PCM samples.
+void drwav_u8_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount);
+
+// Low-level function for converting signed 24-bit PCM samples to signed 16-bit PCM samples.
+void drwav_s24_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount);
+
+// Low-level function for converting signed 32-bit PCM samples to signed 16-bit PCM samples.
+void drwav_s32_to_s16(drwav_int16* pOut, const drwav_int32* pIn, size_t sampleCount);
+
+// Low-level function for converting IEEE 32-bit floating point samples to signed 16-bit PCM samples.
+void drwav_f32_to_s16(drwav_int16* pOut, const float* pIn, size_t sampleCount);
+
+// Low-level function for converting IEEE 64-bit floating point samples to signed 16-bit PCM samples.
+void drwav_f64_to_s16(drwav_int16* pOut, const double* pIn, size_t sampleCount);
+
+// Low-level function for converting A-law samples to signed 16-bit PCM samples.
+void drwav_alaw_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount);
+
+// Low-level function for converting u-law samples to signed 16-bit PCM samples.
+void drwav_mulaw_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount);
+
+
+// Reads a chunk of audio data and converts it to IEEE 32-bit floating point samples.
+//
+// Returns the number of samples actually read.
+//
+// If the return value is less than it means the end of the file has been reached.
+drwav_uint64 drwav_read_f32(drwav* pWav, drwav_uint64 samplesToRead, float* pBufferOut);
+
+// Low-level function for converting unsigned 8-bit PCM samples to IEEE 32-bit floating point samples.
+void drwav_u8_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount);
+
+// Low-level function for converting signed 16-bit PCM samples to IEEE 32-bit floating point samples.
+void drwav_s16_to_f32(float* pOut, const drwav_int16* pIn, size_t sampleCount);
+
+// Low-level function for converting signed 24-bit PCM samples to IEEE 32-bit floating point samples.
+void drwav_s24_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount);
+
+// Low-level function for converting signed 32-bit PCM samples to IEEE 32-bit floating point samples.
+void drwav_s32_to_f32(float* pOut, const drwav_int32* pIn, size_t sampleCount);
+
+// Low-level function for converting IEEE 64-bit floating point samples to IEEE 32-bit floating point samples.
+void drwav_f64_to_f32(float* pOut, const double* pIn, size_t sampleCount);
+
+// Low-level function for converting A-law samples to IEEE 32-bit floating point samples.
+void drwav_alaw_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount);
+
+// Low-level function for converting u-law samples to IEEE 32-bit floating point samples.
+void drwav_mulaw_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount);
+
+
+// Reads a chunk of audio data and converts it to signed 32-bit PCM samples.
+//
+// Returns the number of samples actually read.
+//
+// If the return value is less than it means the end of the file has been reached.
+drwav_uint64 drwav_read_s32(drwav* pWav, drwav_uint64 samplesToRead, drwav_int32* pBufferOut);
+
+// Low-level function for converting unsigned 8-bit PCM samples to signed 32-bit PCM samples.
+void drwav_u8_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount);
+
+// Low-level function for converting signed 16-bit PCM samples to signed 32-bit PCM samples.
+void drwav_s16_to_s32(drwav_int32* pOut, const drwav_int16* pIn, size_t sampleCount);
+
+// Low-level function for converting signed 24-bit PCM samples to signed 32-bit PCM samples.
+void drwav_s24_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount);
+
+// Low-level function for converting IEEE 32-bit floating point samples to signed 32-bit PCM samples.
+void drwav_f32_to_s32(drwav_int32* pOut, const float* pIn, size_t sampleCount);
+
+// Low-level function for converting IEEE 64-bit floating point samples to signed 32-bit PCM samples.
+void drwav_f64_to_s32(drwav_int32* pOut, const double* pIn, size_t sampleCount);
+
+// Low-level function for converting A-law samples to signed 32-bit PCM samples.
+void drwav_alaw_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount);
+
+// Low-level function for converting u-law samples to signed 32-bit PCM samples.
+void drwav_mulaw_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount);
+
+#endif //DR_WAV_NO_CONVERSION_API
+
+
+//// High-Level Convenience Helpers ////
+
+#ifndef DR_WAV_NO_STDIO
+
+// Helper for initializing a wave file using stdio.
+//
+// This holds the internal FILE object until drwav_uninit() is called. Keep this in mind if you're caching drwav
+// objects because the operating system may restrict the number of file handles an application can have open at
+// any given time.
+drwav_bool32 drwav_init_file(drwav* pWav, const char* filename);
+
+// Helper for initializing a wave file for writing using stdio.
+//
+// This holds the internal FILE object until drwav_uninit() is called. Keep this in mind if you're caching drwav
+// objects because the operating system may restrict the number of file handles an application can have open at
+// any given time.
+drwav_bool32 drwav_init_file_write(drwav* pWav, const char* filename, const drwav_data_format* pFormat);
+
+// Helper for opening a wave file using stdio.
+//
+// This holds the internal FILE object until drwav_close() is called. Keep this in mind if you're caching drwav
+// objects because the operating system may restrict the number of file handles an application can have open at
+// any given time.
+drwav* drwav_open_file(const char* filename);
+
+// Helper for opening a wave file for writing using stdio.
+//
+// This holds the internal FILE object until drwav_close() is called. Keep this in mind if you're caching drwav
+// objects because the operating system may restrict the number of file handles an application can have open at
+// any given time.
+drwav* drwav_open_file_write(const char* filename, const drwav_data_format* pFormat);
+
+#endif //DR_WAV_NO_STDIO
+
+// Helper for initializing a loader from a pre-allocated memory buffer.
+//
+// This does not create a copy of the data. It is up to the application to ensure the buffer remains valid for
+// the lifetime of the drwav object.
+//
+// The buffer should contain the contents of the entire wave file, not just the sample data.
+drwav_bool32 drwav_init_memory(drwav* pWav, const void* data, size_t dataSize);
+
+// Helper for initializing a writer which outputs data to a memory buffer.
+//
+// dr_wav will manage the memory allocations, however it is up to the caller to free the data with drwav_free().
+//
+// The buffer will remain allocated even after drwav_uninit() is called. Indeed, the buffer should not be
+// considered valid until after drwav_uninit() has been called anyway.
+drwav_bool32 drwav_init_memory_write(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat);
+
+// Helper for opening a loader from a pre-allocated memory buffer.
+//
+// This does not create a copy of the data. It is up to the application to ensure the buffer remains valid for
+// the lifetime of the drwav object.
+//
+// The buffer should contain the contents of the entire wave file, not just the sample data.
+drwav* drwav_open_memory(const void* data, size_t dataSize);
+
+// Helper for opening a writer which outputs data to a memory buffer.
+//
+// dr_wav will manage the memory allocations, however it is up to the caller to free the data with drwav_free().
+//
+// The buffer will remain allocated even after drwav_close() is called. Indeed, the buffer should not be
+// considered valid until after drwav_close() has been called anyway.
+drwav* drwav_open_memory_write(void** ppData, size_t* pDataSize, const drwav_data_format* pFormat);
+
+
+#ifndef DR_WAV_NO_CONVERSION_API
+// Opens and reads a wav file in a single operation.
+drwav_int16* drwav_open_and_read_s16(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalSampleCount);
+float* drwav_open_and_read_f32(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalSampleCount);
+drwav_int32* drwav_open_and_read_s32(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalSampleCount);
+#ifndef DR_WAV_NO_STDIO
+// Opens an decodes a wav file in a single operation.
+drwav_int16* drwav_open_and_read_file_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalSampleCount);
+float* drwav_open_and_read_file_f32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalSampleCount);
+drwav_int32* drwav_open_and_read_file_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalSampleCount);
+#endif
+
+// Opens an decodes a wav file from a block of memory in a single operation.
+drwav_int16* drwav_open_and_read_memory_s16(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalSampleCount);
+float* drwav_open_and_read_memory_f32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalSampleCount);
+drwav_int32* drwav_open_and_read_memory_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalSampleCount);
+#endif
+
+// Frees data that was allocated internally by dr_wav.
+void drwav_free(void* pDataReturnedByOpenAndRead);
+
+#ifdef __cplusplus
+}
+#endif
+#endif // dr_wav_h
+
+
+/////////////////////////////////////////////////////
+//
+// IMPLEMENTATION
+//
+/////////////////////////////////////////////////////
+
+#ifdef DR_WAV_IMPLEMENTATION
+#include
+#include // For memcpy(), memset()
+#include // For INT_MAX
+
+#ifndef DR_WAV_NO_STDIO
+#include
+#endif
+
+// Standard library stuff.
+#ifndef DRWAV_ASSERT
+#include
+#define DRWAV_ASSERT(expression) assert(expression)
+#endif
+#ifndef DRWAV_MALLOC
+#define DRWAV_MALLOC(sz) malloc((sz))
+#endif
+#ifndef DRWAV_REALLOC
+#define DRWAV_REALLOC(p, sz) realloc((p), (sz))
+#endif
+#ifndef DRWAV_FREE
+#define DRWAV_FREE(p) free((p))
+#endif
+#ifndef DRWAV_COPY_MEMORY
+#define DRWAV_COPY_MEMORY(dst, src, sz) memcpy((dst), (src), (sz))
+#endif
+#ifndef DRWAV_ZERO_MEMORY
+#define DRWAV_ZERO_MEMORY(p, sz) memset((p), 0, (sz))
+#endif
+
+#define drwav_countof(x) (sizeof(x) / sizeof(x[0]))
+#define drwav_align(x, a) ((((x) + (a) - 1) / (a)) * (a))
+#define drwav_min(a, b) (((a) < (b)) ? (a) : (b))
+#define drwav_max(a, b) (((a) > (b)) ? (a) : (b))
+#define drwav_clamp(x, lo, hi) (drwav_max((lo), drwav_min((hi), (x))))
+
+#define drwav_assert DRWAV_ASSERT
+#define drwav_copy_memory DRWAV_COPY_MEMORY
+#define drwav_zero_memory DRWAV_ZERO_MEMORY
+
+
+#define DRWAV_MAX_SIMD_VECTOR_SIZE 64 // 64 for AVX-512 in the future.
+
+#ifdef _MSC_VER
+#define DRWAV_INLINE __forceinline
+#else
+#ifdef __GNUC__
+#define DRWAV_INLINE inline __attribute__((always_inline))
+#else
+#define DRWAV_INLINE inline
+#endif
+#endif
+
+// I couldn't figure out where SIZE_MAX was defined for VC6. If anybody knows, let me know.
+#if defined(_MSC_VER) && _MSC_VER <= 1200
+ #if defined(_WIN64)
+ #define SIZE_MAX ((drwav_uint64)0xFFFFFFFFFFFFFFFF)
+ #else
+ #define SIZE_MAX 0xFFFFFFFF
+ #endif
+#endif
+
+static const drwav_uint8 drwavGUID_W64_RIFF[16] = {0x72,0x69,0x66,0x66, 0x2E,0x91, 0xCF,0x11, 0xA5,0xD6, 0x28,0xDB,0x04,0xC1,0x00,0x00}; // 66666972-912E-11CF-A5D6-28DB04C10000
+static const drwav_uint8 drwavGUID_W64_WAVE[16] = {0x77,0x61,0x76,0x65, 0xF3,0xAC, 0xD3,0x11, 0x8C,0xD1, 0x00,0xC0,0x4F,0x8E,0xDB,0x8A}; // 65766177-ACF3-11D3-8CD1-00C04F8EDB8A
+static const drwav_uint8 drwavGUID_W64_JUNK[16] = {0x6A,0x75,0x6E,0x6B, 0xF3,0xAC, 0xD3,0x11, 0x8C,0xD1, 0x00,0xC0,0x4F,0x8E,0xDB,0x8A}; // 6B6E756A-ACF3-11D3-8CD1-00C04F8EDB8A
+static const drwav_uint8 drwavGUID_W64_FMT [16] = {0x66,0x6D,0x74,0x20, 0xF3,0xAC, 0xD3,0x11, 0x8C,0xD1, 0x00,0xC0,0x4F,0x8E,0xDB,0x8A}; // 20746D66-ACF3-11D3-8CD1-00C04F8EDB8A
+static const drwav_uint8 drwavGUID_W64_FACT[16] = {0x66,0x61,0x63,0x74, 0xF3,0xAC, 0xD3,0x11, 0x8C,0xD1, 0x00,0xC0,0x4F,0x8E,0xDB,0x8A}; // 74636166-ACF3-11D3-8CD1-00C04F8EDB8A
+static const drwav_uint8 drwavGUID_W64_DATA[16] = {0x64,0x61,0x74,0x61, 0xF3,0xAC, 0xD3,0x11, 0x8C,0xD1, 0x00,0xC0,0x4F,0x8E,0xDB,0x8A}; // 61746164-ACF3-11D3-8CD1-00C04F8EDB8A
+
+static DRWAV_INLINE drwav_bool32 drwav__guid_equal(const drwav_uint8 a[16], const drwav_uint8 b[16])
+{
+ const drwav_uint32* a32 = (const drwav_uint32*)a;
+ const drwav_uint32* b32 = (const drwav_uint32*)b;
+
+ return
+ a32[0] == b32[0] &&
+ a32[1] == b32[1] &&
+ a32[2] == b32[2] &&
+ a32[3] == b32[3];
+}
+
+static DRWAV_INLINE drwav_bool32 drwav__fourcc_equal(const unsigned char* a, const char* b)
+{
+ return
+ a[0] == b[0] &&
+ a[1] == b[1] &&
+ a[2] == b[2] &&
+ a[3] == b[3];
+}
+
+
+
+static DRWAV_INLINE int drwav__is_little_endian()
+{
+ int n = 1;
+ return (*(char*)&n) == 1;
+}
+
+static DRWAV_INLINE unsigned short drwav__bytes_to_u16(const unsigned char* data)
+{
+ if (drwav__is_little_endian()) {
+ return (data[0] << 0) | (data[1] << 8);
+ } else {
+ return (data[1] << 0) | (data[0] << 8);
+ }
+}
+
+static DRWAV_INLINE short drwav__bytes_to_s16(const unsigned char* data)
+{
+ return (short)drwav__bytes_to_u16(data);
+}
+
+static DRWAV_INLINE unsigned int drwav__bytes_to_u32(const unsigned char* data)
+{
+ if (drwav__is_little_endian()) {
+ return (data[0] << 0) | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
+ } else {
+ return (data[3] << 0) | (data[2] << 8) | (data[1] << 16) | (data[0] << 24);
+ }
+}
+
+static DRWAV_INLINE drwav_uint64 drwav__bytes_to_u64(const unsigned char* data)
+{
+ if (drwav__is_little_endian()) {
+ return
+ ((drwav_uint64)data[0] << 0) | ((drwav_uint64)data[1] << 8) | ((drwav_uint64)data[2] << 16) | ((drwav_uint64)data[3] << 24) |
+ ((drwav_uint64)data[4] << 32) | ((drwav_uint64)data[5] << 40) | ((drwav_uint64)data[6] << 48) | ((drwav_uint64)data[7] << 56);
+ } else {
+ return
+ ((drwav_uint64)data[7] << 0) | ((drwav_uint64)data[6] << 8) | ((drwav_uint64)data[5] << 16) | ((drwav_uint64)data[4] << 24) |
+ ((drwav_uint64)data[3] << 32) | ((drwav_uint64)data[2] << 40) | ((drwav_uint64)data[1] << 48) | ((drwav_uint64)data[0] << 56);
+ }
+}
+
+static DRWAV_INLINE void drwav__bytes_to_guid(const unsigned char* data, drwav_uint8* guid)
+{
+ for (int i = 0; i < 16; ++i) {
+ guid[i] = data[i];
+ }
+}
+
+
+static DRWAV_INLINE drwav_bool32 drwav__is_compressed_format_tag(drwav_uint16 formatTag)
+{
+ return
+ formatTag == DR_WAVE_FORMAT_ADPCM ||
+ formatTag == DR_WAVE_FORMAT_DVI_ADPCM;
+}
+
+
+typedef struct
+{
+ union
+ {
+ drwav_uint8 fourcc[4];
+ drwav_uint8 guid[16];
+ } id;
+
+ // The size in bytes of the chunk.
+ drwav_uint64 sizeInBytes;
+
+ // RIFF = 2 byte alignment.
+ // W64 = 8 byte alignment.
+ unsigned int paddingSize;
+
+} drwav__chunk_header;
+
+static drwav_bool32 drwav__read_chunk_header(drwav_read_proc onRead, void* pUserData, drwav_container container, drwav_uint64* pRunningBytesReadOut, drwav__chunk_header* pHeaderOut)
+{
+ if (container == drwav_container_riff) {
+ if (onRead(pUserData, pHeaderOut->id.fourcc, 4) != 4) {
+ return DRWAV_FALSE;
+ }
+
+ unsigned char sizeInBytes[4];
+ if (onRead(pUserData, sizeInBytes, 4) != 4) {
+ return DRWAV_FALSE;
+ }
+
+ pHeaderOut->sizeInBytes = drwav__bytes_to_u32(sizeInBytes);
+ pHeaderOut->paddingSize = (unsigned int)(pHeaderOut->sizeInBytes % 2);
+ *pRunningBytesReadOut += 8;
+ } else {
+ if (onRead(pUserData, pHeaderOut->id.guid, 16) != 16) {
+ return DRWAV_FALSE;
+ }
+
+ unsigned char sizeInBytes[8];
+ if (onRead(pUserData, sizeInBytes, 8) != 8) {
+ return DRWAV_FALSE;
+ }
+
+ pHeaderOut->sizeInBytes = drwav__bytes_to_u64(sizeInBytes) - 24; // <-- Subtract 24 because w64 includes the size of the header.
+ pHeaderOut->paddingSize = (unsigned int)(pHeaderOut->sizeInBytes % 8);
+ pRunningBytesReadOut += 24;
+ }
+
+ return DRWAV_TRUE;
+}
+
+static drwav_bool32 drwav__seek_forward(drwav_seek_proc onSeek, drwav_uint64 offset, void* pUserData)
+{
+ drwav_uint64 bytesRemainingToSeek = offset;
+ while (bytesRemainingToSeek > 0) {
+ if (bytesRemainingToSeek > 0x7FFFFFFF) {
+ if (!onSeek(pUserData, 0x7FFFFFFF, drwav_seek_origin_current)) {
+ return DRWAV_FALSE;
+ }
+ bytesRemainingToSeek -= 0x7FFFFFFF;
+ } else {
+ if (!onSeek(pUserData, (int)bytesRemainingToSeek, drwav_seek_origin_current)) {
+ return DRWAV_FALSE;
+ }
+ bytesRemainingToSeek = 0;
+ }
+ }
+
+ return DRWAV_TRUE;
+}
+
+
+static drwav_bool32 drwav__read_fmt(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, drwav_container container, drwav_uint64* pRunningBytesReadOut, drwav_fmt* fmtOut)
+{
+ drwav__chunk_header header;
+ if (!drwav__read_chunk_header(onRead, pUserData, container, pRunningBytesReadOut, &header)) {
+ return DRWAV_FALSE;
+ }
+
+
+ // Skip junk chunks.
+ if ((container == drwav_container_riff && drwav__fourcc_equal(header.id.fourcc, "JUNK")) || (container == drwav_container_w64 && drwav__guid_equal(header.id.guid, drwavGUID_W64_JUNK))) {
+ if (!drwav__seek_forward(onSeek, header.sizeInBytes + header.paddingSize, pUserData)) {
+ return DRWAV_FALSE;
+ }
+ *pRunningBytesReadOut += header.sizeInBytes + header.paddingSize;
+
+ return drwav__read_fmt(onRead, onSeek, pUserData, container, pRunningBytesReadOut, fmtOut);
+ }
+
+
+ // Validation.
+ if (container == drwav_container_riff) {
+ if (!drwav__fourcc_equal(header.id.fourcc, "fmt ")) {
+ return DRWAV_FALSE;
+ }
+ } else {
+ if (!drwav__guid_equal(header.id.guid, drwavGUID_W64_FMT)) {
+ return DRWAV_FALSE;
+ }
+ }
+
+
+ unsigned char fmt[16];
+ if (onRead(pUserData, fmt, sizeof(fmt)) != sizeof(fmt)) {
+ return DRWAV_FALSE;
+ }
+ *pRunningBytesReadOut += sizeof(fmt);
+
+ fmtOut->formatTag = drwav__bytes_to_u16(fmt + 0);
+ fmtOut->channels = drwav__bytes_to_u16(fmt + 2);
+ fmtOut->sampleRate = drwav__bytes_to_u32(fmt + 4);
+ fmtOut->avgBytesPerSec = drwav__bytes_to_u32(fmt + 8);
+ fmtOut->blockAlign = drwav__bytes_to_u16(fmt + 12);
+ fmtOut->bitsPerSample = drwav__bytes_to_u16(fmt + 14);
+
+ fmtOut->extendedSize = 0;
+ fmtOut->validBitsPerSample = 0;
+ fmtOut->channelMask = 0;
+ memset(fmtOut->subFormat, 0, sizeof(fmtOut->subFormat));
+
+ if (header.sizeInBytes > 16) {
+ unsigned char fmt_cbSize[2];
+ if (onRead(pUserData, fmt_cbSize, sizeof(fmt_cbSize)) != sizeof(fmt_cbSize)) {
+ return DRWAV_FALSE; // Expecting more data.
+ }
+ *pRunningBytesReadOut += sizeof(fmt_cbSize);
+
+ int bytesReadSoFar = 18;
+
+ fmtOut->extendedSize = drwav__bytes_to_u16(fmt_cbSize);
+ if (fmtOut->extendedSize > 0) {
+ // Simple validation.
+ if (fmtOut->formatTag == DR_WAVE_FORMAT_EXTENSIBLE) {
+ if (fmtOut->extendedSize != 22) {
+ return DRWAV_FALSE;
+ }
+ }
+
+ if (fmtOut->formatTag == DR_WAVE_FORMAT_EXTENSIBLE) {
+ unsigned char fmtext[22];
+ if (onRead(pUserData, fmtext, fmtOut->extendedSize) != fmtOut->extendedSize) {
+ return DRWAV_FALSE; // Expecting more data.
+ }
+
+ fmtOut->validBitsPerSample = drwav__bytes_to_u16(fmtext + 0);
+ fmtOut->channelMask = drwav__bytes_to_u32(fmtext + 2);
+ drwav__bytes_to_guid(fmtext + 6, fmtOut->subFormat);
+ } else {
+ if (!onSeek(pUserData, fmtOut->extendedSize, drwav_seek_origin_current)) {
+ return DRWAV_FALSE;
+ }
+ }
+ *pRunningBytesReadOut += fmtOut->extendedSize;
+
+ bytesReadSoFar += fmtOut->extendedSize;
+ }
+
+ // Seek past any leftover bytes. For w64 the leftover will be defined based on the chunk size.
+ if (!onSeek(pUserData, (int)(header.sizeInBytes - bytesReadSoFar), drwav_seek_origin_current)) {
+ return DRWAV_FALSE;
+ }
+ *pRunningBytesReadOut += (header.sizeInBytes - bytesReadSoFar);
+ }
+
+ if (header.paddingSize > 0) {
+ if (!onSeek(pUserData, header.paddingSize, drwav_seek_origin_current)) {
+ return DRWAV_FALSE;
+ }
+ *pRunningBytesReadOut += header.paddingSize;
+ }
+
+ return DRWAV_TRUE;
+}
+
+
+#ifndef DR_WAV_NO_STDIO
+static size_t drwav__on_read_stdio(void* pUserData, void* pBufferOut, size_t bytesToRead)
+{
+ return fread(pBufferOut, 1, bytesToRead, (FILE*)pUserData);
+}
+
+static size_t drwav__on_write_stdio(void* pUserData, const void* pData, size_t bytesToWrite)
+{
+ return fwrite(pData, 1, bytesToWrite, (FILE*)pUserData);
+}
+
+static drwav_bool32 drwav__on_seek_stdio(void* pUserData, int offset, drwav_seek_origin origin)
+{
+ return fseek((FILE*)pUserData, offset, (origin == drwav_seek_origin_current) ? SEEK_CUR : SEEK_SET) == 0;
+}
+
+drwav_bool32 drwav_init_file(drwav* pWav, const char* filename)
+{
+ FILE* pFile;
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+ if (fopen_s(&pFile, filename, "rb") != 0) {
+ return DRWAV_FALSE;
+ }
+#else
+ pFile = fopen(filename, "rb");
+ if (pFile == NULL) {
+ return DRWAV_FALSE;
+ }
+#endif
+
+ return drwav_init(pWav, drwav__on_read_stdio, drwav__on_seek_stdio, (void*)pFile);
+}
+
+drwav_bool32 drwav_init_file_write(drwav* pWav, const char* filename, const drwav_data_format* pFormat)
+{
+ FILE* pFile;
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+ if (fopen_s(&pFile, filename, "wb") != 0) {
+ return DRWAV_FALSE;
+ }
+#else
+ pFile = fopen(filename, "wb");
+ if (pFile == NULL) {
+ return DRWAV_FALSE;
+ }
+#endif
+
+ return drwav_init_write(pWav, pFormat, drwav__on_write_stdio, drwav__on_seek_stdio, (void*)pFile);
+}
+
+drwav* drwav_open_file(const char* filename)
+{
+ FILE* pFile;
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+ if (fopen_s(&pFile, filename, "rb") != 0) {
+ return NULL;
+ }
+#else
+ pFile = fopen(filename, "rb");
+ if (pFile == NULL) {
+ return NULL;
+ }
+#endif
+
+ drwav* pWav = drwav_open(drwav__on_read_stdio, drwav__on_seek_stdio, (void*)pFile);
+ if (pWav == NULL) {
+ fclose(pFile);
+ return NULL;
+ }
+
+ return pWav;
+}
+
+drwav* drwav_open_file_write(const char* filename, const drwav_data_format* pFormat)
+{
+ FILE* pFile;
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+ if (fopen_s(&pFile, filename, "wb") != 0) {
+ return NULL;
+ }
+#else
+ pFile = fopen(filename, "wb");
+ if (pFile == NULL) {
+ return NULL;
+ }
+#endif
+
+ drwav* pWav = drwav_open_write(pFormat, drwav__on_write_stdio, drwav__on_seek_stdio, (void*)pFile);
+ if (pWav == NULL) {
+ fclose(pFile);
+ return NULL;
+ }
+
+ return pWav;
+}
+#endif //DR_WAV_NO_STDIO
+
+
+static size_t drwav__on_read_memory(void* pUserData, void* pBufferOut, size_t bytesToRead)
+{
+ drwav__memory_stream* memory = (drwav__memory_stream*)pUserData;
+ drwav_assert(memory != NULL);
+ drwav_assert(memory->dataSize >= memory->currentReadPos);
+
+ size_t bytesRemaining = memory->dataSize - memory->currentReadPos;
+ if (bytesToRead > bytesRemaining) {
+ bytesToRead = bytesRemaining;
+ }
+
+ if (bytesToRead > 0) {
+ DRWAV_COPY_MEMORY(pBufferOut, memory->data + memory->currentReadPos, bytesToRead);
+ memory->currentReadPos += bytesToRead;
+ }
+
+ return bytesToRead;
+}
+
+static drwav_bool32 drwav__on_seek_memory(void* pUserData, int offset, drwav_seek_origin origin)
+{
+ drwav__memory_stream* memory = (drwav__memory_stream*)pUserData;
+ drwav_assert(memory != NULL);
+
+ if (origin == drwav_seek_origin_current) {
+ if (offset > 0) {
+ if (memory->currentReadPos + offset > memory->dataSize) {
+ offset = (int)(memory->dataSize - memory->currentReadPos); // Trying to seek too far forward.
+ }
+ } else {
+ if (memory->currentReadPos < (size_t)-offset) {
+ offset = -(int)memory->currentReadPos; // Trying to seek too far backwards.
+ }
+ }
+
+ // This will never underflow thanks to the clamps above.
+ memory->currentReadPos += offset;
+ } else {
+ if ((drwav_uint32)offset <= memory->dataSize) {
+ memory->currentReadPos = offset;
+ } else {
+ memory->currentReadPos = memory->dataSize; // Trying to seek too far forward.
+ }
+ }
+
+ return DRWAV_TRUE;
+}
+
+static size_t drwav__on_write_memory(void* pUserData, const void* pDataIn, size_t bytesToWrite)
+{
+ drwav__memory_stream_write* memory = (drwav__memory_stream_write*)pUserData;
+ drwav_assert(memory != NULL);
+ drwav_assert(memory->dataCapacity >= memory->currentWritePos);
+
+ size_t bytesRemaining = memory->dataCapacity - memory->currentWritePos;
+ if (bytesRemaining < bytesToWrite) {
+ // Need to reallocate.
+ size_t newDataCapacity = (memory->dataCapacity == 0) ? 256 : memory->dataCapacity * 2;
+
+ // If doubling wasn't enough, just make it the minimum required size to write the data.
+ if ((newDataCapacity - memory->currentWritePos) < bytesToWrite) {
+ newDataCapacity = memory->currentWritePos + bytesToWrite;
+ }
+
+ void* pNewData = DRWAV_REALLOC(*memory->ppData, newDataCapacity);
+ if (pNewData == NULL) {
+ return 0;
+ }
+
+ *memory->ppData = pNewData;
+ memory->dataCapacity = newDataCapacity;
+ }
+
+ drwav_uint8* pDataOut = (drwav_uint8*)(*memory->ppData);
+ DRWAV_COPY_MEMORY(pDataOut + memory->currentWritePos, pDataIn, bytesToWrite);
+
+ memory->currentWritePos += bytesToWrite;
+ if (memory->dataSize < memory->currentWritePos) {
+ memory->dataSize = memory->currentWritePos;
+ }
+
+ *memory->pDataSize = memory->dataSize;
+
+ return bytesToWrite;
+}
+
+static drwav_bool32 drwav__on_seek_memory_write(void* pUserData, int offset, drwav_seek_origin origin)
+{
+ drwav__memory_stream_write* memory = (drwav__memory_stream_write*)pUserData;
+ drwav_assert(memory != NULL);
+
+ if (origin == drwav_seek_origin_current) {
+ if (offset > 0) {
+ if (memory->currentWritePos + offset > memory->dataSize) {
+ offset = (int)(memory->dataSize - memory->currentWritePos); // Trying to seek too far forward.
+ }
+ } else {
+ if (memory->currentWritePos < (size_t)-offset) {
+ offset = -(int)memory->currentWritePos; // Trying to seek too far backwards.
+ }
+ }
+
+ // This will never underflow thanks to the clamps above.
+ memory->currentWritePos += offset;
+ } else {
+ if ((drwav_uint32)offset <= memory->dataSize) {
+ memory->currentWritePos = offset;
+ } else {
+ memory->currentWritePos = memory->dataSize; // Trying to seek too far forward.
+ }
+ }
+
+ return DRWAV_TRUE;
+}
+
+drwav_bool32 drwav_init_memory(drwav* pWav, const void* data, size_t dataSize)
+{
+ if (data == NULL || dataSize == 0) {
+ return DRWAV_FALSE;
+ }
+
+ drwav__memory_stream memoryStream;
+ drwav_zero_memory(&memoryStream, sizeof(memoryStream));
+ memoryStream.data = (const unsigned char*)data;
+ memoryStream.dataSize = dataSize;
+ memoryStream.currentReadPos = 0;
+
+ if (!drwav_init(pWav, drwav__on_read_memory, drwav__on_seek_memory, (void*)&memoryStream)) {
+ return DRWAV_FALSE;
+ }
+
+ pWav->memoryStream = memoryStream;
+ pWav->pUserData = &pWav->memoryStream;
+ return DRWAV_TRUE;
+}
+
+drwav_bool32 drwav_init_memory_write(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat)
+{
+ if (ppData == NULL) {
+ return DRWAV_FALSE;
+ }
+
+ *ppData = NULL; // Important because we're using realloc()!
+ *pDataSize = 0;
+
+ drwav__memory_stream_write memoryStreamWrite;
+ drwav_zero_memory(&memoryStreamWrite, sizeof(memoryStreamWrite));
+ memoryStreamWrite.ppData = ppData;
+ memoryStreamWrite.pDataSize = pDataSize;
+ memoryStreamWrite.dataSize = 0;
+ memoryStreamWrite.dataCapacity = 0;
+ memoryStreamWrite.currentWritePos = 0;
+
+ if (!drwav_init_write(pWav, pFormat, drwav__on_write_memory, drwav__on_seek_memory_write, (void*)&memoryStreamWrite)) {
+ return DRWAV_FALSE;
+ }
+
+ pWav->memoryStreamWrite = memoryStreamWrite;
+ pWav->pUserData = &pWav->memoryStreamWrite;
+ return DRWAV_TRUE;
+}
+
+drwav* drwav_open_memory(const void* data, size_t dataSize)
+{
+ if (data == NULL || dataSize == 0) {
+ return NULL;
+ }
+
+ drwav__memory_stream memoryStream;
+ drwav_zero_memory(&memoryStream, sizeof(memoryStream));
+ memoryStream.data = (const unsigned char*)data;
+ memoryStream.dataSize = dataSize;
+ memoryStream.currentReadPos = 0;
+
+ drwav* pWav = drwav_open(drwav__on_read_memory, drwav__on_seek_memory, (void*)&memoryStream);
+ if (pWav == NULL) {
+ return NULL;
+ }
+
+ pWav->memoryStream = memoryStream;
+ pWav->pUserData = &pWav->memoryStream;
+ return pWav;
+}
+
+drwav* drwav_open_memory_write(void** ppData, size_t* pDataSize, const drwav_data_format* pFormat)
+{
+ if (ppData == NULL) {
+ return NULL;
+ }
+
+ *ppData = NULL; // Important because we're using realloc()!
+ *pDataSize = 0;
+
+ drwav__memory_stream_write memoryStreamWrite;
+ drwav_zero_memory(&memoryStreamWrite, sizeof(memoryStreamWrite));
+ memoryStreamWrite.ppData = ppData;
+ memoryStreamWrite.pDataSize = pDataSize;
+ memoryStreamWrite.dataSize = 0;
+ memoryStreamWrite.dataCapacity = 0;
+ memoryStreamWrite.currentWritePos = 0;
+
+ drwav* pWav = drwav_open_write(pFormat, drwav__on_write_memory, drwav__on_seek_memory_write, (void*)&memoryStreamWrite);
+ if (pWav == NULL) {
+ return NULL;
+ }
+
+ pWav->memoryStreamWrite = memoryStreamWrite;
+ pWav->pUserData = &pWav->memoryStreamWrite;
+ return pWav;
+}
+
+
+drwav_bool32 drwav_init(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData)
+{
+ if (onRead == NULL || onSeek == NULL) {
+ return DRWAV_FALSE;
+ }
+
+ drwav_zero_memory(pWav, sizeof(*pWav));
+
+
+ // The first 4 bytes should be the RIFF identifier.
+ unsigned char riff[4];
+ if (onRead(pUserData, riff, sizeof(riff)) != sizeof(riff)) {
+ return DRWAV_FALSE; // Failed to read data.
+ }
+
+ // The first 4 bytes can be used to identify the container. For RIFF files it will start with "RIFF" and for
+ // w64 it will start with "riff".
+ if (drwav__fourcc_equal(riff, "RIFF")) {
+ pWav->container = drwav_container_riff;
+ } else if (drwav__fourcc_equal(riff, "riff")) {
+ pWav->container = drwav_container_w64;
+
+ // Check the rest of the GUID for validity.
+ drwav_uint8 riff2[12];
+ if (onRead(pUserData, riff2, sizeof(riff2)) != sizeof(riff2)) {
+ return DRWAV_FALSE;
+ }
+
+ for (int i = 0; i < 12; ++i) {
+ if (riff2[i] != drwavGUID_W64_RIFF[i+4]) {
+ return DRWAV_FALSE;
+ }
+ }
+ } else {
+ return DRWAV_FALSE; // Unknown or unsupported container.
+ }
+
+
+ if (pWav->container == drwav_container_riff) {
+ // RIFF/WAVE
+ unsigned char chunkSizeBytes[4];
+ if (onRead(pUserData, chunkSizeBytes, sizeof(chunkSizeBytes)) != sizeof(chunkSizeBytes)) {
+ return DRWAV_FALSE;
+ }
+
+ unsigned int chunkSize = drwav__bytes_to_u32(chunkSizeBytes);
+ if (chunkSize < 36) {
+ return DRWAV_FALSE; // Chunk size should always be at least 36 bytes.
+ }
+
+ unsigned char wave[4];
+ if (onRead(pUserData, wave, sizeof(wave)) != sizeof(wave)) {
+ return DRWAV_FALSE;
+ }
+
+ if (!drwav__fourcc_equal(wave, "WAVE")) {
+ return DRWAV_FALSE; // Expecting "WAVE".
+ }
+
+ pWav->dataChunkDataPos = 4 + sizeof(chunkSizeBytes) + sizeof(wave);
+ } else {
+ // W64
+ unsigned char chunkSize[8];
+ if (onRead(pUserData, chunkSize, sizeof(chunkSize)) != sizeof(chunkSize)) {
+ return DRWAV_FALSE;
+ }
+
+ if (drwav__bytes_to_u64(chunkSize) < 80) {
+ return DRWAV_FALSE;
+ }
+
+ drwav_uint8 wave[16];
+ if (onRead(pUserData, wave, sizeof(wave)) != sizeof(wave)) {
+ return DRWAV_FALSE;
+ }
+
+ if (!drwav__guid_equal(wave, drwavGUID_W64_WAVE)) {
+ return DRWAV_FALSE;
+ }
+
+ pWav->dataChunkDataPos = 16 + sizeof(chunkSize) + sizeof(wave);
+ }
+
+
+ // The next 24 bytes should be the "fmt " chunk.
+ drwav_fmt fmt;
+ if (!drwav__read_fmt(onRead, onSeek, pUserData, pWav->container, &pWav->dataChunkDataPos, &fmt)) {
+ return DRWAV_FALSE; // Failed to read the "fmt " chunk.
+ }
+
+
+ // Translate the internal format.
+ unsigned short translatedFormatTag = fmt.formatTag;
+ if (translatedFormatTag == DR_WAVE_FORMAT_EXTENSIBLE) {
+ translatedFormatTag = drwav__bytes_to_u16(fmt.subFormat + 0);
+ }
+
+
+ drwav_uint64 sampleCountFromFactChunk = 0;
+
+ // The next chunk we care about is the "data" chunk. This is not necessarily the next chunk so we'll need to loop.
+ drwav_uint64 dataSize;
+ for (;;)
+ {
+ drwav__chunk_header header;
+ if (!drwav__read_chunk_header(onRead, pUserData, pWav->container, &pWav->dataChunkDataPos, &header)) {
+ return DRWAV_FALSE;
+ }
+
+ dataSize = header.sizeInBytes;
+ if (pWav->container == drwav_container_riff) {
+ if (drwav__fourcc_equal(header.id.fourcc, "data")) {
+ break;
+ }
+ } else {
+ if (drwav__guid_equal(header.id.guid, drwavGUID_W64_DATA)) {
+ break;
+ }
+ }
+
+ // Optional. Get the total sample count from the FACT chunk. This is useful for compressed formats.
+ if (pWav->container == drwav_container_riff) {
+ if (drwav__fourcc_equal(header.id.fourcc, "fact")) {
+ drwav_uint32 sampleCount;
+ if (onRead(pUserData, &sampleCount, 4) != 4) {
+ return DRWAV_FALSE;
+ }
+ pWav->dataChunkDataPos += 4;
+ dataSize -= 4;
+
+ // The sample count in the "fact" chunk is either unreliable, or I'm not understanding it properly. For now I am only enabling this
+ // for Microsoft ADPCM formats.
+ if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) {
+ sampleCountFromFactChunk = sampleCount;
+ } else {
+ sampleCountFromFactChunk = 0;
+ }
+ }
+ } else {
+ if (drwav__guid_equal(header.id.guid, drwavGUID_W64_FACT)) {
+ if (onRead(pUserData, &sampleCountFromFactChunk, 8) != 8) {
+ return DRWAV_FALSE;
+ }
+ pWav->dataChunkDataPos += 4;
+ dataSize -= 8;
+ }
+ }
+
+ // If we get here it means we didn't find the "data" chunk. Seek past it.
+
+ // Make sure we seek past the padding.
+ dataSize += header.paddingSize;
+ drwav__seek_forward(onSeek, dataSize, pUserData);
+ pWav->dataChunkDataPos += dataSize;
+ }
+
+ // At this point we should be sitting on the first byte of the raw audio data.
+
+ pWav->onRead = onRead;
+ pWav->onSeek = onSeek;
+ pWav->pUserData = pUserData;
+ pWav->fmt = fmt;
+ pWav->sampleRate = fmt.sampleRate;
+ pWav->channels = fmt.channels;
+ pWav->bitsPerSample = fmt.bitsPerSample;
+ pWav->bytesPerSample = (unsigned int)(fmt.blockAlign / fmt.channels);
+ pWav->bytesRemaining = dataSize;
+ pWav->translatedFormatTag = translatedFormatTag;
+ pWav->dataChunkDataSize = dataSize;
+
+ if (sampleCountFromFactChunk != 0) {
+ pWav->totalSampleCount = sampleCountFromFactChunk * fmt.channels;
+ } else {
+ pWav->totalSampleCount = dataSize / pWav->bytesPerSample;
+
+ if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) {
+ drwav_uint64 blockCount = dataSize / fmt.blockAlign;
+ pWav->totalSampleCount = (blockCount * (fmt.blockAlign - (6*pWav->channels))) * 2; // x2 because two samples per byte.
+ }
+ if (pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
+ drwav_uint64 blockCount = dataSize / fmt.blockAlign;
+ pWav->totalSampleCount = ((blockCount * (fmt.blockAlign - (4*pWav->channels))) * 2) + (blockCount * pWav->channels);
+ }
+ }
+
+ if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) {
+ pWav->bytesPerSample = 0;
+ }
+
+#ifdef DR_WAV_LIBSNDFILE_COMPAT
+ // I use libsndfile as a benchmark for testing, however in the version I'm using (from the Windows installer on the libsndfile website),
+ // it appears the total sample count libsndfile uses for MS-ADPCM is incorrect. It would seem they are computing the total sample count
+ // from the number of blocks, however this results in the inclusion of the extra silent samples at the end of the last block. The correct
+ // way to know the total sample count is to inspect the "fact" chunk which should always be present for compressed formats, and should
+ // always include the sample count. This little block of code below is only used to emulate the libsndfile logic so I can properly run my
+ // correctness tests against libsndfile and is disabled by default.
+ if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) {
+ drwav_uint64 blockCount = dataSize / fmt.blockAlign;
+ pWav->totalSampleCount = (blockCount * (fmt.blockAlign - (6*pWav->channels))) * 2; // x2 because two samples per byte.
+ }
+ if (pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
+ drwav_uint64 blockCount = dataSize / fmt.blockAlign;
+ pWav->totalSampleCount = ((blockCount * (fmt.blockAlign - (4*pWav->channels))) * 2) + (blockCount * pWav->channels);
+ }
+#endif
+
+ return DRWAV_TRUE;
+}
+
+drwav_bool32 drwav_init_write(drwav* pWav, const drwav_data_format* pFormat, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData)
+{
+ if (onWrite == NULL || onSeek == NULL) {
+ return DRWAV_FALSE;
+ }
+
+ // Not currently supporting compressed formats. Will need to add support for the "fact" chunk before we enable this.
+ if (pFormat->format == DR_WAVE_FORMAT_EXTENSIBLE) {
+ return DRWAV_FALSE;
+ }
+ if (pFormat->format == DR_WAVE_FORMAT_ADPCM || pFormat->format == DR_WAVE_FORMAT_DVI_ADPCM) {
+ return DRWAV_FALSE;
+ }
+
+
+ drwav_zero_memory(pWav, sizeof(*pWav));
+ pWav->onWrite = onWrite;
+ pWav->onSeek = onSeek;
+ pWav->pUserData = pUserData;
+ pWav->fmt.formatTag = (drwav_uint16)pFormat->format;
+ pWav->fmt.channels = (drwav_uint16)pFormat->channels;
+ pWav->fmt.sampleRate = pFormat->sampleRate;
+ pWav->fmt.avgBytesPerSec = (drwav_uint32)((pFormat->bitsPerSample * pFormat->sampleRate * pFormat->channels) >> 3);
+ pWav->fmt.blockAlign = (drwav_uint16)((pFormat->channels * pFormat->bitsPerSample) >> 3);
+ pWav->fmt.bitsPerSample = (drwav_uint16)pFormat->bitsPerSample;
+ pWav->fmt.extendedSize = 0;
+
+ size_t runningPos = 0;
+
+ // "RIFF" chunk.
+ drwav_uint64 chunkSizeRIFF = 0;
+ if (pFormat->container == drwav_container_riff) {
+ runningPos += pWav->onWrite(pUserData, "RIFF", 4);
+ runningPos += pWav->onWrite(pUserData, &chunkSizeRIFF, 4);
+ runningPos += pWav->onWrite(pUserData, "WAVE", 4);
+ } else {
+ runningPos += pWav->onWrite(pUserData, drwavGUID_W64_RIFF, 16);
+ runningPos += pWav->onWrite(pUserData, &chunkSizeRIFF, 8);
+ runningPos += pWav->onWrite(pUserData, drwavGUID_W64_WAVE, 16);
+ }
+
+ // "fmt " chunk.
+ drwav_uint64 chunkSizeFMT;
+ if (pFormat->container == drwav_container_riff) {
+ chunkSizeFMT = 16;
+ runningPos += pWav->onWrite(pUserData, "fmt ", 4);
+ runningPos += pWav->onWrite(pUserData, &chunkSizeFMT, 4);
+ } else {
+ chunkSizeFMT = 40;
+ runningPos += pWav->onWrite(pUserData, drwavGUID_W64_FMT, 16);
+ runningPos += pWav->onWrite(pUserData, &chunkSizeFMT, 8);
+ }
+
+ runningPos += pWav->onWrite(pUserData, &pWav->fmt.formatTag, 2);
+ runningPos += pWav->onWrite(pUserData, &pWav->fmt.channels, 2);
+ runningPos += pWav->onWrite(pUserData, &pWav->fmt.sampleRate, 4);
+ runningPos += pWav->onWrite(pUserData, &pWav->fmt.avgBytesPerSec, 4);
+ runningPos += pWav->onWrite(pUserData, &pWav->fmt.blockAlign, 2);
+ runningPos += pWav->onWrite(pUserData, &pWav->fmt.bitsPerSample, 2);
+
+ pWav->dataChunkDataPos = runningPos;
+ pWav->dataChunkDataSize = 0;
+
+ // "data" chunk.
+ drwav_uint64 chunkSizeDATA = 0;
+ if (pFormat->container == drwav_container_riff) {
+ runningPos += pWav->onWrite(pUserData, "data", 4);
+ runningPos += pWav->onWrite(pUserData, &chunkSizeDATA, 4);
+ } else {
+ runningPos += pWav->onWrite(pUserData, drwavGUID_W64_DATA, 16);
+ runningPos += pWav->onWrite(pUserData, &chunkSizeDATA, 8);
+ }
+
+
+ // Simple validation.
+ if (pFormat->container == drwav_container_riff) {
+ if (runningPos != 20 + chunkSizeFMT + 8) {
+ return DRWAV_FALSE;
+ }
+ } else {
+ if (runningPos != 40 + chunkSizeFMT + 24) {
+ return DRWAV_FALSE;
+ }
+ }
+
+
+
+ // Set some properties for the client's convenience.
+ pWav->container = pFormat->container;
+ pWav->channels = (drwav_uint16)pFormat->channels;
+ pWav->sampleRate = pFormat->sampleRate;
+ pWav->bitsPerSample = (drwav_uint16)pFormat->bitsPerSample;
+ pWav->bytesPerSample = (drwav_uint16)(pFormat->bitsPerSample >> 3);
+ pWav->translatedFormatTag = (drwav_uint16)pFormat->format;
+
+ return DRWAV_TRUE;
+}
+
+void drwav_uninit(drwav* pWav)
+{
+ if (pWav == NULL) {
+ return;
+ }
+
+ // If the drwav object was opened in write mode we'll need to finialize a few things:
+ // - Make sure the "data" chunk is aligned to 16-bits
+ // - Set the size of the "data" chunk.
+ if (pWav->onWrite != NULL) {
+ // Padding. Do not adjust pWav->dataChunkDataSize - this should not include the padding.
+ drwav_uint32 paddingSize = 0;
+ if (pWav->container == drwav_container_riff) {
+ paddingSize = (drwav_uint32)(pWav->dataChunkDataSize % 2);
+ } else {
+ paddingSize = (drwav_uint32)(pWav->dataChunkDataSize % 8);
+ }
+
+ if (paddingSize > 0) {
+ drwav_uint64 paddingData = 0;
+ pWav->onWrite(pWav->pUserData, &paddingData, paddingSize);
+ }
+
+
+ // Chunk sizes.
+ if (pWav->onSeek) {
+ if (pWav->container == drwav_container_riff) {
+ // The "RIFF" chunk size.
+ if (pWav->onSeek(pWav->pUserData, 4, drwav_seek_origin_start)) {
+ drwav_uint32 riffChunkSize = 36;
+ if (pWav->dataChunkDataSize <= (0xFFFFFFFF - 36)) {
+ riffChunkSize = 36 + (drwav_uint32)pWav->dataChunkDataSize;
+ } else {
+ riffChunkSize = 0xFFFFFFFF;
+ }
+
+ pWav->onWrite(pWav->pUserData, &riffChunkSize, 4);
+ }
+
+ // the "data" chunk size.
+ if (pWav->onSeek(pWav->pUserData, (int)pWav->dataChunkDataPos + 4, drwav_seek_origin_start)) {
+ drwav_uint32 dataChunkSize = 0;
+ if (pWav->dataChunkDataSize <= 0xFFFFFFFF) {
+ dataChunkSize = (drwav_uint32)pWav->dataChunkDataSize;
+ } else {
+ dataChunkSize = 0xFFFFFFFF;
+ }
+
+ pWav->onWrite(pWav->pUserData, &dataChunkSize, 4);
+ }
+ } else {
+ // The "RIFF" chunk size.
+ if (pWav->onSeek(pWav->pUserData, 16, drwav_seek_origin_start)) {
+ drwav_uint64 riffChunkSize = 80 + 24 + pWav->dataChunkDataSize;
+ pWav->onWrite(pWav->pUserData, &riffChunkSize, 8);
+ }
+
+ // The "data" chunk size.
+ if (pWav->onSeek(pWav->pUserData, (int)pWav->dataChunkDataPos + 16, drwav_seek_origin_start)) {
+ drwav_uint64 dataChunkSize = 24 + pWav->dataChunkDataSize; // +24 because W64 includes the size of the GUID and size fields.
+ pWav->onWrite(pWav->pUserData, &dataChunkSize, 8);
+ }
+ }
+ }
+ }
+
+#ifndef DR_WAV_NO_STDIO
+ // If we opened the file with drwav_open_file() we will want to close the file handle. We can know whether or not drwav_open_file()
+ // was used by looking at the onRead and onSeek callbacks.
+ if (pWav->onRead == drwav__on_read_stdio || pWav->onWrite == drwav__on_write_stdio) {
+ fclose((FILE*)pWav->pUserData);
+ }
+#endif
+}
+
+
+drwav* drwav_open(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData)
+{
+ drwav* pWav = (drwav*)DRWAV_MALLOC(sizeof(*pWav));
+ if (pWav == NULL) {
+ return NULL;
+ }
+
+ if (!drwav_init(pWav, onRead, onSeek, pUserData)) {
+ DRWAV_FREE(pWav);
+ return NULL;
+ }
+
+ return pWav;
+}
+
+drwav* drwav_open_write(const drwav_data_format* pFormat, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData)
+{
+ drwav* pWav = (drwav*)DRWAV_MALLOC(sizeof(*pWav));
+ if (pWav == NULL) {
+ return NULL;
+ }
+
+ if (!drwav_init_write(pWav, pFormat, onWrite, onSeek, pUserData)) {
+ DRWAV_FREE(pWav);
+ return NULL;
+ }
+
+ return pWav;
+}
+
+void drwav_close(drwav* pWav)
+{
+ drwav_uninit(pWav);
+ DRWAV_FREE(pWav);
+}
+
+
+size_t drwav_read_raw(drwav* pWav, size_t bytesToRead, void* pBufferOut)
+{
+ if (pWav == NULL || bytesToRead == 0 || pBufferOut == NULL) {
+ return 0;
+ }
+
+ if (bytesToRead > pWav->bytesRemaining) {
+ bytesToRead = (size_t)pWav->bytesRemaining;
+ }
+
+ size_t bytesRead = pWav->onRead(pWav->pUserData, pBufferOut, bytesToRead);
+
+ pWav->bytesRemaining -= bytesRead;
+ return bytesRead;
+}
+
+drwav_uint64 drwav_read(drwav* pWav, drwav_uint64 samplesToRead, void* pBufferOut)
+{
+ if (pWav == NULL || samplesToRead == 0 || pBufferOut == NULL) {
+ return 0;
+ }
+
+ // Cannot use this function for compressed formats.
+ if (drwav__is_compressed_format_tag(pWav->translatedFormatTag)) {
+ return 0;
+ }
+
+ // Don't try to read more samples than can potentially fit in the output buffer.
+ if (samplesToRead * pWav->bytesPerSample > SIZE_MAX) {
+ samplesToRead = SIZE_MAX / pWav->bytesPerSample;
+ }
+
+ size_t bytesRead = drwav_read_raw(pWav, (size_t)(samplesToRead * pWav->bytesPerSample), pBufferOut);
+ return bytesRead / pWav->bytesPerSample;
+}
+
+drwav_bool32 drwav_seek_to_first_sample(drwav* pWav)
+{
+ if (!pWav->onSeek(pWav->pUserData, (int)pWav->dataChunkDataPos, drwav_seek_origin_start)) {
+ return DRWAV_FALSE;
+ }
+
+ if (drwav__is_compressed_format_tag(pWav->translatedFormatTag)) {
+ pWav->compressed.iCurrentSample = 0;
+ }
+
+ pWav->bytesRemaining = pWav->dataChunkDataSize;
+ return DRWAV_TRUE;
+}
+
+drwav_bool32 drwav_seek_to_sample(drwav* pWav, drwav_uint64 sample)
+{
+ // Seeking should be compatible with wave files > 2GB.
+
+ if (pWav == NULL || pWav->onSeek == NULL) {
+ return DRWAV_FALSE;
+ }
+
+ // If there are no samples, just return DRWAV_TRUE without doing anything.
+ if (pWav->totalSampleCount == 0) {
+ return DRWAV_TRUE;
+ }
+
+ // Make sure the sample is clamped.
+ if (sample >= pWav->totalSampleCount) {
+ sample = pWav->totalSampleCount - 1;
+ }
+
+
+ // For compressed formats we just use a slow generic seek. If we are seeking forward we just seek forward. If we are going backwards we need
+ // to seek back to the start.
+ if (drwav__is_compressed_format_tag(pWav->translatedFormatTag)) {
+ // TODO: This can be optimized.
+ if (sample > pWav->compressed.iCurrentSample) {
+ // Seeking forward - just move from the current position.
+ drwav_uint64 offset = sample - pWav->compressed.iCurrentSample;
+
+ drwav_int16 devnull[2048];
+ while (offset > 0) {
+ drwav_uint64 samplesToRead = sample;
+ if (samplesToRead > 2048) {
+ samplesToRead = 2048;
+ }
+
+ drwav_uint64 samplesRead = drwav_read_s16(pWav, samplesToRead, devnull);
+ if (samplesRead != samplesToRead) {
+ return DRWAV_FALSE;
+ }
+
+ offset -= samplesRead;
+ }
+ } else {
+ // Seeking backwards. Just use the fallback.
+ goto fallback;
+ }
+ } else {
+ drwav_uint64 totalSizeInBytes = pWav->totalSampleCount * pWav->bytesPerSample;
+ drwav_assert(totalSizeInBytes >= pWav->bytesRemaining);
+
+ drwav_uint64 currentBytePos = totalSizeInBytes - pWav->bytesRemaining;
+ drwav_uint64 targetBytePos = sample * pWav->bytesPerSample;
+
+ drwav_uint64 offset;
+ if (currentBytePos < targetBytePos) {
+ // Offset forwards.
+ offset = (targetBytePos - currentBytePos);
+ } else {
+ // Offset backwards.
+ if (!drwav_seek_to_first_sample(pWav)) {
+ return DRWAV_FALSE;
+ }
+ offset = targetBytePos;
+ }
+
+ while (offset > 0) {
+ int offset32 = ((offset > INT_MAX) ? INT_MAX : (int)offset);
+ if (!pWav->onSeek(pWav->pUserData, offset32, drwav_seek_origin_current)) {
+ return DRWAV_FALSE;
+ }
+
+ pWav->bytesRemaining -= offset32;
+ offset -= offset32;
+ }
+ }
+
+ return DRWAV_TRUE;
+
+fallback:
+ // This is a generic seek implementation that just continuously reads samples into a temporary buffer. This should work for all supported
+ // formats, but it is not efficient. This should be used as a fall back.
+ if (!drwav_seek_to_first_sample(pWav)) {
+ return DRWAV_FALSE;
+ }
+
+ drwav_int16 devnull[2048];
+ while (sample > 0) {
+ drwav_uint64 samplesToRead = sample;
+ if (samplesToRead > 2048) {
+ samplesToRead = 2048;
+ }
+
+ drwav_uint64 samplesRead = drwav_read_s16(pWav, samplesToRead, devnull);
+ if (samplesRead != samplesToRead) {
+ return DRWAV_FALSE;
+ }
+
+ sample -= samplesRead;
+ }
+
+ return DRWAV_TRUE;
+}
+
+
+size_t drwav_write_raw(drwav* pWav, size_t bytesToWrite, const void* pData)
+{
+ if (pWav == NULL || bytesToWrite == 0 || pData == NULL) {
+ return 0;
+ }
+
+ size_t bytesWritten = pWav->onWrite(pWav->pUserData, pData, bytesToWrite);
+ pWav->dataChunkDataSize += bytesWritten;
+
+ return bytesWritten;
+}
+
+drwav_uint64 drwav_write(drwav* pWav, drwav_uint64 samplesToWrite, const void* pData)
+{
+ if (pWav == NULL || samplesToWrite == 0 || pData == NULL) {
+ return 0;
+ }
+
+ drwav_uint64 bytesToWrite = ((samplesToWrite * pWav->bitsPerSample) / 8);
+ if (bytesToWrite > SIZE_MAX) {
+ return 0;
+ }
+
+ size_t bytesWritten = drwav_write_raw(pWav, (size_t)bytesToWrite, pData);
+ return ((drwav_uint64)bytesWritten * 8) / pWav->bitsPerSample;
+}
+
+
+#ifndef DR_WAV_NO_CONVERSION_API
+static unsigned short g_drwavAlawTable[256] = {
+ 0xEA80, 0xEB80, 0xE880, 0xE980, 0xEE80, 0xEF80, 0xEC80, 0xED80, 0xE280, 0xE380, 0xE080, 0xE180, 0xE680, 0xE780, 0xE480, 0xE580,
+ 0xF540, 0xF5C0, 0xF440, 0xF4C0, 0xF740, 0xF7C0, 0xF640, 0xF6C0, 0xF140, 0xF1C0, 0xF040, 0xF0C0, 0xF340, 0xF3C0, 0xF240, 0xF2C0,
+ 0xAA00, 0xAE00, 0xA200, 0xA600, 0xBA00, 0xBE00, 0xB200, 0xB600, 0x8A00, 0x8E00, 0x8200, 0x8600, 0x9A00, 0x9E00, 0x9200, 0x9600,
+ 0xD500, 0xD700, 0xD100, 0xD300, 0xDD00, 0xDF00, 0xD900, 0xDB00, 0xC500, 0xC700, 0xC100, 0xC300, 0xCD00, 0xCF00, 0xC900, 0xCB00,
+ 0xFEA8, 0xFEB8, 0xFE88, 0xFE98, 0xFEE8, 0xFEF8, 0xFEC8, 0xFED8, 0xFE28, 0xFE38, 0xFE08, 0xFE18, 0xFE68, 0xFE78, 0xFE48, 0xFE58,
+ 0xFFA8, 0xFFB8, 0xFF88, 0xFF98, 0xFFE8, 0xFFF8, 0xFFC8, 0xFFD8, 0xFF28, 0xFF38, 0xFF08, 0xFF18, 0xFF68, 0xFF78, 0xFF48, 0xFF58,
+ 0xFAA0, 0xFAE0, 0xFA20, 0xFA60, 0xFBA0, 0xFBE0, 0xFB20, 0xFB60, 0xF8A0, 0xF8E0, 0xF820, 0xF860, 0xF9A0, 0xF9E0, 0xF920, 0xF960,
+ 0xFD50, 0xFD70, 0xFD10, 0xFD30, 0xFDD0, 0xFDF0, 0xFD90, 0xFDB0, 0xFC50, 0xFC70, 0xFC10, 0xFC30, 0xFCD0, 0xFCF0, 0xFC90, 0xFCB0,
+ 0x1580, 0x1480, 0x1780, 0x1680, 0x1180, 0x1080, 0x1380, 0x1280, 0x1D80, 0x1C80, 0x1F80, 0x1E80, 0x1980, 0x1880, 0x1B80, 0x1A80,
+ 0x0AC0, 0x0A40, 0x0BC0, 0x0B40, 0x08C0, 0x0840, 0x09C0, 0x0940, 0x0EC0, 0x0E40, 0x0FC0, 0x0F40, 0x0CC0, 0x0C40, 0x0DC0, 0x0D40,
+ 0x5600, 0x5200, 0x5E00, 0x5A00, 0x4600, 0x4200, 0x4E00, 0x4A00, 0x7600, 0x7200, 0x7E00, 0x7A00, 0x6600, 0x6200, 0x6E00, 0x6A00,
+ 0x2B00, 0x2900, 0x2F00, 0x2D00, 0x2300, 0x2100, 0x2700, 0x2500, 0x3B00, 0x3900, 0x3F00, 0x3D00, 0x3300, 0x3100, 0x3700, 0x3500,
+ 0x0158, 0x0148, 0x0178, 0x0168, 0x0118, 0x0108, 0x0138, 0x0128, 0x01D8, 0x01C8, 0x01F8, 0x01E8, 0x0198, 0x0188, 0x01B8, 0x01A8,
+ 0x0058, 0x0048, 0x0078, 0x0068, 0x0018, 0x0008, 0x0038, 0x0028, 0x00D8, 0x00C8, 0x00F8, 0x00E8, 0x0098, 0x0088, 0x00B8, 0x00A8,
+ 0x0560, 0x0520, 0x05E0, 0x05A0, 0x0460, 0x0420, 0x04E0, 0x04A0, 0x0760, 0x0720, 0x07E0, 0x07A0, 0x0660, 0x0620, 0x06E0, 0x06A0,
+ 0x02B0, 0x0290, 0x02F0, 0x02D0, 0x0230, 0x0210, 0x0270, 0x0250, 0x03B0, 0x0390, 0x03F0, 0x03D0, 0x0330, 0x0310, 0x0370, 0x0350
+};
+
+static unsigned short g_drwavMulawTable[256] = {
+ 0x8284, 0x8684, 0x8A84, 0x8E84, 0x9284, 0x9684, 0x9A84, 0x9E84, 0xA284, 0xA684, 0xAA84, 0xAE84, 0xB284, 0xB684, 0xBA84, 0xBE84,
+ 0xC184, 0xC384, 0xC584, 0xC784, 0xC984, 0xCB84, 0xCD84, 0xCF84, 0xD184, 0xD384, 0xD584, 0xD784, 0xD984, 0xDB84, 0xDD84, 0xDF84,
+ 0xE104, 0xE204, 0xE304, 0xE404, 0xE504, 0xE604, 0xE704, 0xE804, 0xE904, 0xEA04, 0xEB04, 0xEC04, 0xED04, 0xEE04, 0xEF04, 0xF004,
+ 0xF0C4, 0xF144, 0xF1C4, 0xF244, 0xF2C4, 0xF344, 0xF3C4, 0xF444, 0xF4C4, 0xF544, 0xF5C4, 0xF644, 0xF6C4, 0xF744, 0xF7C4, 0xF844,
+ 0xF8A4, 0xF8E4, 0xF924, 0xF964, 0xF9A4, 0xF9E4, 0xFA24, 0xFA64, 0xFAA4, 0xFAE4, 0xFB24, 0xFB64, 0xFBA4, 0xFBE4, 0xFC24, 0xFC64,
+ 0xFC94, 0xFCB4, 0xFCD4, 0xFCF4, 0xFD14, 0xFD34, 0xFD54, 0xFD74, 0xFD94, 0xFDB4, 0xFDD4, 0xFDF4, 0xFE14, 0xFE34, 0xFE54, 0xFE74,
+ 0xFE8C, 0xFE9C, 0xFEAC, 0xFEBC, 0xFECC, 0xFEDC, 0xFEEC, 0xFEFC, 0xFF0C, 0xFF1C, 0xFF2C, 0xFF3C, 0xFF4C, 0xFF5C, 0xFF6C, 0xFF7C,
+ 0xFF88, 0xFF90, 0xFF98, 0xFFA0, 0xFFA8, 0xFFB0, 0xFFB8, 0xFFC0, 0xFFC8, 0xFFD0, 0xFFD8, 0xFFE0, 0xFFE8, 0xFFF0, 0xFFF8, 0x0000,
+ 0x7D7C, 0x797C, 0x757C, 0x717C, 0x6D7C, 0x697C, 0x657C, 0x617C, 0x5D7C, 0x597C, 0x557C, 0x517C, 0x4D7C, 0x497C, 0x457C, 0x417C,
+ 0x3E7C, 0x3C7C, 0x3A7C, 0x387C, 0x367C, 0x347C, 0x327C, 0x307C, 0x2E7C, 0x2C7C, 0x2A7C, 0x287C, 0x267C, 0x247C, 0x227C, 0x207C,
+ 0x1EFC, 0x1DFC, 0x1CFC, 0x1BFC, 0x1AFC, 0x19FC, 0x18FC, 0x17FC, 0x16FC, 0x15FC, 0x14FC, 0x13FC, 0x12FC, 0x11FC, 0x10FC, 0x0FFC,
+ 0x0F3C, 0x0EBC, 0x0E3C, 0x0DBC, 0x0D3C, 0x0CBC, 0x0C3C, 0x0BBC, 0x0B3C, 0x0ABC, 0x0A3C, 0x09BC, 0x093C, 0x08BC, 0x083C, 0x07BC,
+ 0x075C, 0x071C, 0x06DC, 0x069C, 0x065C, 0x061C, 0x05DC, 0x059C, 0x055C, 0x051C, 0x04DC, 0x049C, 0x045C, 0x041C, 0x03DC, 0x039C,
+ 0x036C, 0x034C, 0x032C, 0x030C, 0x02EC, 0x02CC, 0x02AC, 0x028C, 0x026C, 0x024C, 0x022C, 0x020C, 0x01EC, 0x01CC, 0x01AC, 0x018C,
+ 0x0174, 0x0164, 0x0154, 0x0144, 0x0134, 0x0124, 0x0114, 0x0104, 0x00F4, 0x00E4, 0x00D4, 0x00C4, 0x00B4, 0x00A4, 0x0094, 0x0084,
+ 0x0078, 0x0070, 0x0068, 0x0060, 0x0058, 0x0050, 0x0048, 0x0040, 0x0038, 0x0030, 0x0028, 0x0020, 0x0018, 0x0010, 0x0008, 0x0000
+};
+
+static DRWAV_INLINE drwav_int16 drwav__alaw_to_s16(drwav_uint8 sampleIn)
+{
+ return (short)g_drwavAlawTable[sampleIn];
+}
+
+static DRWAV_INLINE drwav_int16 drwav__mulaw_to_s16(drwav_uint8 sampleIn)
+{
+ return (short)g_drwavMulawTable[sampleIn];
+}
+
+
+
+static void drwav__pcm_to_s16(drwav_int16* pOut, const unsigned char* pIn, size_t totalSampleCount, unsigned short bytesPerSample)
+{
+ // Special case for 8-bit sample data because it's treated as unsigned.
+ if (bytesPerSample == 1) {
+ drwav_u8_to_s16(pOut, pIn, totalSampleCount);
+ return;
+ }
+
+
+ // Slightly more optimal implementation for common formats.
+ if (bytesPerSample == 2) {
+ for (unsigned int i = 0; i < totalSampleCount; ++i) {
+ *pOut++ = ((drwav_int16*)pIn)[i];
+ }
+ return;
+ }
+ if (bytesPerSample == 3) {
+ drwav_s24_to_s16(pOut, pIn, totalSampleCount);
+ return;
+ }
+ if (bytesPerSample == 4) {
+ drwav_s32_to_s16(pOut, (const drwav_int32*)pIn, totalSampleCount);
+ return;
+ }
+
+
+ // Generic, slow converter.
+ for (unsigned int i = 0; i < totalSampleCount; ++i) {
+ unsigned short sample = 0;
+ unsigned short shift = (8 - bytesPerSample) * 8;
+ for (unsigned short j = 0; j < bytesPerSample && j < 2; ++j) {
+ sample |= (unsigned short)(pIn[j]) << shift;
+ shift += 8;
+ }
+
+ pIn += bytesPerSample;
+ *pOut++ = sample;
+ }
+}
+
+static void drwav__ieee_to_s16(drwav_int16* pOut, const unsigned char* pIn, size_t totalSampleCount, unsigned short bytesPerSample)
+{
+ if (bytesPerSample == 4) {
+ drwav_f32_to_s16(pOut, (float*)pIn, totalSampleCount);
+ return;
+ } else {
+ drwav_f64_to_s16(pOut, (double*)pIn, totalSampleCount);
+ return;
+ }
+}
+
+drwav_uint64 drwav_read_s16__pcm(drwav* pWav, drwav_uint64 samplesToRead, drwav_int16* pBufferOut)
+{
+ // Fast path.
+ if (pWav->bytesPerSample == 2) {
+ return drwav_read(pWav, samplesToRead, pBufferOut);
+ }
+
+ drwav_uint64 totalSamplesRead = 0;
+ unsigned char sampleData[4096];
+ while (samplesToRead > 0) {
+ drwav_uint64 samplesRead = drwav_read(pWav, drwav_min(samplesToRead, sizeof(sampleData)/pWav->bytesPerSample), sampleData);
+ if (samplesRead == 0) {
+ break;
+ }
+
+ drwav__pcm_to_s16(pBufferOut, sampleData, (size_t)samplesRead, pWav->bytesPerSample);
+
+ pBufferOut += samplesRead;
+ samplesToRead -= samplesRead;
+ totalSamplesRead += samplesRead;
+ }
+
+ return totalSamplesRead;
+}
+
+drwav_uint64 drwav_read_s16__msadpcm(drwav* pWav, drwav_uint64 samplesToRead, drwav_int16* pBufferOut)
+{
+ drwav_assert(pWav != NULL);
+ drwav_assert(samplesToRead > 0);
+ drwav_assert(pBufferOut != NULL);
+
+ // TODO: Lots of room for optimization here.
+
+ drwav_uint64 totalSamplesRead = 0;
+
+ while (samplesToRead > 0 && pWav->compressed.iCurrentSample < pWav->totalSampleCount) {
+ // If there are no cached samples we need to load a new block.
+ if (pWav->msadpcm.cachedSampleCount == 0 && pWav->msadpcm.bytesRemainingInBlock == 0) {
+ if (pWav->channels == 1) {
+ // Mono.
+ drwav_uint8 header[7];
+ if (pWav->onRead(pWav->pUserData, header, sizeof(header)) != sizeof(header)) {
+ return totalSamplesRead;
+ }
+ pWav->msadpcm.bytesRemainingInBlock = pWav->fmt.blockAlign - sizeof(header);
+
+ pWav->msadpcm.predictor[0] = header[0];
+ pWav->msadpcm.delta[0] = drwav__bytes_to_s16(header + 1);
+ pWav->msadpcm.prevSamples[0][1] = (drwav_int32)drwav__bytes_to_s16(header + 3);
+ pWav->msadpcm.prevSamples[0][0] = (drwav_int32)drwav__bytes_to_s16(header + 5);
+ pWav->msadpcm.cachedSamples[2] = pWav->msadpcm.prevSamples[0][0];
+ pWav->msadpcm.cachedSamples[3] = pWav->msadpcm.prevSamples[0][1];
+ pWav->msadpcm.cachedSampleCount = 2;
+ } else {
+ // Stereo.
+ drwav_uint8 header[14];
+ if (pWav->onRead(pWav->pUserData, header, sizeof(header)) != sizeof(header)) {
+ return totalSamplesRead;
+ }
+ pWav->msadpcm.bytesRemainingInBlock = pWav->fmt.blockAlign - sizeof(header);
+
+ pWav->msadpcm.predictor[0] = header[0];
+ pWav->msadpcm.predictor[1] = header[1];
+ pWav->msadpcm.delta[0] = drwav__bytes_to_s16(header + 2);
+ pWav->msadpcm.delta[1] = drwav__bytes_to_s16(header + 4);
+ pWav->msadpcm.prevSamples[0][1] = (drwav_int32)drwav__bytes_to_s16(header + 6);
+ pWav->msadpcm.prevSamples[1][1] = (drwav_int32)drwav__bytes_to_s16(header + 8);
+ pWav->msadpcm.prevSamples[0][0] = (drwav_int32)drwav__bytes_to_s16(header + 10);
+ pWav->msadpcm.prevSamples[1][0] = (drwav_int32)drwav__bytes_to_s16(header + 12);
+
+ pWav->msadpcm.cachedSamples[0] = pWav->msadpcm.prevSamples[0][0];
+ pWav->msadpcm.cachedSamples[1] = pWav->msadpcm.prevSamples[1][0];
+ pWav->msadpcm.cachedSamples[2] = pWav->msadpcm.prevSamples[0][1];
+ pWav->msadpcm.cachedSamples[3] = pWav->msadpcm.prevSamples[1][1];
+ pWav->msadpcm.cachedSampleCount = 4;
+ }
+ }
+
+ // Output anything that's cached.
+ while (samplesToRead > 0 && pWav->msadpcm.cachedSampleCount > 0 && pWav->compressed.iCurrentSample < pWav->totalSampleCount) {
+ pBufferOut[0] = (drwav_int16)pWav->msadpcm.cachedSamples[drwav_countof(pWav->msadpcm.cachedSamples) - pWav->msadpcm.cachedSampleCount];
+ pWav->msadpcm.cachedSampleCount -= 1;
+
+ pBufferOut += 1;
+ samplesToRead -= 1;
+ totalSamplesRead += 1;
+ pWav->compressed.iCurrentSample += 1;
+ }
+
+ if (samplesToRead == 0) {
+ return totalSamplesRead;
+ }
+
+
+ // If there's nothing left in the cache, just go ahead and load more. If there's nothing left to load in the current block we just continue to the next
+ // loop iteration which will trigger the loading of a new block.
+ if (pWav->msadpcm.cachedSampleCount == 0) {
+ if (pWav->msadpcm.bytesRemainingInBlock == 0) {
+ continue;
+ } else {
+ drwav_uint8 nibbles;
+ if (pWav->onRead(pWav->pUserData, &nibbles, 1) != 1) {
+ return totalSamplesRead;
+ }
+ pWav->msadpcm.bytesRemainingInBlock -= 1;
+
+ // TODO: Optimize away these if statements.
+ drwav_int32 nibble0 = ((nibbles & 0xF0) >> 4); if ((nibbles & 0x80)) { nibble0 |= 0xFFFFFFF0UL; }
+ drwav_int32 nibble1 = ((nibbles & 0x0F) >> 0); if ((nibbles & 0x08)) { nibble1 |= 0xFFFFFFF0UL; }
+
+ static drwav_int32 adaptationTable[] = {
+ 230, 230, 230, 230, 307, 409, 512, 614,
+ 768, 614, 512, 409, 307, 230, 230, 230
+ };
+ static drwav_int32 coeff1Table[] = { 256, 512, 0, 192, 240, 460, 392 };
+ static drwav_int32 coeff2Table[] = { 0, -256, 0, 64, 0, -208, -232 };
+
+ if (pWav->channels == 1) {
+ // Mono.
+ drwav_int32 newSample0;
+ newSample0 = ((pWav->msadpcm.prevSamples[0][1] * coeff1Table[pWav->msadpcm.predictor[0]]) + (pWav->msadpcm.prevSamples[0][0] * coeff2Table[pWav->msadpcm.predictor[0]])) >> 8;
+ newSample0 += nibble0 * pWav->msadpcm.delta[0];
+ newSample0 = drwav_clamp(newSample0, -32768, 32767);
+
+ pWav->msadpcm.delta[0] = (adaptationTable[((nibbles & 0xF0) >> 4)] * pWav->msadpcm.delta[0]) >> 8;
+ if (pWav->msadpcm.delta[0] < 16) {
+ pWav->msadpcm.delta[0] = 16;
+ }
+
+ pWav->msadpcm.prevSamples[0][0] = pWav->msadpcm.prevSamples[0][1];
+ pWav->msadpcm.prevSamples[0][1] = newSample0;
+
+
+ drwav_int32 newSample1;
+ newSample1 = ((pWav->msadpcm.prevSamples[0][1] * coeff1Table[pWav->msadpcm.predictor[0]]) + (pWav->msadpcm.prevSamples[0][0] * coeff2Table[pWav->msadpcm.predictor[0]])) >> 8;
+ newSample1 += nibble1 * pWav->msadpcm.delta[0];
+ newSample1 = drwav_clamp(newSample1, -32768, 32767);
+
+ pWav->msadpcm.delta[0] = (adaptationTable[((nibbles & 0x0F) >> 0)] * pWav->msadpcm.delta[0]) >> 8;
+ if (pWav->msadpcm.delta[0] < 16) {
+ pWav->msadpcm.delta[0] = 16;
+ }
+
+ pWav->msadpcm.prevSamples[0][0] = pWav->msadpcm.prevSamples[0][1];
+ pWav->msadpcm.prevSamples[0][1] = newSample1;
+
+
+ pWav->msadpcm.cachedSamples[2] = newSample0;
+ pWav->msadpcm.cachedSamples[3] = newSample1;
+ pWav->msadpcm.cachedSampleCount = 2;
+ } else {
+ // Stereo.
+
+ // Left.
+ drwav_int32 newSample0;
+ newSample0 = ((pWav->msadpcm.prevSamples[0][1] * coeff1Table[pWav->msadpcm.predictor[0]]) + (pWav->msadpcm.prevSamples[0][0] * coeff2Table[pWav->msadpcm.predictor[0]])) >> 8;
+ newSample0 += nibble0 * pWav->msadpcm.delta[0];
+ newSample0 = drwav_clamp(newSample0, -32768, 32767);
+
+ pWav->msadpcm.delta[0] = (adaptationTable[((nibbles & 0xF0) >> 4)] * pWav->msadpcm.delta[0]) >> 8;
+ if (pWav->msadpcm.delta[0] < 16) {
+ pWav->msadpcm.delta[0] = 16;
+ }
+
+ pWav->msadpcm.prevSamples[0][0] = pWav->msadpcm.prevSamples[0][1];
+ pWav->msadpcm.prevSamples[0][1] = newSample0;
+
+
+ // Right.
+ drwav_int32 newSample1;
+ newSample1 = ((pWav->msadpcm.prevSamples[1][1] * coeff1Table[pWav->msadpcm.predictor[1]]) + (pWav->msadpcm.prevSamples[1][0] * coeff2Table[pWav->msadpcm.predictor[1]])) >> 8;
+ newSample1 += nibble1 * pWav->msadpcm.delta[1];
+ newSample1 = drwav_clamp(newSample1, -32768, 32767);
+
+ pWav->msadpcm.delta[1] = (adaptationTable[((nibbles & 0x0F) >> 0)] * pWav->msadpcm.delta[1]) >> 8;
+ if (pWav->msadpcm.delta[1] < 16) {
+ pWav->msadpcm.delta[1] = 16;
+ }
+
+ pWav->msadpcm.prevSamples[1][0] = pWav->msadpcm.prevSamples[1][1];
+ pWav->msadpcm.prevSamples[1][1] = newSample1;
+
+ pWav->msadpcm.cachedSamples[2] = newSample0;
+ pWav->msadpcm.cachedSamples[3] = newSample1;
+ pWav->msadpcm.cachedSampleCount = 2;
+ }
+ }
+ }
+ }
+
+ return totalSamplesRead;
+}
+
+drwav_uint64 drwav_read_s16__ima(drwav* pWav, drwav_uint64 samplesToRead, drwav_int16* pBufferOut)
+{
+ drwav_assert(pWav != NULL);
+ drwav_assert(samplesToRead > 0);
+ drwav_assert(pBufferOut != NULL);
+
+ // TODO: Lots of room for optimization here.
+
+ drwav_uint64 totalSamplesRead = 0;
+
+ while (samplesToRead > 0 && pWav->compressed.iCurrentSample < pWav->totalSampleCount) {
+ // If there are no cached samples we need to load a new block.
+ if (pWav->ima.cachedSampleCount == 0 && pWav->ima.bytesRemainingInBlock == 0) {
+ if (pWav->channels == 1) {
+ // Mono.
+ drwav_uint8 header[4];
+ if (pWav->onRead(pWav->pUserData, header, sizeof(header)) != sizeof(header)) {
+ return totalSamplesRead;
+ }
+ pWav->ima.bytesRemainingInBlock = pWav->fmt.blockAlign - sizeof(header);
+
+ pWav->ima.predictor[0] = drwav__bytes_to_s16(header + 0);
+ pWav->ima.stepIndex[0] = header[2];
+ pWav->ima.cachedSamples[drwav_countof(pWav->ima.cachedSamples) - 1] = pWav->ima.predictor[0];
+ pWav->ima.cachedSampleCount = 1;
+ } else {
+ // Stereo.
+ drwav_uint8 header[8];
+ if (pWav->onRead(pWav->pUserData, header, sizeof(header)) != sizeof(header)) {
+ return totalSamplesRead;
+ }
+ pWav->ima.bytesRemainingInBlock = pWav->fmt.blockAlign - sizeof(header);
+
+ pWav->ima.predictor[0] = drwav__bytes_to_s16(header + 0);
+ pWav->ima.stepIndex[0] = header[2];
+ pWav->ima.predictor[1] = drwav__bytes_to_s16(header + 4);
+ pWav->ima.stepIndex[1] = header[6];
+
+ pWav->ima.cachedSamples[drwav_countof(pWav->ima.cachedSamples) - 2] = pWav->ima.predictor[0];
+ pWav->ima.cachedSamples[drwav_countof(pWav->ima.cachedSamples) - 1] = pWav->ima.predictor[1];
+ pWav->ima.cachedSampleCount = 2;
+ }
+ }
+
+ // Output anything that's cached.
+ while (samplesToRead > 0 && pWav->ima.cachedSampleCount > 0 && pWav->compressed.iCurrentSample < pWav->totalSampleCount) {
+ pBufferOut[0] = (drwav_int16)pWav->ima.cachedSamples[drwav_countof(pWav->ima.cachedSamples) - pWav->ima.cachedSampleCount];
+ pWav->ima.cachedSampleCount -= 1;
+
+ pBufferOut += 1;
+ samplesToRead -= 1;
+ totalSamplesRead += 1;
+ pWav->compressed.iCurrentSample += 1;
+ }
+
+ if (samplesToRead == 0) {
+ return totalSamplesRead;
+ }
+
+ // If there's nothing left in the cache, just go ahead and load more. If there's nothing left to load in the current block we just continue to the next
+ // loop iteration which will trigger the loading of a new block.
+ if (pWav->ima.cachedSampleCount == 0) {
+ if (pWav->ima.bytesRemainingInBlock == 0) {
+ continue;
+ } else {
+ static drwav_int32 indexTable[16] = {
+ -1, -1, -1, -1, 2, 4, 6, 8,
+ -1, -1, -1, -1, 2, 4, 6, 8
+ };
+
+ static drwav_int32 stepTable[89] = {
+ 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
+ 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
+ 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
+ 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
+ 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
+ 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
+ 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
+ 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
+ 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
+ };
+
+ // From what I can tell with stereo streams, it looks like every 4 bytes (8 samples) is for one channel. So it goes 4 bytes for the
+ // left channel, 4 bytes for the right channel.
+ pWav->ima.cachedSampleCount = 8 * pWav->channels;
+ for (drwav_uint32 iChannel = 0; iChannel < pWav->channels; ++iChannel) {
+ drwav_uint8 nibbles[4];
+ if (pWav->onRead(pWav->pUserData, &nibbles, 4) != 4) {
+ return totalSamplesRead;
+ }
+ pWav->ima.bytesRemainingInBlock -= 4;
+
+ for (drwav_uint32 iByte = 0; iByte < 4; ++iByte) {
+ drwav_uint8 nibble0 = ((nibbles[iByte] & 0x0F) >> 0);
+ drwav_uint8 nibble1 = ((nibbles[iByte] & 0xF0) >> 4);
+
+ drwav_int32 step = stepTable[pWav->ima.stepIndex[iChannel]];
+ drwav_int32 predictor = pWav->ima.predictor[iChannel];
+
+ drwav_int32 diff = step >> 3;
+ if (nibble0 & 1) diff += step >> 2;
+ if (nibble0 & 2) diff += step >> 1;
+ if (nibble0 & 4) diff += step;
+ if (nibble0 & 8) diff = -diff;
+
+ predictor = drwav_clamp(predictor + diff, -32768, 32767);
+ pWav->ima.predictor[iChannel] = predictor;
+ pWav->ima.stepIndex[iChannel] = drwav_clamp(pWav->ima.stepIndex[iChannel] + indexTable[nibble0], 0, (drwav_int32)drwav_countof(stepTable)-1);
+ pWav->ima.cachedSamples[(drwav_countof(pWav->ima.cachedSamples) - pWav->ima.cachedSampleCount) + (iByte*2+0)*pWav->channels + iChannel] = predictor;
+
+
+ step = stepTable[pWav->ima.stepIndex[iChannel]];
+ predictor = pWav->ima.predictor[iChannel];
+
+ diff = step >> 3;
+ if (nibble1 & 1) diff += step >> 2;
+ if (nibble1 & 2) diff += step >> 1;
+ if (nibble1 & 4) diff += step;
+ if (nibble1 & 8) diff = -diff;
+
+ predictor = drwav_clamp(predictor + diff, -32768, 32767);
+ pWav->ima.predictor[iChannel] = predictor;
+ pWav->ima.stepIndex[iChannel] = drwav_clamp(pWav->ima.stepIndex[iChannel] + indexTable[nibble1], 0, (drwav_int32)drwav_countof(stepTable)-1);
+ pWav->ima.cachedSamples[(drwav_countof(pWav->ima.cachedSamples) - pWav->ima.cachedSampleCount) + (iByte*2+1)*pWav->channels + iChannel] = predictor;
+ }
+ }
+ }
+ }
+ }
+
+ return totalSamplesRead;
+}
+
+drwav_uint64 drwav_read_s16__ieee(drwav* pWav, drwav_uint64 samplesToRead, drwav_int16* pBufferOut)
+{
+ drwav_uint64 totalSamplesRead = 0;
+ unsigned char sampleData[4096];
+ while (samplesToRead > 0) {
+ drwav_uint64 samplesRead = drwav_read(pWav, drwav_min(samplesToRead, sizeof(sampleData)/pWav->bytesPerSample), sampleData);
+ if (samplesRead == 0) {
+ break;
+ }
+
+ drwav__ieee_to_s16(pBufferOut, sampleData, (size_t)samplesRead, pWav->bytesPerSample);
+
+ pBufferOut += samplesRead;
+ samplesToRead -= samplesRead;
+ totalSamplesRead += samplesRead;
+ }
+
+ return totalSamplesRead;
+}
+
+drwav_uint64 drwav_read_s16__alaw(drwav* pWav, drwav_uint64 samplesToRead, drwav_int16* pBufferOut)
+{
+ drwav_uint64 totalSamplesRead = 0;
+ unsigned char sampleData[4096];
+ while (samplesToRead > 0) {
+ drwav_uint64 samplesRead = drwav_read(pWav, drwav_min(samplesToRead, sizeof(sampleData)/pWav->bytesPerSample), sampleData);
+ if (samplesRead == 0) {
+ break;
+ }
+
+ drwav_alaw_to_s16(pBufferOut, sampleData, (size_t)samplesRead);
+
+ pBufferOut += samplesRead;
+ samplesToRead -= samplesRead;
+ totalSamplesRead += samplesRead;
+ }
+
+ return totalSamplesRead;
+}
+
+drwav_uint64 drwav_read_s16__mulaw(drwav* pWav, drwav_uint64 samplesToRead, drwav_int16* pBufferOut)
+{
+ drwav_uint64 totalSamplesRead = 0;
+ unsigned char sampleData[4096];
+ while (samplesToRead > 0) {
+ drwav_uint64 samplesRead = drwav_read(pWav, drwav_min(samplesToRead, sizeof(sampleData)/pWav->bytesPerSample), sampleData);
+ if (samplesRead == 0) {
+ break;
+ }
+
+ drwav_mulaw_to_s16(pBufferOut, sampleData, (size_t)samplesRead);
+
+ pBufferOut += samplesRead;
+ samplesToRead -= samplesRead;
+ totalSamplesRead += samplesRead;
+ }
+
+ return totalSamplesRead;
+}
+
+drwav_uint64 drwav_read_s16(drwav* pWav, drwav_uint64 samplesToRead, drwav_int16* pBufferOut)
+{
+ if (pWav == NULL || samplesToRead == 0 || pBufferOut == NULL) {
+ return 0;
+ }
+
+ // Don't try to read more samples than can potentially fit in the output buffer.
+ if (samplesToRead * sizeof(drwav_int16) > SIZE_MAX) {
+ samplesToRead = SIZE_MAX / sizeof(drwav_int16);
+ }
+
+ if (pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM) {
+ return drwav_read_s16__pcm(pWav, samplesToRead, pBufferOut);
+ }
+
+ if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) {
+ return drwav_read_s16__msadpcm(pWav, samplesToRead, pBufferOut);
+ }
+
+ if (pWav->translatedFormatTag == DR_WAVE_FORMAT_IEEE_FLOAT) {
+ return drwav_read_s16__ieee(pWav, samplesToRead, pBufferOut);
+ }
+
+ if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ALAW) {
+ return drwav_read_s16__alaw(pWav, samplesToRead, pBufferOut);
+ }
+
+ if (pWav->translatedFormatTag == DR_WAVE_FORMAT_MULAW) {
+ return drwav_read_s16__mulaw(pWav, samplesToRead, pBufferOut);
+ }
+
+ if (pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
+ return drwav_read_s16__ima(pWav, samplesToRead, pBufferOut);
+ }
+
+ return 0;
+}
+
+void drwav_u8_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount)
+{
+ int r;
+ for (size_t i = 0; i < sampleCount; ++i) {
+ int x = pIn[i];
+ r = x - 128;
+ r = r << 8;
+ pOut[i] = (short)r;
+ }
+}
+
+void drwav_s24_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount)
+{
+ int r;
+ for (size_t i = 0; i < sampleCount; ++i) {
+ int x = ((int)(((unsigned int)(((unsigned char*)pIn)[i*3+0]) << 8) | ((unsigned int)(((unsigned char*)pIn)[i*3+1]) << 16) | ((unsigned int)(((unsigned char*)pIn)[i*3+2])) << 24)) >> 8;
+ r = x >> 8;
+ pOut[i] = (short)r;
+ }
+}
+
+void drwav_s32_to_s16(drwav_int16* pOut, const drwav_int32* pIn, size_t sampleCount)
+{
+ int r;
+ for (size_t i = 0; i < sampleCount; ++i) {
+ int x = pIn[i];
+ r = x >> 16;
+ pOut[i] = (short)r;
+ }
+}
+
+void drwav_f32_to_s16(drwav_int16* pOut, const float* pIn, size_t sampleCount)
+{
+ int r;
+ for (size_t i = 0; i < sampleCount; ++i) {
+ float x = pIn[i];
+ float c;
+ c = ((x < -1) ? -1 : ((x > 1) ? 1 : x));
+ c = c + 1;
+ r = (int)(c * 32767.5f);
+ r = r - 32768;
+ pOut[i] = (short)r;
+ }
+}
+
+void drwav_f64_to_s16(drwav_int16* pOut, const double* pIn, size_t sampleCount)
+{
+ int r;
+ for (size_t i = 0; i < sampleCount; ++i) {
+ double x = pIn[i];
+ double c;
+ c = ((x < -1) ? -1 : ((x > 1) ? 1 : x));
+ c = c + 1;
+ r = (int)(c * 32767.5);
+ r = r - 32768;
+ pOut[i] = (short)r;
+ }
+}
+
+void drwav_alaw_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount)
+{
+ for (size_t i = 0; i < sampleCount; ++i) {
+ pOut[i] = drwav__alaw_to_s16(pIn[i]);
+ }
+}
+
+void drwav_mulaw_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount)
+{
+ for (size_t i = 0; i < sampleCount; ++i) {
+ pOut[i] = drwav__mulaw_to_s16(pIn[i]);
+ }
+}
+
+
+
+static void drwav__pcm_to_f32(float* pOut, const unsigned char* pIn, size_t sampleCount, unsigned short bytesPerSample)
+{
+ // Special case for 8-bit sample data because it's treated as unsigned.
+ if (bytesPerSample == 1) {
+ drwav_u8_to_f32(pOut, pIn, sampleCount);
+ return;
+ }
+
+ // Slightly more optimal implementation for common formats.
+ if (bytesPerSample == 2) {
+ drwav_s16_to_f32(pOut, (const drwav_int16*)pIn, sampleCount);
+ return;
+ }
+ if (bytesPerSample == 3) {
+ drwav_s24_to_f32(pOut, pIn, sampleCount);
+ return;
+ }
+ if (bytesPerSample == 4) {
+ drwav_s32_to_f32(pOut, (const drwav_int32*)pIn, sampleCount);
+ return;
+ }
+
+ // Generic, slow converter.
+ for (unsigned int i = 0; i < sampleCount; ++i) {
+ unsigned int sample = 0;
+ unsigned int shift = (8 - bytesPerSample) * 8;
+ for (unsigned short j = 0; j < bytesPerSample && j < 4; ++j) {
+ sample |= (unsigned int)(pIn[j]) << shift;
+ shift += 8;
+ }
+
+ pIn += bytesPerSample;
+ *pOut++ = (float)((int)sample / 2147483648.0);
+ }
+}
+
+static void drwav__ieee_to_f32(float* pOut, const unsigned char* pIn, size_t sampleCount, unsigned short bytesPerSample)
+{
+ if (bytesPerSample == 4) {
+ for (unsigned int i = 0; i < sampleCount; ++i) {
+ *pOut++ = ((float*)pIn)[i];
+ }
+ return;
+ } else {
+ drwav_f64_to_f32(pOut, (double*)pIn, sampleCount);
+ return;
+ }
+}
+
+
+drwav_uint64 drwav_read_f32__pcm(drwav* pWav, drwav_uint64 samplesToRead, float* pBufferOut)
+{
+ drwav_uint64 totalSamplesRead = 0;
+ unsigned char sampleData[4096];
+ while (samplesToRead > 0) {
+ drwav_uint64 samplesRead = drwav_read(pWav, drwav_min(samplesToRead, sizeof(sampleData)/pWav->bytesPerSample), sampleData);
+ if (samplesRead == 0) {
+ break;
+ }
+
+ drwav__pcm_to_f32(pBufferOut, sampleData, (size_t)samplesRead, pWav->bytesPerSample);
+ pBufferOut += samplesRead;
+
+ samplesToRead -= samplesRead;
+ totalSamplesRead += samplesRead;
+ }
+
+ return totalSamplesRead;
+}
+
+drwav_uint64 drwav_read_f32__msadpcm(drwav* pWav, drwav_uint64 samplesToRead, float* pBufferOut)
+{
+ // We're just going to borrow the implementation from the drwav_read_s16() since ADPCM is a little bit more complicated than other formats and I don't
+ // want to duplicate that code.
+ drwav_uint64 totalSamplesRead = 0;
+ drwav_int16 samples16[2048];
+ while (samplesToRead > 0) {
+ drwav_uint64 samplesRead = drwav_read_s16(pWav, drwav_min(samplesToRead, 2048), samples16);
+ if (samplesRead == 0) {
+ break;
+ }
+
+ drwav_s16_to_f32(pBufferOut, samples16, (size_t)samplesRead); // <-- Safe cast because we're clamping to 2048.
+
+ pBufferOut += samplesRead;
+ samplesToRead -= samplesRead;
+ totalSamplesRead += samplesRead;
+ }
+
+ return totalSamplesRead;
+}
+
+drwav_uint64 drwav_read_f32__ima(drwav* pWav, drwav_uint64 samplesToRead, float* pBufferOut)
+{
+ // We're just going to borrow the implementation from the drwav_read_s16() since IMA-ADPCM is a little bit more complicated than other formats and I don't
+ // want to duplicate that code.
+ drwav_uint64 totalSamplesRead = 0;
+ drwav_int16 samples16[2048];
+ while (samplesToRead > 0) {
+ drwav_uint64 samplesRead = drwav_read_s16(pWav, drwav_min(samplesToRead, 2048), samples16);
+ if (samplesRead == 0) {
+ break;
+ }
+
+ drwav_s16_to_f32(pBufferOut, samples16, (size_t)samplesRead); // <-- Safe cast because we're clamping to 2048.
+
+ pBufferOut += samplesRead;
+ samplesToRead -= samplesRead;
+ totalSamplesRead += samplesRead;
+ }
+
+ return totalSamplesRead;
+}
+
+drwav_uint64 drwav_read_f32__ieee(drwav* pWav, drwav_uint64 samplesToRead, float* pBufferOut)
+{
+ // Fast path.
+ if (pWav->translatedFormatTag == DR_WAVE_FORMAT_IEEE_FLOAT && pWav->bytesPerSample == 4) {
+ return drwav_read(pWav, samplesToRead, pBufferOut);
+ }
+
+ drwav_uint64 totalSamplesRead = 0;
+ unsigned char sampleData[4096];
+ while (samplesToRead > 0) {
+ drwav_uint64 samplesRead = drwav_read(pWav, drwav_min(samplesToRead, sizeof(sampleData)/pWav->bytesPerSample), sampleData);
+ if (samplesRead == 0) {
+ break;
+ }
+
+ drwav__ieee_to_f32(pBufferOut, sampleData, (size_t)samplesRead, pWav->bytesPerSample);
+
+ pBufferOut += samplesRead;
+ samplesToRead -= samplesRead;
+ totalSamplesRead += samplesRead;
+ }
+
+ return totalSamplesRead;
+}
+
+drwav_uint64 drwav_read_f32__alaw(drwav* pWav, drwav_uint64 samplesToRead, float* pBufferOut)
+{
+ drwav_uint64 totalSamplesRead = 0;
+ unsigned char sampleData[4096];
+ while (samplesToRead > 0) {
+ drwav_uint64 samplesRead = drwav_read(pWav, drwav_min(samplesToRead, sizeof(sampleData)/pWav->bytesPerSample), sampleData);
+ if (samplesRead == 0) {
+ break;
+ }
+
+ drwav_alaw_to_f32(pBufferOut, sampleData, (size_t)samplesRead);
+
+ pBufferOut += samplesRead;
+ samplesToRead -= samplesRead;
+ totalSamplesRead += samplesRead;
+ }
+
+ return totalSamplesRead;
+}
+
+drwav_uint64 drwav_read_f32__mulaw(drwav* pWav, drwav_uint64 samplesToRead, float* pBufferOut)
+{
+ drwav_uint64 totalSamplesRead = 0;
+ unsigned char sampleData[4096];
+ while (samplesToRead > 0) {
+ drwav_uint64 samplesRead = drwav_read(pWav, drwav_min(samplesToRead, sizeof(sampleData)/pWav->bytesPerSample), sampleData);
+ if (samplesRead == 0) {
+ break;
+ }
+
+ drwav_mulaw_to_f32(pBufferOut, sampleData, (size_t)samplesRead);
+
+ pBufferOut += samplesRead;
+ samplesToRead -= samplesRead;
+ totalSamplesRead += samplesRead;
+ }
+
+ return totalSamplesRead;
+}
+
+drwav_uint64 drwav_read_f32(drwav* pWav, drwav_uint64 samplesToRead, float* pBufferOut)
+{
+ if (pWav == NULL || samplesToRead == 0 || pBufferOut == NULL) {
+ return 0;
+ }
+
+ // Don't try to read more samples than can potentially fit in the output buffer.
+ if (samplesToRead * sizeof(float) > SIZE_MAX) {
+ samplesToRead = SIZE_MAX / sizeof(float);
+ }
+
+ if (pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM) {
+ return drwav_read_f32__pcm(pWav, samplesToRead, pBufferOut);
+ }
+
+ if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) {
+ return drwav_read_f32__msadpcm(pWav, samplesToRead, pBufferOut);
+ }
+
+ if (pWav->translatedFormatTag == DR_WAVE_FORMAT_IEEE_FLOAT) {
+ return drwav_read_f32__ieee(pWav, samplesToRead, pBufferOut);
+ }
+
+ if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ALAW) {
+ return drwav_read_f32__alaw(pWav, samplesToRead, pBufferOut);
+ }
+
+ if (pWav->translatedFormatTag == DR_WAVE_FORMAT_MULAW) {
+ return drwav_read_f32__mulaw(pWav, samplesToRead, pBufferOut);
+ }
+
+ if (pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
+ return drwav_read_f32__ima(pWav, samplesToRead, pBufferOut);
+ }
+
+ return 0;
+}
+
+void drwav_u8_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount)
+{
+ if (pOut == NULL || pIn == NULL) {
+ return;
+ }
+
+#ifdef DR_WAV_LIBSNDFILE_COMPAT
+ // It appears libsndfile uses slightly different logic for the u8 -> f32 conversion to dr_wav, which in my opinion is incorrect. It appears
+ // libsndfile performs the conversion something like "f32 = (u8 / 256) * 2 - 1", however I think it should be "f32 = (u8 / 255) * 2 - 1" (note
+ // the divisor of 256 vs 255). I use libsndfile as a benchmark for testing, so I'm therefore leaving this block here just for my automated
+ // correctness testing. This is disabled by default.
+ for (size_t i = 0; i < sampleCount; ++i) {
+ *pOut++ = (pIn[i] / 256.0f) * 2 - 1;
+ }
+#else
+ for (size_t i = 0; i < sampleCount; ++i) {
+ *pOut++ = (pIn[i] / 255.0f) * 2 - 1;
+ }
+#endif
+}
+
+void drwav_s16_to_f32(float* pOut, const drwav_int16* pIn, size_t sampleCount)
+{
+ if (pOut == NULL || pIn == NULL) {
+ return;
+ }
+
+ for (size_t i = 0; i < sampleCount; ++i) {
+ *pOut++ = pIn[i] / 32768.0f;
+ }
+}
+
+void drwav_s24_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount)
+{
+ if (pOut == NULL || pIn == NULL) {
+ return;
+ }
+
+ for (size_t i = 0; i < sampleCount; ++i) {
+ unsigned int s0 = pIn[i*3 + 0];
+ unsigned int s1 = pIn[i*3 + 1];
+ unsigned int s2 = pIn[i*3 + 2];
+
+ int sample32 = (int)((s0 << 8) | (s1 << 16) | (s2 << 24));
+ *pOut++ = (float)(sample32 / 2147483648.0);
+ }
+}
+
+void drwav_s32_to_f32(float* pOut, const drwav_int32* pIn, size_t sampleCount)
+{
+ if (pOut == NULL || pIn == NULL) {
+ return;
+ }
+
+ for (size_t i = 0; i < sampleCount; ++i) {
+ *pOut++ = (float)(pIn[i] / 2147483648.0);
+ }
+}
+
+void drwav_f64_to_f32(float* pOut, const double* pIn, size_t sampleCount)
+{
+ if (pOut == NULL || pIn == NULL) {
+ return;
+ }
+
+ for (size_t i = 0; i < sampleCount; ++i) {
+ *pOut++ = (float)pIn[i];
+ }
+}
+
+void drwav_alaw_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount)
+{
+ if (pOut == NULL || pIn == NULL) {
+ return;
+ }
+
+ for (size_t i = 0; i < sampleCount; ++i) {
+ *pOut++ = drwav__alaw_to_s16(pIn[i]) / 32768.0f;
+ }
+}
+
+void drwav_mulaw_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount)
+{
+ if (pOut == NULL || pIn == NULL) {
+ return;
+ }
+
+ for (size_t i = 0; i < sampleCount; ++i) {
+ *pOut++ = drwav__mulaw_to_s16(pIn[i]) / 32768.0f;
+ }
+}
+
+
+
+static void drwav__pcm_to_s32(drwav_int32* pOut, const unsigned char* pIn, size_t totalSampleCount, unsigned short bytesPerSample)
+{
+ // Special case for 8-bit sample data because it's treated as unsigned.
+ if (bytesPerSample == 1) {
+ drwav_u8_to_s32(pOut, pIn, totalSampleCount);
+ return;
+ }
+
+ // Slightly more optimal implementation for common formats.
+ if (bytesPerSample == 2) {
+ drwav_s16_to_s32(pOut, (const drwav_int16*)pIn, totalSampleCount);
+ return;
+ }
+ if (bytesPerSample == 3) {
+ drwav_s24_to_s32(pOut, pIn, totalSampleCount);
+ return;
+ }
+ if (bytesPerSample == 4) {
+ for (unsigned int i = 0; i < totalSampleCount; ++i) {
+ *pOut++ = ((drwav_int32*)pIn)[i];
+ }
+ return;
+ }
+
+ // Generic, slow converter.
+ for (unsigned int i = 0; i < totalSampleCount; ++i) {
+ unsigned int sample = 0;
+ unsigned int shift = (8 - bytesPerSample) * 8;
+ for (unsigned short j = 0; j < bytesPerSample && j < 4; ++j) {
+ sample |= (unsigned int)(pIn[j]) << shift;
+ shift += 8;
+ }
+
+ pIn += bytesPerSample;
+ *pOut++ = sample;
+ }
+}
+
+static void drwav__ieee_to_s32(drwav_int32* pOut, const unsigned char* pIn, size_t totalSampleCount, unsigned short bytesPerSample)
+{
+ if (bytesPerSample == 4) {
+ drwav_f32_to_s32(pOut, (float*)pIn, totalSampleCount);
+ return;
+ } else {
+ drwav_f64_to_s32(pOut, (double*)pIn, totalSampleCount);
+ return;
+ }
+}
+
+
+drwav_uint64 drwav_read_s32__pcm(drwav* pWav, drwav_uint64 samplesToRead, drwav_int32* pBufferOut)
+{
+ // Fast path.
+ if (pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM && pWav->bytesPerSample == 4) {
+ return drwav_read(pWav, samplesToRead, pBufferOut);
+ }
+
+ drwav_uint64 totalSamplesRead = 0;
+ unsigned char sampleData[4096];
+ while (samplesToRead > 0) {
+ drwav_uint64 samplesRead = drwav_read(pWav, drwav_min(samplesToRead, sizeof(sampleData)/pWav->bytesPerSample), sampleData);
+ if (samplesRead == 0) {
+ break;
+ }
+
+ drwav__pcm_to_s32(pBufferOut, sampleData, (size_t)samplesRead, pWav->bytesPerSample);
+
+ pBufferOut += samplesRead;
+ samplesToRead -= samplesRead;
+ totalSamplesRead += samplesRead;
+ }
+
+ return totalSamplesRead;
+}
+
+drwav_uint64 drwav_read_s32__msadpcm(drwav* pWav, drwav_uint64 samplesToRead, drwav_int32* pBufferOut)
+{
+ // We're just going to borrow the implementation from the drwav_read_s16() since ADPCM is a little bit more complicated than other formats and I don't
+ // want to duplicate that code.
+ drwav_uint64 totalSamplesRead = 0;
+ drwav_int16 samples16[2048];
+ while (samplesToRead > 0) {
+ drwav_uint64 samplesRead = drwav_read_s16(pWav, drwav_min(samplesToRead, 2048), samples16);
+ if (samplesRead == 0) {
+ break;
+ }
+
+ drwav_s16_to_s32(pBufferOut, samples16, (size_t)samplesRead); // <-- Safe cast because we're clamping to 2048.
+
+ pBufferOut += samplesRead;
+ samplesToRead -= samplesRead;
+ totalSamplesRead += samplesRead;
+ }
+
+ return totalSamplesRead;
+}
+
+drwav_uint64 drwav_read_s32__ima(drwav* pWav, drwav_uint64 samplesToRead, drwav_int32* pBufferOut)
+{
+ // We're just going to borrow the implementation from the drwav_read_s16() since IMA-ADPCM is a little bit more complicated than other formats and I don't
+ // want to duplicate that code.
+ drwav_uint64 totalSamplesRead = 0;
+ drwav_int16 samples16[2048];
+ while (samplesToRead > 0) {
+ drwav_uint64 samplesRead = drwav_read_s16(pWav, drwav_min(samplesToRead, 2048), samples16);
+ if (samplesRead == 0) {
+ break;
+ }
+
+ drwav_s16_to_s32(pBufferOut, samples16, (size_t)samplesRead); // <-- Safe cast because we're clamping to 2048.
+
+ pBufferOut += samplesRead;
+ samplesToRead -= samplesRead;
+ totalSamplesRead += samplesRead;
+ }
+
+ return totalSamplesRead;
+}
+
+drwav_uint64 drwav_read_s32__ieee(drwav* pWav, drwav_uint64 samplesToRead, drwav_int32* pBufferOut)
+{
+ drwav_uint64 totalSamplesRead = 0;
+ unsigned char sampleData[4096];
+ while (samplesToRead > 0) {
+ drwav_uint64 samplesRead = drwav_read(pWav, drwav_min(samplesToRead, sizeof(sampleData)/pWav->bytesPerSample), sampleData);
+ if (samplesRead == 0) {
+ break;
+ }
+
+ drwav__ieee_to_s32(pBufferOut, sampleData, (size_t)samplesRead, pWav->bytesPerSample);
+
+ pBufferOut += samplesRead;
+ samplesToRead -= samplesRead;
+ totalSamplesRead += samplesRead;
+ }
+
+ return totalSamplesRead;
+}
+
+drwav_uint64 drwav_read_s32__alaw(drwav* pWav, drwav_uint64 samplesToRead, drwav_int32* pBufferOut)
+{
+ drwav_uint64 totalSamplesRead = 0;
+ unsigned char sampleData[4096];
+ while (samplesToRead > 0) {
+ drwav_uint64 samplesRead = drwav_read(pWav, drwav_min(samplesToRead, sizeof(sampleData)/pWav->bytesPerSample), sampleData);
+ if (samplesRead == 0) {
+ break;
+ }
+
+ drwav_alaw_to_s32(pBufferOut, sampleData, (size_t)samplesRead);
+
+ pBufferOut += samplesRead;
+ samplesToRead -= samplesRead;
+ totalSamplesRead += samplesRead;
+ }
+
+ return totalSamplesRead;
+}
+
+drwav_uint64 drwav_read_s32__mulaw(drwav* pWav, drwav_uint64 samplesToRead, drwav_int32* pBufferOut)
+{
+ drwav_uint64 totalSamplesRead = 0;
+ unsigned char sampleData[4096];
+ while (samplesToRead > 0) {
+ drwav_uint64 samplesRead = drwav_read(pWav, drwav_min(samplesToRead, sizeof(sampleData)/pWav->bytesPerSample), sampleData);
+ if (samplesRead == 0) {
+ break;
+ }
+
+ drwav_mulaw_to_s32(pBufferOut, sampleData, (size_t)samplesRead);
+
+ pBufferOut += samplesRead;
+ samplesToRead -= samplesRead;
+ totalSamplesRead += samplesRead;
+ }
+
+ return totalSamplesRead;
+}
+
+drwav_uint64 drwav_read_s32(drwav* pWav, drwav_uint64 samplesToRead, drwav_int32* pBufferOut)
+{
+ if (pWav == NULL || samplesToRead == 0 || pBufferOut == NULL) {
+ return 0;
+ }
+
+ // Don't try to read more samples than can potentially fit in the output buffer.
+ if (samplesToRead * sizeof(drwav_int32) > SIZE_MAX) {
+ samplesToRead = SIZE_MAX / sizeof(drwav_int32);
+ }
+
+
+ if (pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM) {
+ return drwav_read_s32__pcm(pWav, samplesToRead, pBufferOut);
+ }
+
+ if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) {
+ return drwav_read_s32__msadpcm(pWav, samplesToRead, pBufferOut);
+ }
+
+ if (pWav->translatedFormatTag == DR_WAVE_FORMAT_IEEE_FLOAT) {
+ return drwav_read_s32__ieee(pWav, samplesToRead, pBufferOut);
+ }
+
+ if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ALAW) {
+ return drwav_read_s32__alaw(pWav, samplesToRead, pBufferOut);
+ }
+
+ if (pWav->translatedFormatTag == DR_WAVE_FORMAT_MULAW) {
+ return drwav_read_s32__mulaw(pWav, samplesToRead, pBufferOut);
+ }
+
+ if (pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
+ return drwav_read_s32__ima(pWav, samplesToRead, pBufferOut);
+ }
+
+ return 0;
+}
+
+void drwav_u8_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount)
+{
+ if (pOut == NULL || pIn == NULL) {
+ return;
+ }
+
+ for (size_t i = 0; i < sampleCount; ++i) {
+ *pOut++ = ((int)pIn[i] - 128) << 24;
+ }
+}
+
+void drwav_s16_to_s32(drwav_int32* pOut, const drwav_int16* pIn, size_t sampleCount)
+{
+ if (pOut == NULL || pIn == NULL) {
+ return;
+ }
+
+ for (size_t i = 0; i < sampleCount; ++i) {
+ *pOut++ = pIn[i] << 16;
+ }
+}
+
+void drwav_s24_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount)
+{
+ if (pOut == NULL || pIn == NULL) {
+ return;
+ }
+
+ for (size_t i = 0; i < sampleCount; ++i) {
+ unsigned int s0 = pIn[i*3 + 0];
+ unsigned int s1 = pIn[i*3 + 1];
+ unsigned int s2 = pIn[i*3 + 2];
+
+ drwav_int32 sample32 = (drwav_int32)((s0 << 8) | (s1 << 16) | (s2 << 24));
+ *pOut++ = sample32;
+ }
+}
+
+void drwav_f32_to_s32(drwav_int32* pOut, const float* pIn, size_t sampleCount)
+{
+ if (pOut == NULL || pIn == NULL) {
+ return;
+ }
+
+ for (size_t i = 0; i < sampleCount; ++i) {
+ *pOut++ = (drwav_int32)(2147483648.0 * pIn[i]);
+ }
+}
+
+void drwav_f64_to_s32(drwav_int32* pOut, const double* pIn, size_t sampleCount)
+{
+ if (pOut == NULL || pIn == NULL) {
+ return;
+ }
+
+ for (size_t i = 0; i < sampleCount; ++i) {
+ *pOut++ = (drwav_int32)(2147483648.0 * pIn[i]);
+ }
+}
+
+void drwav_alaw_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount)
+{
+ if (pOut == NULL || pIn == NULL) {
+ return;
+ }
+
+ for (size_t i = 0; i < sampleCount; ++i) {
+ *pOut++ = ((drwav_int32)drwav__alaw_to_s16(pIn[i])) << 16;
+ }
+}
+
+void drwav_mulaw_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount)
+{
+ if (pOut == NULL || pIn == NULL) {
+ return;
+ }
+
+ for (size_t i= 0; i < sampleCount; ++i) {
+ *pOut++ = ((drwav_int32)drwav__mulaw_to_s16(pIn[i])) << 16;
+ }
+}
+
+
+
+drwav_int16* drwav__read_and_close_s16(drwav* pWav, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalSampleCount)
+{
+ drwav_assert(pWav != NULL);
+
+ drwav_uint64 sampleDataSize = pWav->totalSampleCount * sizeof(drwav_int16);
+ if (sampleDataSize > SIZE_MAX) {
+ drwav_uninit(pWav);
+ return NULL; // File's too big.
+ }
+
+ drwav_int16* pSampleData = (drwav_int16*)DRWAV_MALLOC((size_t)sampleDataSize); // <-- Safe cast due to the check above.
+ if (pSampleData == NULL) {
+ drwav_uninit(pWav);
+ return NULL; // Failed to allocate memory.
+ }
+
+ drwav_uint64 samplesRead = drwav_read_s16(pWav, (size_t)pWav->totalSampleCount, pSampleData);
+ if (samplesRead != pWav->totalSampleCount) {
+ DRWAV_FREE(pSampleData);
+ drwav_uninit(pWav);
+ return NULL; // There was an error reading the samples.
+ }
+
+ drwav_uninit(pWav);
+
+ if (sampleRate) *sampleRate = pWav->sampleRate;
+ if (channels) *channels = pWav->channels;
+ if (totalSampleCount) *totalSampleCount = pWav->totalSampleCount;
+ return pSampleData;
+}
+
+float* drwav__read_and_close_f32(drwav* pWav, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalSampleCount)
+{
+ drwav_assert(pWav != NULL);
+
+ drwav_uint64 sampleDataSize = pWav->totalSampleCount * sizeof(float);
+ if (sampleDataSize > SIZE_MAX) {
+ drwav_uninit(pWav);
+ return NULL; // File's too big.
+ }
+
+ float* pSampleData = (float*)DRWAV_MALLOC((size_t)sampleDataSize); // <-- Safe cast due to the check above.
+ if (pSampleData == NULL) {
+ drwav_uninit(pWav);
+ return NULL; // Failed to allocate memory.
+ }
+
+ drwav_uint64 samplesRead = drwav_read_f32(pWav, (size_t)pWav->totalSampleCount, pSampleData);
+ if (samplesRead != pWav->totalSampleCount) {
+ DRWAV_FREE(pSampleData);
+ drwav_uninit(pWav);
+ return NULL; // There was an error reading the samples.
+ }
+
+ drwav_uninit(pWav);
+
+ if (sampleRate) *sampleRate = pWav->sampleRate;
+ if (channels) *channels = pWav->channels;
+ if (totalSampleCount) *totalSampleCount = pWav->totalSampleCount;
+ return pSampleData;
+}
+
+drwav_int32* drwav__read_and_close_s32(drwav* pWav, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalSampleCount)
+{
+ drwav_assert(pWav != NULL);
+
+ drwav_uint64 sampleDataSize = pWav->totalSampleCount * sizeof(drwav_int32);
+ if (sampleDataSize > SIZE_MAX) {
+ drwav_uninit(pWav);
+ return NULL; // File's too big.
+ }
+
+ drwav_int32* pSampleData = (drwav_int32*)DRWAV_MALLOC((size_t)sampleDataSize); // <-- Safe cast due to the check above.
+ if (pSampleData == NULL) {
+ drwav_uninit(pWav);
+ return NULL; // Failed to allocate memory.
+ }
+
+ drwav_uint64 samplesRead = drwav_read_s32(pWav, (size_t)pWav->totalSampleCount, pSampleData);
+ if (samplesRead != pWav->totalSampleCount) {
+ DRWAV_FREE(pSampleData);
+ drwav_uninit(pWav);
+ return NULL; // There was an error reading the samples.
+ }
+
+ drwav_uninit(pWav);
+
+ if (sampleRate) *sampleRate = pWav->sampleRate;
+ if (channels) *channels = pWav->channels;
+ if (totalSampleCount) *totalSampleCount = pWav->totalSampleCount;
+ return pSampleData;
+}
+
+
+drwav_int16* drwav_open_and_read_s16(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalSampleCount)
+{
+ if (sampleRate) *sampleRate = 0;
+ if (channels) *channels = 0;
+ if (totalSampleCount) *totalSampleCount = 0;
+
+ drwav wav;
+ if (!drwav_init(&wav, onRead, onSeek, pUserData)) {
+ return NULL;
+ }
+
+ return drwav__read_and_close_s16(&wav, channels, sampleRate, totalSampleCount);
+}
+
+float* drwav_open_and_read_f32(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalSampleCount)
+{
+ if (sampleRate) *sampleRate = 0;
+ if (channels) *channels = 0;
+ if (totalSampleCount) *totalSampleCount = 0;
+
+ drwav wav;
+ if (!drwav_init(&wav, onRead, onSeek, pUserData)) {
+ return NULL;
+ }
+
+ return drwav__read_and_close_f32(&wav, channels, sampleRate, totalSampleCount);
+}
+
+drwav_int32* drwav_open_and_read_s32(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalSampleCount)
+{
+ if (sampleRate) *sampleRate = 0;
+ if (channels) *channels = 0;
+ if (totalSampleCount) *totalSampleCount = 0;
+
+ drwav wav;
+ if (!drwav_init(&wav, onRead, onSeek, pUserData)) {
+ return NULL;
+ }
+
+ return drwav__read_and_close_s32(&wav, channels, sampleRate, totalSampleCount);
+}
+
+#ifndef DR_WAV_NO_STDIO
+drwav_int16* drwav_open_and_read_file_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalSampleCount)
+{
+ if (sampleRate) *sampleRate = 0;
+ if (channels) *channels = 0;
+ if (totalSampleCount) *totalSampleCount = 0;
+
+ drwav wav;
+ if (!drwav_init_file(&wav, filename)) {
+ return NULL;
+ }
+
+ return drwav__read_and_close_s16(&wav, channels, sampleRate, totalSampleCount);
+}
+
+float* drwav_open_and_read_file_f32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalSampleCount)
+{
+ if (sampleRate) *sampleRate = 0;
+ if (channels) *channels = 0;
+ if (totalSampleCount) *totalSampleCount = 0;
+
+ drwav wav;
+ if (!drwav_init_file(&wav, filename)) {
+ return NULL;
+ }
+
+ return drwav__read_and_close_f32(&wav, channels, sampleRate, totalSampleCount);
+}
+
+drwav_int32* drwav_open_and_read_file_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalSampleCount)
+{
+ if (sampleRate) *sampleRate = 0;
+ if (channels) *channels = 0;
+ if (totalSampleCount) *totalSampleCount = 0;
+
+ drwav wav;
+ if (!drwav_init_file(&wav, filename)) {
+ return NULL;
+ }
+
+ return drwav__read_and_close_s32(&wav, channels, sampleRate, totalSampleCount);
+}
+#endif
+
+drwav_int16* drwav_open_and_read_memory_s16(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalSampleCount)
+{
+ if (sampleRate) *sampleRate = 0;
+ if (channels) *channels = 0;
+ if (totalSampleCount) *totalSampleCount = 0;
+
+ drwav wav;
+ if (!drwav_init_memory(&wav, data, dataSize)) {
+ return NULL;
+ }
+
+ return drwav__read_and_close_s16(&wav, channels, sampleRate, totalSampleCount);
+}
+
+float* drwav_open_and_read_memory_f32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalSampleCount)
+{
+ if (sampleRate) *sampleRate = 0;
+ if (channels) *channels = 0;
+ if (totalSampleCount) *totalSampleCount = 0;
+
+ drwav wav;
+ if (!drwav_init_memory(&wav, data, dataSize)) {
+ return NULL;
+ }
+
+ return drwav__read_and_close_f32(&wav, channels, sampleRate, totalSampleCount);
+}
+
+drwav_int32* drwav_open_and_read_memory_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalSampleCount)
+{
+ if (sampleRate) *sampleRate = 0;
+ if (channels) *channels = 0;
+ if (totalSampleCount) *totalSampleCount = 0;
+
+ drwav wav;
+ if (!drwav_init_memory(&wav, data, dataSize)) {
+ return NULL;
+ }
+
+ return drwav__read_and_close_s32(&wav, channels, sampleRate, totalSampleCount);
+}
+#endif //DR_WAV_NO_CONVERSION_API
+
+
+void drwav_free(void* pDataReturnedByOpenAndRead)
+{
+ DRWAV_FREE(pDataReturnedByOpenAndRead);
+}
+
+#endif //DR_WAV_IMPLEMENTATION
+
+
+// REVISION HISTORY
+//
+// v0.7a - 2017-11-17
+// - Fix some GCC warnings.
+//
+// v0.7 - 2017-11-04
+// - Add writing APIs.
+//
+// v0.6 - 2017-08-16
+// - API CHANGE: Rename dr_* types to drwav_*.
+// - Add support for custom implementations of malloc(), realloc(), etc.
+// - Add support for Microsoft ADPCM.
+// - Add support for IMA ADPCM (DVI, format code 0x11).
+// - Optimizations to drwav_read_s16().
+// - Bug fixes.
+//
+// v0.5g - 2017-07-16
+// - Change underlying type for booleans to unsigned.
+//
+// v0.5f - 2017-04-04
+// - Fix a minor bug with drwav_open_and_read_s16() and family.
+//
+// v0.5e - 2016-12-29
+// - Added support for reading samples as signed 16-bit integers. Use the _s16() family of APIs for this.
+// - Minor fixes to documentation.
+//
+// v0.5d - 2016-12-28
+// - Use drwav_int*/drwav_uint* sized types to improve compiler support.
+//
+// v0.5c - 2016-11-11
+// - Properly handle JUNK chunks that come before the FMT chunk.
+//
+// v0.5b - 2016-10-23
+// - A minor change to drwav_bool8 and drwav_bool32 types.
+//
+// v0.5a - 2016-10-11
+// - Fixed a bug with drwav_open_and_read() and family due to incorrect argument ordering.
+// - Improve A-law and mu-law efficiency.
+//
+// v0.5 - 2016-09-29
+// - API CHANGE. Swap the order of "channels" and "sampleRate" parameters in drwav_open_and_read*(). Rationale for this is to
+// keep it consistent with dr_audio and drwav_flac.
+//
+// v0.4b - 2016-09-18
+// - Fixed a typo in documentation.
+//
+// v0.4a - 2016-09-18
+// - Fixed a typo.
+// - Change date format to ISO 8601 (YYYY-MM-DD)
+//
+// v0.4 - 2016-07-13
+// - API CHANGE. Make onSeek consistent with drwav_flac.
+// - API CHANGE. Rename drwav_seek() to drwav_seek_to_sample() for clarity and consistency with drwav_flac.
+// - Added support for Sony Wave64.
+//
+// v0.3a - 2016-05-28
+// - API CHANGE. Return drwav_bool32 instead of int in onSeek callback.
+// - Fixed a memory leak.
+//
+// v0.3 - 2016-05-22
+// - Lots of API changes for consistency.
+//
+// v0.2a - 2016-05-16
+// - Fixed Linux/GCC build.
+//
+// v0.2 - 2016-05-11
+// - Added support for reading data as signed 32-bit PCM for consistency with drwav_flac.
+//
+// v0.1a - 2016-05-07
+// - Fixed a bug in drwav_open_file() where the file handle would not be closed if the loader failed to initialize.
+//
+// v0.1 - 2016-05-04
+// - Initial versioned release.
+
+
+/*
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to
+*/
diff --git a/src/external/glad.h b/src/external/glad.h
index ab5947e68..70dbc7394 100644
--- a/src/external/glad.h
+++ b/src/external/glad.h
@@ -3446,6 +3446,19 @@ typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEEXTPROC)(GLenum sfactorRGB, GLenum
GLAPI PFNGLBLENDFUNCSEPARATEEXTPROC glad_glBlendFuncSeparateEXT;
#define glBlendFuncSeparateEXT glad_glBlendFuncSeparateEXT
#endif
+#ifndef GL_EXT_debug_marker
+#define GL_EXT_debug_marker 1
+GLAPI int GLAD_GL_EXT_debug_marker;
+typedef void (APIENTRYP PFNGLINSERTEVENTMARKEREXTPROC)(GLsizei length, const GLchar *marker);
+GLAPI PFNGLINSERTEVENTMARKEREXTPROC glad_glInsertEventMarkerEXT;
+#define glInsertEventMarkerEXT glad_glInsertEventMarkerEXT
+typedef void (APIENTRYP PFNGLPUSHGROUPMARKEREXTPROC)(GLsizei length, const GLchar *marker);
+GLAPI PFNGLPUSHGROUPMARKEREXTPROC glad_glPushGroupMarkerEXT;
+#define glPushGroupMarkerEXT glad_glPushGroupMarkerEXT
+typedef void (APIENTRYP PFNGLPOPGROUPMARKEREXTPROC)(void);
+GLAPI PFNGLPOPGROUPMARKEREXTPROC glad_glPopGroupMarkerEXT;
+#define glPopGroupMarkerEXT glad_glPopGroupMarkerEXT
+#endif
#ifndef GL_EXT_framebuffer_blit
#define GL_EXT_framebuffer_blit 1
GLAPI int GLAD_GL_EXT_framebuffer_blit;
@@ -4209,6 +4222,7 @@ int GLAD_GL_ARB_vertex_shader;
int GLAD_GL_ARB_vertex_attrib_binding;
int GLAD_GL_ARB_vertex_program;
int GLAD_GL_EXT_texture_compression_s3tc;
+int GLAD_GL_EXT_debug_marker;
int GLAD_GL_EXT_texture_swizzle;
int GLAD_GL_ARB_texture_multisample;
int GLAD_GL_ARB_texture_rg;
@@ -4391,6 +4405,9 @@ PFNGLGETVARIANTARRAYOBJECTIVATIPROC glad_glGetVariantArrayObjectivATI;
PFNGLBLENDCOLOREXTPROC glad_glBlendColorEXT;
PFNGLBLENDEQUATIONSEPARATEEXTPROC glad_glBlendEquationSeparateEXT;
PFNGLBLENDFUNCSEPARATEEXTPROC glad_glBlendFuncSeparateEXT;
+PFNGLINSERTEVENTMARKEREXTPROC glad_glInsertEventMarkerEXT;
+PFNGLPUSHGROUPMARKEREXTPROC glad_glPushGroupMarkerEXT;
+PFNGLPOPGROUPMARKEREXTPROC glad_glPopGroupMarkerEXT;
PFNGLBLITFRAMEBUFFEREXTPROC glad_glBlitFramebufferEXT;
PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glRenderbufferStorageMultisampleEXT;
PFNGLISRENDERBUFFEREXTPROC glad_glIsRenderbufferEXT;
@@ -5190,6 +5207,12 @@ static void load_GL_EXT_blend_func_separate(GLADloadproc load) {
if(!GLAD_GL_EXT_blend_func_separate) return;
glad_glBlendFuncSeparateEXT = (PFNGLBLENDFUNCSEPARATEEXTPROC)load("glBlendFuncSeparateEXT");
}
+static void load_GL_EXT_debug_marker(GLADloadproc load) {
+ if(!GLAD_GL_EXT_debug_marker) return;
+ glad_glInsertEventMarkerEXT = (PFNGLINSERTEVENTMARKEREXTPROC)load("glInsertEventMarkerEXT");
+ glad_glPushGroupMarkerEXT = (PFNGLPUSHGROUPMARKEREXTPROC)load("glPushGroupMarkerEXT");
+ glad_glPopGroupMarkerEXT = (PFNGLPOPGROUPMARKEREXTPROC)load("glPopGroupMarkerEXT");
+}
static void load_GL_EXT_framebuffer_blit(GLADloadproc load) {
if(!GLAD_GL_EXT_framebuffer_blit) return;
glad_glBlitFramebufferEXT = (PFNGLBLITFRAMEBUFFEREXTPROC)load("glBlitFramebufferEXT");
@@ -5316,6 +5339,7 @@ static int find_extensionsGL(void) {
GLAD_GL_EXT_blend_color = has_ext("GL_EXT_blend_color");
GLAD_GL_EXT_blend_equation_separate = has_ext("GL_EXT_blend_equation_separate");
GLAD_GL_EXT_blend_func_separate = has_ext("GL_EXT_blend_func_separate");
+ GLAD_GL_EXT_debug_marker = has_ext("GL_EXT_debug_marker");
GLAD_GL_EXT_framebuffer_blit = has_ext("GL_EXT_framebuffer_blit");
GLAD_GL_EXT_framebuffer_multisample = has_ext("GL_EXT_framebuffer_multisample");
GLAD_GL_EXT_framebuffer_multisample_blit_scaled = has_ext("GL_EXT_framebuffer_multisample_blit_scaled");
@@ -5430,6 +5454,7 @@ int gladLoadGLLoader(GLADloadproc load) {
load_GL_EXT_blend_color(load);
load_GL_EXT_blend_equation_separate(load);
load_GL_EXT_blend_func_separate(load);
+ load_GL_EXT_debug_marker(load);
load_GL_EXT_framebuffer_blit(load);
load_GL_EXT_framebuffer_multisample(load);
load_GL_EXT_framebuffer_object(load);
diff --git a/src/external/include/GLFW_COPYING.txt b/src/external/glfw/LICENSE.md
similarity index 93%
rename from src/external/include/GLFW_COPYING.txt
rename to src/external/glfw/LICENSE.md
index ad16462a9..acdac20b9 100644
--- a/src/external/include/GLFW_COPYING.txt
+++ b/src/external/glfw/LICENSE.md
@@ -1,5 +1,5 @@
Copyright (c) 2002-2006 Marcus Geelnard
-Copyright (c) 2006-2016 Camilla Berglund
+Copyright (c) 2006-2016 Camilla Löwy
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
diff --git a/src/external/glfw/README.md b/src/external/glfw/README.md
new file mode 100644
index 000000000..0573dcd93
--- /dev/null
+++ b/src/external/glfw/README.md
@@ -0,0 +1,463 @@
+# GLFW
+
+[](https://travis-ci.org/glfw/glfw)
+[](https://ci.appveyor.com/project/elmindreda/glfw)
+[](https://scan.coverity.com/projects/glfw-glfw)
+
+## Introduction
+
+GLFW is an Open Source, multi-platform library for OpenGL, OpenGL ES and Vulkan
+application development. It provides a simple, platform-independent API for
+creating windows, contexts and surfaces, reading input, handling events, etc.
+
+GLFW natively supports Windows, macOS and Linux and other Unix-like systems.
+Experimental implementations for the Wayland protocol and the Mir display server
+are available but not yet officially supported.
+
+GLFW is licensed under the [zlib/libpng
+license](http://www.glfw.org/license.html).
+
+The latest stable release is version 3.2.1.
+
+See the [downloads](http://www.glfw.org/download.html) page for details and
+files, or fetch the `latest` branch, which always points to the latest stable
+release. Each release starting with 3.0 also has a corresponding [annotated
+tag](https://github.com/glfw/glfw/releases) with source and binary archives.
+The [version history](http://www.glfw.org/changelog.html) lists all user-visible
+changes for every release.
+
+This is a development branch for version 3.3, which is _not yet described_.
+Pre-release documentation is available [here](http://www.glfw.org/docs/3.3/).
+
+The `master` branch is the stable integration branch and _should_ always compile
+and run on all supported platforms, although details of newly added features may
+change until they have been included in a release. New features and many bug
+fixes live in [other branches](https://github.com/glfw/glfw/branches/all) until
+they are stable enough to merge.
+
+If you are new to GLFW, you may find the
+[tutorial](http://www.glfw.org/docs/latest/quick.html) for GLFW 3 useful. If
+you have used GLFW 2 in the past, there is a [transition
+guide](http://www.glfw.org/docs/latest/moving.html) for moving to the GLFW
+3 API.
+
+
+## Compiling GLFW
+
+GLFW itself requires only the headers and libraries for your window system. It
+does not need the headers for any context creation API (WGL, GLX, EGL, NSGL,
+OSMesa) or rendering API (OpenGL, OpenGL ES, Vulkan) to enable support for them.
+
+GLFW supports compilation on Windows with Visual C++ 2010 and later, MinGW and
+MinGW-w64, on macOS with Clang and on Linux and other Unix-like systems with GCC
+and Clang. It will likely compile in other environments as well, but this is
+not regularly tested.
+
+There are [pre-compiled Windows binaries](http://www.glfw.org/download.html)
+available for all supported compilers.
+
+See the [compilation guide](http://www.glfw.org/docs/latest/compile.html) for
+more information about how to compile GLFW yourself.
+
+
+## Using GLFW
+
+See the [documentation](http://www.glfw.org/docs/latest/) for tutorials, guides
+and the API reference.
+
+
+## Contributing to GLFW
+
+See the [contribution
+guide](https://github.com/glfw/glfw/blob/master/docs/CONTRIBUTING.md) for
+more information.
+
+
+## System requirements
+
+GLFW supports Windows XP and later and macOS 10.7 and later. Linux and other
+Unix-like systems running the X Window System are supported even without
+a desktop environment or modern extensions, although some features require
+a running window or clipboard manager. The OSMesa backend requires Mesa 6.3.
+
+See the [compatibility guide](http://www.glfw.org/docs/latest/compat.html)
+in the documentation for more information.
+
+
+## Dependencies
+
+GLFW itself depends only on the headers and libraries for your window system.
+
+The (experimental) Wayland backend also depends on the `extra-cmake-modules`
+package, which is used to generated Wayland protocol headers.
+
+The examples and test programs depend on a number of tiny libraries. These are
+located in the `deps/` directory.
+
+ - [getopt\_port](https://github.com/kimgr/getopt_port/) for examples
+ with command-line options
+ - [TinyCThread](https://github.com/tinycthread/tinycthread) for threaded
+ examples
+ - An OpenGL 3.2 core loader generated by
+ [glad](https://github.com/Dav1dde/glad) for examples using modern OpenGL
+ - [linmath.h](https://github.com/datenwolf/linmath.h) for linear algebra in
+ examples
+ - [Nuklear](https://github.com/vurtun/nuklear) for test and example UI
+ - [stb\_image\_write](https://github.com/nothings/stb) for writing images to disk
+ - [Vulkan headers](https://www.khronos.org/registry/vulkan/) for Vulkan tests
+
+The Vulkan example additionally requires the LunarG Vulkan SDK to be installed,
+or it will not be included in the build. On macOS you need to provide the path
+to the SDK manually as it has no standard installation location.
+
+The documentation is generated with [Doxygen](http://doxygen.org/) if CMake can
+find that tool.
+
+
+## Reporting bugs
+
+Bugs are reported to our [issue tracker](https://github.com/glfw/glfw/issues).
+Please check the [contribution
+guide](https://github.com/glfw/glfw/blob/master/docs/CONTRIBUTING.md) for
+information on what to include when reporting a bug.
+
+
+## Changelog
+
+- Added `glfwGetError` function for querying the last error code and its
+ description (#970)
+- Added `glfwUpdateGamepadMappings` function for importing gamepad mappings in
+ SDL\_GameControllerDB format (#900)
+- Added `glfwJoystickIsGamepad` function for querying whether a joystick has
+ a gamepad mapping (#900)
+- Added `glfwGetJoystickGUID` function for querying the SDL compatible GUID of
+ a joystick (#900)
+- Added `glfwGetGamepadName` function for querying the name provided by the
+ gamepad mapping (#900)
+- Added `glfwGetGamepadState` function, `GLFW_GAMEPAD_*` and `GLFWgamepadstate`
+ for retrieving gamepad input state (#900)
+- Added `glfwGetWindowContentScale`, `glfwGetMonitorContentScale` and
+ `glfwSetWindowContentScaleCallback` for DPI-aware rendering
+ (#235,#439,#677,#845,#898)
+- Added `glfwRequestWindowAttention` function for requesting attention from the
+ user (#732,#988)
+- Added `glfwGetKeyScancode` function that allows retrieving platform dependent
+ scancodes for keys (#830)
+- Added `glfwSetWindowMaximizeCallback` and `GLFWwindowmaximizefun` for
+ receiving window maximization events (#778)
+- Added `glfwSetWindowAttrib` function for changing window attributes (#537)
+- Added `glfwGetJoystickHats` function for querying joystick hats
+ (#889,#906,#934)
+- Added `glfwInitHint` for setting initialization hints
+- Added `glfwWindowHintString` for setting string type window hints (#893,#1139)
+- Added `glfwGetWindowOpacity` and `glfwSetWindowOpacity` for controlling whole
+ window transparency (#1089)
+- Added `glfwSetMonitorUserPointer` and `glfwGetMonitorUserPointer` for
+ per-monitor user pointers
+- Added `glfwSetJoystickUserPointer` and `glfwGetJoystickUserPointer` for
+ per-joystick user pointers
+- Added `glfwGetX11SelectionString` and `glfwSetX11SelectionString`
+ functions for accessing X11 primary selection (#894,#1056)
+- Added headless [OSMesa](http://mesa3d.org/osmesa.html) backend (#850)
+- Added definition of `GLAPIENTRY` to public header
+- Added `GLFW_TRANSPARENT_FRAMEBUFFER` window hint and attribute for controlling
+ per-pixel framebuffer transparency (#197,#663,#715,#723,#1078)
+- Added `GLFW_HOVERED` window attribute for polling cursor hover state (#1166)
+- Added `GLFW_CENTER_CURSOR` window hint for controlling cursor centering
+ (#749,#842)
+- Added `GLFW_JOYSTICK_HAT_BUTTONS` init hint (#889)
+- Added `GLFW_LOCK_KEY_MODS` input mode and `GLFW_MOD_*_LOCK` mod bits (#946)
+- Added macOS specific `GLFW_COCOA_RETINA_FRAMEBUFFER` window hint
+- Added macOS specific `GLFW_COCOA_FRAME_NAME` window hint (#195)
+- Added macOS specific `GLFW_COCOA_GRAPHICS_SWITCHING` window hint (#377,#935)
+- Added macOS specific `GLFW_COCOA_CHDIR_RESOURCES` init hint
+- Added macOS specific `GLFW_COCOA_MENUBAR` init hint
+- Added X11 specific `GLFW_X11_CLASS_NAME` and `GLFW_X11_INSTANCE_NAME` window
+ hints (#893,#1139)
+- Added `GLFW_INCLUDE_ES32` for including the OpenGL ES 3.2 header
+- Added `GLFW_OSMESA_CONTEXT_API` for creating OpenGL contexts with
+ [OSMesa](https://www.mesa3d.org/osmesa.html) (#281)
+- Added `GenerateMappings.cmake` script for updating gamepad mappings
+- Made `glfwCreateWindowSurface` emit an error when the window has a context
+ (#1194,#1205)
+- Deprecated window parameter of clipboard string functions
+- Deprecated charmods callback
+- Removed `GLFW_USE_RETINA` compile-time option
+- Removed `GLFW_USE_CHDIR` compile-time option
+- Removed `GLFW_USE_MENUBAR` compile-time option
+- Bugfix: Calling `glfwMaximizeWindow` on a full screen window was not ignored
+- Bugfix: `GLFW_INCLUDE_VULKAN` could not be combined with the corresponding
+ OpenGL and OpenGL ES header macros
+- Bugfix: `glfwGetInstanceProcAddress` returned `NULL` for
+ `vkGetInstanceProcAddr` when `_GLFW_VULKAN_STATIC` was enabled
+- Bugfix: Invalid library paths were used in test and example CMake files (#930)
+- Bugfix: The scancode for synthetic key release events was always zero
+- Bugfix: The generated Doxyfile did not handle paths with spaces (#1081)
+- [Win32] Added system error strings to relevant GLFW error descriptions (#733)
+- [Win32] Moved to `WM_INPUT` for disabled cursor mode motion input (#125)
+- [Win32] Removed XInput circular deadzone from joystick axis data (#1045)
+- [Win32] Bugfix: Undecorated windows could not be iconified by the user (#861)
+- [Win32] Bugfix: Deadzone logic could underflow with some controllers (#910)
+- [Win32] Bugfix: Bitness test in `FindVulkan.cmake` was VS specific (#928)
+- [Win32] Bugfix: `glfwVulkanSupported` emitted an error on systems with
+ a loader but no ICD (#916)
+- [Win32] Bugfix: Non-iconified full sreeen windows did not prevent screen
+ blanking or password enabled screensavers (#851)
+- [Win32] Bugfix: Mouse capture logic lost secondary release messages (#954)
+- [Win32] Bugfix: The 32-bit Vulkan loader library static was not searched for
+- [Win32] Bugfix: Vulkan libraries have a new path as of SDK 1.0.42.0 (#956)
+- [Win32] Bugfix: Monitors with no display devices were not enumerated (#960)
+- [Win32] Bugfix: Monitor events were not emitted (#784)
+- [Win32] Bugfix: The Cygwin DLL was installed to the wrong directory (#1035)
+- [Win32] Bugfix: Normalization of axis data via XInput was incorrect (#1045)
+- [Win32] Bugfix: `glfw3native.h` would undefine a foreign `APIENTRY` (#1062)
+- [Win32] Bugfix: Disabled cursor mode prevented use of caption buttons
+ (#650,#1071)
+- [Win32] Bugfix: Returned key names did not match other platforms (#943)
+- [Win32] Bugfix: Undecorated windows did not maximize to workarea (#899)
+- [Win32] Bugfix: Window was resized twice when entering full screen (#1085)
+- [Win32] Bugfix: The HID device notification was not unregistered (#1170)
+- [Win32] Bugfix: `glfwCreateWindow` activated window even with `GLFW_FOCUSED`
+ hint set to false (#1179,#1180)
+- [X11] Moved to XI2 `XI_RawMotion` for disable cursor mode motion input (#125)
+- [X11] Replaced `_GLFW_HAS_XF86VM` compile-time option with dynamic loading
+- [X11] Bugfix: `glfwGetVideoMode` would segfault on Cygwin/X
+- [X11] Bugfix: Dynamic X11 library loading did not use full sonames (#941)
+- [X11] Bugfix: Window creation on 64-bit would read past top of stack (#951)
+- [X11] Bugfix: XDND support had multiple non-conformance issues (#968)
+- [X11] Bugfix: The RandR monitor path was disabled despite working RandR (#972)
+- [X11] Bugfix: IM-duplicated key events would leak at low polling rates (#747)
+- [X11] Bugfix: Gamma ramp setting via RandR did not validate ramp size
+- [X11] Bugfix: Key name string encoding depended on current locale (#981,#983)
+- [X11] Bugfix: Incremental reading of selections was not supported (#275)
+- [X11] Bugfix: Selection I/O reported but did not support `COMPOUND_TEXT`
+- [X11] Bugfix: Latin-1 text read from selections was not converted to UTF-8
+- [X11] Bugfix: NVidia EGL would segfault if unloaded before closing the display
+- [Linux] Added workaround for missing `SYN_DROPPED` in pre-2.6.39 kernel
+ headers (#1196)
+- [Linux] Moved to evdev for joystick input (#906,#1005)
+- [Linux] Bugfix: Event processing did not detect joystick disconnection (#932)
+- [Linux] Bugfix: The joystick device path could be truncated (#1025)
+- [Linux] Bugfix: `glfwInit` would fail if inotify creation failed (#833)
+- [Linux] Bugfix: `strdup` was used without any required feature macro (#1055)
+- [Cocoa] Added support for Vulkan window surface creation via
+ [MoltenVK](https://moltengl.com/moltenvk/) (#870)
+- [Cocoa] Added support for loading a `MainMenu.nib` when available
+- [Cocoa] Bugfix: Disabling window aspect ratio would assert (#852)
+- [Cocoa] Bugfix: Window creation failed to set first responder (#876,#883)
+- [Cocoa] Bugfix: Removed use of deprecated `CGDisplayIOServicePort` function
+ (#165,#192,#508,#511)
+- [Cocoa] Bugfix: Disabled use of deprecated `CGDisplayModeCopyPixelEncoding`
+ function on macOS 10.12+
+- [Cocoa] Bugfix: Running in AppSandbox would emit warnings (#816,#882)
+- [Cocoa] Bugfix: Windows created after the first were not cascaded (#195)
+- [Cocoa] Bugfix: Leaving video mode with `glfwSetWindowMonitor` would set
+ incorrect position and size (#748)
+- [Cocoa] Bugfix: Iconified full screen windows could not be restored (#848)
+- [Cocoa] Bugfix: Value range was ignored for joystick hats and buttons (#888)
+- [Cocoa] Bugfix: Full screen framebuffer was incorrectly sized for some video
+ modes (#682)
+- [Cocoa] Bugfix: A string object for IME was updated non-idiomatically (#1050)
+- [Cocoa] Bugfix: A hidden or disabled cursor would become visible when a user
+ notification was shown (#971,#1028)
+- [Cocoa] Bugfix: Some characters did not repeat due to Press and Hold (#1010)
+- [Cocoa] Bugfix: Window title was lost when full screen or undecorated (#1082)
+- [Cocoa] Bugfix: Window was resized twice when entering full screen (#1085)
+- [Cocoa] Bugfix: Duplicate size events were not filtered (#1085)
+- [Cocoa] Bugfix: Event polling did not initialize AppKit if necessary (#1218)
+- [WGL] Added support for `WGL_EXT_colorspace` for OpenGL ES contexts
+- [WGL] Added support for `WGL_ARB_create_context_no_error`
+- [GLX] Added support for `GLX_ARB_create_context_no_error`
+- [GLX] Bugfix: Context creation could segfault if no GLXFBConfigs were
+ available (#1040)
+- [EGL] Added support for `EGL_KHR_get_all_proc_addresses` (#871)
+- [EGL] Added support for `EGL_KHR_context_flush_control`
+- [EGL] Bugfix: The test for `EGL_RGB_BUFFER` was invalid
+
+
+## Contact
+
+On [glfw.org](http://www.glfw.org/) you can find the latest version of GLFW, as
+well as news, documentation and other information about the project.
+
+If you have questions related to the use of GLFW, we have a
+[forum](http://discourse.glfw.org/), and the `#glfw` IRC channel on
+[Freenode](http://freenode.net/).
+
+If you have a bug to report, a patch to submit or a feature you'd like to
+request, please file it in the
+[issue tracker](https://github.com/glfw/glfw/issues) on GitHub.
+
+Finally, if you're interested in helping out with the development of GLFW or
+porting it to your favorite platform, join us on the forum, GitHub or IRC.
+
+
+## Acknowledgements
+
+GLFW exists because people around the world donated their time and lent their
+skills.
+
+ - Bobyshev Alexander
+ - Matt Arsenault
+ - David Avedissian
+ - Keith Bauer
+ - John Bartholomew
+ - Niklas Behrens
+ - Niklas Bergström
+ - Denis Bernard
+ - Doug Binks
+ - blanco
+ - Kyle Brenneman
+ - Rok Breulj
+ - Martin Capitanio
+ - David Carlier
+ - Arturo Castro
+ - Chi-kwan Chan
+ - Ian Clarkson
+ - Michał Cichoń
+ - Lambert Clara
+ - Yaron Cohen-Tal
+ - Omar Cornut
+ - Andrew Corrigan
+ - Bailey Cosier
+ - Noel Cower
+ - Jason Daly
+ - Jarrod Davis
+ - Olivier Delannoy
+ - Paul R. Deppe
+ - Michael Dickens
+ - Роман Донченко
+ - Mario Dorn
+ - Wolfgang Draxinger
+ - Jonathan Dummer
+ - Ralph Eastwood
+ - Fredrik Ehnbom
+ - Robin Eklind
+ - Siavash Eliasi
+ - Felipe Ferreira
+ - Michael Fogleman
+ - Gerald Franz
+ - Mário Freitas
+ - GeO4d
+ - Marcus Geelnard
+ - Stephen Gowen
+ - Kovid Goyal
+ - Eloi MarÃn Gratacós
+ - Stefan Gustavson
+ - Jonathan Hale
+ - Sylvain Hellegouarch
+ - Matthew Henry
+ - heromyth
+ - Lucas Hinderberger
+ - Paul Holden
+ - Warren Hu
+ - IntellectualKitty
+ - Aaron Jacobs
+ - Erik S. V. Jansson
+ - Toni Jovanoski
+ - Arseny Kapoulkine
+ - Cem Karan
+ - Osman Keskin
+ - Josh Kilmer
+ - Cameron King
+ - Peter Knut
+ - Christoph Kubisch
+ - Yuri Kunde Schlesner
+ - Konstantin Käfer
+ - Eric Larson
+ - Robin Leffmann
+ - Glenn Lewis
+ - Shane Liesegang
+ - Eyal Lotem
+ - Tristam MacDonald
+ - Hans Mackowiak
+ - Дмитри Малышев
+ - Zbigniew Mandziejewicz
+ - Célestin Marot
+ - Kyle McDonald
+ - David Medlock
+ - Bryce Mehring
+ - Jonathan Mercier
+ - Marcel Metz
+ - Liam Middlebrook
+ - Jonathan Miller
+ - Kenneth Miller
+ - Bruce Mitchener
+ - Jack Moffitt
+ - Jeff Molofee
+ - Pierre Morel
+ - Jon Morton
+ - Pierre Moulon
+ - Martins Mozeiko
+ - Julian Møller
+ - ndogxj
+ - Kristian Nielsen
+ - Kamil Nowakowski
+ - Denis Ovod
+ - Ozzy
+ - Andri Pálsson
+ - Peoro
+ - Braden Pellett
+ - Christopher Pelloux
+ - Arturo J. Pérez
+ - Anthony Pesch
+ - Orson Peters
+ - Emmanuel Gil Peyrot
+ - Cyril Pichard
+ - Keith Pitt
+ - Stanislav Podgorskiy
+ - Alexandre Pretyman
+ - przemekmirek
+ - Philip Rideout
+ - Eddie Ringle
+ - Jorge Rodriguez
+ - Ed Ropple
+ - Aleksey Rybalkin
+ - Riku Salminen
+ - Brandon Schaefer
+ - Sebastian Schuberth
+ - Christian Sdunek
+ - Matt Sealey
+ - Steve Sexton
+ - Arkady Shapkin
+ - Yoshiki Shibukawa
+ - Dmitri Shuralyov
+ - Daniel Skorupski
+ - Bradley Smith
+ - Patrick Snape
+ - Erlend Sogge Heggen
+ - Julian Squires
+ - Johannes Stein
+ - Pontus Stenetorp
+ - Michael Stocker
+ - Justin Stoecker
+ - Elviss Strazdins
+ - Paul Sultana
+ - Nathan Sweet
+ - TTK-Bandit
+ - Sergey Tikhomirov
+ - Arthur Tombs
+ - Ioannis Tsakpinis
+ - Samuli Tuomola
+ - Matthew Turner
+ - urraka
+ - Elias Vanderstuyft
+ - Stef Velzel
+ - Jari Vetoniemi
+ - Ricardo Vieira
+ - Nicholas Vitovitch
+ - Simon Voordouw
+ - Corentin Wallez
+ - Torsten Walluhn
+ - Patrick Walton
+ - Xo Wang
+ - Jay Weisskopf
+ - Frank Wille
+ - Ryogo Yoshimura
+ - Andrey Zholos
+ - Santi Zupancic
+ - Jonas Ã…dahl
+ - Lasse Öörni
+ - All the unmentioned and anonymous contributors in the GLFW community, for bug
+ reports, patches, feedback, testing and encouragement
+
diff --git a/src/external/glfw/deps/KHR/khrplatform.h b/src/external/glfw/deps/KHR/khrplatform.h
new file mode 100644
index 000000000..c9e6f17d3
--- /dev/null
+++ b/src/external/glfw/deps/KHR/khrplatform.h
@@ -0,0 +1,282 @@
+#ifndef __khrplatform_h_
+#define __khrplatform_h_
+
+/*
+** Copyright (c) 2008-2009 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+/* Khronos platform-specific types and definitions.
+ *
+ * $Revision: 23298 $ on $Date: 2013-09-30 17:07:13 -0700 (Mon, 30 Sep 2013) $
+ *
+ * Adopters may modify this file to suit their platform. Adopters are
+ * encouraged to submit platform specific modifications to the Khronos
+ * group so that they can be included in future versions of this file.
+ * Please submit changes by sending them to the public Khronos Bugzilla
+ * (http://khronos.org/bugzilla) by filing a bug against product
+ * "Khronos (general)" component "Registry".
+ *
+ * A predefined template which fills in some of the bug fields can be
+ * reached using http://tinyurl.com/khrplatform-h-bugreport, but you
+ * must create a Bugzilla login first.
+ *
+ *
+ * See the Implementer's Guidelines for information about where this file
+ * should be located on your system and for more details of its use:
+ * http://www.khronos.org/registry/implementers_guide.pdf
+ *
+ * This file should be included as
+ * #include
+ * by Khronos client API header files that use its types and defines.
+ *
+ * The types in khrplatform.h should only be used to define API-specific types.
+ *
+ * Types defined in khrplatform.h:
+ * khronos_int8_t signed 8 bit
+ * khronos_uint8_t unsigned 8 bit
+ * khronos_int16_t signed 16 bit
+ * khronos_uint16_t unsigned 16 bit
+ * khronos_int32_t signed 32 bit
+ * khronos_uint32_t unsigned 32 bit
+ * khronos_int64_t signed 64 bit
+ * khronos_uint64_t unsigned 64 bit
+ * khronos_intptr_t signed same number of bits as a pointer
+ * khronos_uintptr_t unsigned same number of bits as a pointer
+ * khronos_ssize_t signed size
+ * khronos_usize_t unsigned size
+ * khronos_float_t signed 32 bit floating point
+ * khronos_time_ns_t unsigned 64 bit time in nanoseconds
+ * khronos_utime_nanoseconds_t unsigned time interval or absolute time in
+ * nanoseconds
+ * khronos_stime_nanoseconds_t signed time interval in nanoseconds
+ * khronos_boolean_enum_t enumerated boolean type. This should
+ * only be used as a base type when a client API's boolean type is
+ * an enum. Client APIs which use an integer or other type for
+ * booleans cannot use this as the base type for their boolean.
+ *
+ * Tokens defined in khrplatform.h:
+ *
+ * KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
+ *
+ * KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
+ * KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
+ *
+ * Calling convention macros defined in this file:
+ * KHRONOS_APICALL
+ * KHRONOS_APIENTRY
+ * KHRONOS_APIATTRIBUTES
+ *
+ * These may be used in function prototypes as:
+ *
+ * KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
+ * int arg1,
+ * int arg2) KHRONOS_APIATTRIBUTES;
+ */
+
+/*-------------------------------------------------------------------------
+ * Definition of KHRONOS_APICALL
+ *-------------------------------------------------------------------------
+ * This precedes the return type of the function in the function prototype.
+ */
+#if defined(_WIN32) && !defined(__SCITECH_SNAP__)
+# define KHRONOS_APICALL __declspec(dllimport)
+#elif defined (__SYMBIAN32__)
+# define KHRONOS_APICALL IMPORT_C
+#else
+# define KHRONOS_APICALL
+#endif
+
+/*-------------------------------------------------------------------------
+ * Definition of KHRONOS_APIENTRY
+ *-------------------------------------------------------------------------
+ * This follows the return type of the function and precedes the function
+ * name in the function prototype.
+ */
+#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
+ /* Win32 but not WinCE */
+# define KHRONOS_APIENTRY __stdcall
+#else
+# define KHRONOS_APIENTRY
+#endif
+
+/*-------------------------------------------------------------------------
+ * Definition of KHRONOS_APIATTRIBUTES
+ *-------------------------------------------------------------------------
+ * This follows the closing parenthesis of the function prototype arguments.
+ */
+#if defined (__ARMCC_2__)
+#define KHRONOS_APIATTRIBUTES __softfp
+#else
+#define KHRONOS_APIATTRIBUTES
+#endif
+
+/*-------------------------------------------------------------------------
+ * basic type definitions
+ *-----------------------------------------------------------------------*/
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
+
+
+/*
+ * Using
+ */
+#include
+typedef int32_t khronos_int32_t;
+typedef uint32_t khronos_uint32_t;
+typedef int64_t khronos_int64_t;
+typedef uint64_t khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#elif defined(__VMS ) || defined(__sgi)
+
+/*
+ * Using
+ */
+#include
+typedef int32_t khronos_int32_t;
+typedef uint32_t khronos_uint32_t;
+typedef int64_t khronos_int64_t;
+typedef uint64_t khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
+
+/*
+ * Win32
+ */
+typedef __int32 khronos_int32_t;
+typedef unsigned __int32 khronos_uint32_t;
+typedef __int64 khronos_int64_t;
+typedef unsigned __int64 khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#elif defined(__sun__) || defined(__digital__)
+
+/*
+ * Sun or Digital
+ */
+typedef int khronos_int32_t;
+typedef unsigned int khronos_uint32_t;
+#if defined(__arch64__) || defined(_LP64)
+typedef long int khronos_int64_t;
+typedef unsigned long int khronos_uint64_t;
+#else
+typedef long long int khronos_int64_t;
+typedef unsigned long long int khronos_uint64_t;
+#endif /* __arch64__ */
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#elif 0
+
+/*
+ * Hypothetical platform with no float or int64 support
+ */
+typedef int khronos_int32_t;
+typedef unsigned int khronos_uint32_t;
+#define KHRONOS_SUPPORT_INT64 0
+#define KHRONOS_SUPPORT_FLOAT 0
+
+#else
+
+/*
+ * Generic fallback
+ */
+#include
+typedef int32_t khronos_int32_t;
+typedef uint32_t khronos_uint32_t;
+typedef int64_t khronos_int64_t;
+typedef uint64_t khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#endif
+
+
+/*
+ * Types that are (so far) the same on all platforms
+ */
+typedef signed char khronos_int8_t;
+typedef unsigned char khronos_uint8_t;
+typedef signed short int khronos_int16_t;
+typedef unsigned short int khronos_uint16_t;
+
+/*
+ * Types that differ between LLP64 and LP64 architectures - in LLP64,
+ * pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
+ * to be the only LLP64 architecture in current use.
+ */
+#ifdef _WIN64
+typedef signed long long int khronos_intptr_t;
+typedef unsigned long long int khronos_uintptr_t;
+typedef signed long long int khronos_ssize_t;
+typedef unsigned long long int khronos_usize_t;
+#else
+typedef signed long int khronos_intptr_t;
+typedef unsigned long int khronos_uintptr_t;
+typedef signed long int khronos_ssize_t;
+typedef unsigned long int khronos_usize_t;
+#endif
+
+#if KHRONOS_SUPPORT_FLOAT
+/*
+ * Float type
+ */
+typedef float khronos_float_t;
+#endif
+
+#if KHRONOS_SUPPORT_INT64
+/* Time types
+ *
+ * These types can be used to represent a time interval in nanoseconds or
+ * an absolute Unadjusted System Time. Unadjusted System Time is the number
+ * of nanoseconds since some arbitrary system event (e.g. since the last
+ * time the system booted). The Unadjusted System Time is an unsigned
+ * 64 bit value that wraps back to 0 every 584 years. Time intervals
+ * may be either signed or unsigned.
+ */
+typedef khronos_uint64_t khronos_utime_nanoseconds_t;
+typedef khronos_int64_t khronos_stime_nanoseconds_t;
+#endif
+
+/*
+ * Dummy value used to pad enum types to 32 bits.
+ */
+#ifndef KHRONOS_MAX_ENUM
+#define KHRONOS_MAX_ENUM 0x7FFFFFFF
+#endif
+
+/*
+ * Enumerated boolean type
+ *
+ * Values other than zero should be considered to be true. Therefore
+ * comparisons should not be made against KHRONOS_TRUE.
+ */
+typedef enum {
+ KHRONOS_FALSE = 0,
+ KHRONOS_TRUE = 1,
+ KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
+} khronos_boolean_enum_t;
+
+#endif /* __khrplatform_h_ */
diff --git a/src/external/glfw/deps/mingw/_mingw_dxhelper.h b/src/external/glfw/deps/mingw/_mingw_dxhelper.h
new file mode 100644
index 000000000..849e29146
--- /dev/null
+++ b/src/external/glfw/deps/mingw/_mingw_dxhelper.h
@@ -0,0 +1,117 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+
+#if defined(_MSC_VER) && !defined(_MSC_EXTENSIONS)
+#define NONAMELESSUNION 1
+#endif
+#if defined(NONAMELESSSTRUCT) && \
+ !defined(NONAMELESSUNION)
+#define NONAMELESSUNION 1
+#endif
+#if defined(NONAMELESSUNION) && \
+ !defined(NONAMELESSSTRUCT)
+#define NONAMELESSSTRUCT 1
+#endif
+#if !defined(__GNU_EXTENSION)
+#if defined(__GNUC__) || defined(__GNUG__)
+#define __GNU_EXTENSION __extension__
+#else
+#define __GNU_EXTENSION
+#endif
+#endif /* __extension__ */
+
+#ifndef __ANONYMOUS_DEFINED
+#define __ANONYMOUS_DEFINED
+#if defined(__GNUC__) || defined(__GNUG__)
+#define _ANONYMOUS_UNION __extension__
+#define _ANONYMOUS_STRUCT __extension__
+#else
+#define _ANONYMOUS_UNION
+#define _ANONYMOUS_STRUCT
+#endif
+#ifndef NONAMELESSUNION
+#define _UNION_NAME(x)
+#define _STRUCT_NAME(x)
+#else /* NONAMELESSUNION */
+#define _UNION_NAME(x) x
+#define _STRUCT_NAME(x) x
+#endif
+#endif /* __ANONYMOUS_DEFINED */
+
+#ifndef DUMMYUNIONNAME
+# ifdef NONAMELESSUNION
+# define DUMMYUNIONNAME u
+# define DUMMYUNIONNAME1 u1 /* Wine uses this variant */
+# define DUMMYUNIONNAME2 u2
+# define DUMMYUNIONNAME3 u3
+# define DUMMYUNIONNAME4 u4
+# define DUMMYUNIONNAME5 u5
+# define DUMMYUNIONNAME6 u6
+# define DUMMYUNIONNAME7 u7
+# define DUMMYUNIONNAME8 u8
+# define DUMMYUNIONNAME9 u9
+# else /* NONAMELESSUNION */
+# define DUMMYUNIONNAME
+# define DUMMYUNIONNAME1 /* Wine uses this variant */
+# define DUMMYUNIONNAME2
+# define DUMMYUNIONNAME3
+# define DUMMYUNIONNAME4
+# define DUMMYUNIONNAME5
+# define DUMMYUNIONNAME6
+# define DUMMYUNIONNAME7
+# define DUMMYUNIONNAME8
+# define DUMMYUNIONNAME9
+# endif
+#endif /* DUMMYUNIONNAME */
+
+#if !defined(DUMMYUNIONNAME1) /* MinGW does not define this one */
+# ifdef NONAMELESSUNION
+# define DUMMYUNIONNAME1 u1 /* Wine uses this variant */
+# else
+# define DUMMYUNIONNAME1 /* Wine uses this variant */
+# endif
+#endif /* DUMMYUNIONNAME1 */
+
+#ifndef DUMMYSTRUCTNAME
+# ifdef NONAMELESSUNION
+# define DUMMYSTRUCTNAME s
+# define DUMMYSTRUCTNAME1 s1 /* Wine uses this variant */
+# define DUMMYSTRUCTNAME2 s2
+# define DUMMYSTRUCTNAME3 s3
+# define DUMMYSTRUCTNAME4 s4
+# define DUMMYSTRUCTNAME5 s5
+# else
+# define DUMMYSTRUCTNAME
+# define DUMMYSTRUCTNAME1 /* Wine uses this variant */
+# define DUMMYSTRUCTNAME2
+# define DUMMYSTRUCTNAME3
+# define DUMMYSTRUCTNAME4
+# define DUMMYSTRUCTNAME5
+# endif
+#endif /* DUMMYSTRUCTNAME */
+
+/* These are for compatibility with the Wine source tree */
+
+#ifndef WINELIB_NAME_AW
+# ifdef __MINGW_NAME_AW
+# define WINELIB_NAME_AW __MINGW_NAME_AW
+# else
+# ifdef UNICODE
+# define WINELIB_NAME_AW(func) func##W
+# else
+# define WINELIB_NAME_AW(func) func##A
+# endif
+# endif
+#endif /* WINELIB_NAME_AW */
+
+#ifndef DECL_WINELIB_TYPE_AW
+# ifdef __MINGW_TYPEDEF_AW
+# define DECL_WINELIB_TYPE_AW __MINGW_TYPEDEF_AW
+# else
+# define DECL_WINELIB_TYPE_AW(type) typedef WINELIB_NAME_AW(type) type;
+# endif
+#endif /* DECL_WINELIB_TYPE_AW */
+
diff --git a/src/external/glfw/deps/mingw/dinput.h b/src/external/glfw/deps/mingw/dinput.h
new file mode 100644
index 000000000..b5754802b
--- /dev/null
+++ b/src/external/glfw/deps/mingw/dinput.h
@@ -0,0 +1,2467 @@
+/*
+ * Copyright (C) the Wine project
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __DINPUT_INCLUDED__
+#define __DINPUT_INCLUDED__
+
+#define COM_NO_WINDOWS_H
+#include
+#include <_mingw_dxhelper.h>
+
+#ifndef DIRECTINPUT_VERSION
+#define DIRECTINPUT_VERSION 0x0800
+#endif
+
+/* Classes */
+DEFINE_GUID(CLSID_DirectInput, 0x25E609E0,0xB259,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(CLSID_DirectInputDevice, 0x25E609E1,0xB259,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+
+DEFINE_GUID(CLSID_DirectInput8, 0x25E609E4,0xB259,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(CLSID_DirectInputDevice8, 0x25E609E5,0xB259,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+
+/* Interfaces */
+DEFINE_GUID(IID_IDirectInputA, 0x89521360,0xAA8A,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(IID_IDirectInputW, 0x89521361,0xAA8A,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(IID_IDirectInput2A, 0x5944E662,0xAA8A,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(IID_IDirectInput2W, 0x5944E663,0xAA8A,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(IID_IDirectInput7A, 0x9A4CB684,0x236D,0x11D3,0x8E,0x9D,0x00,0xC0,0x4F,0x68,0x44,0xAE);
+DEFINE_GUID(IID_IDirectInput7W, 0x9A4CB685,0x236D,0x11D3,0x8E,0x9D,0x00,0xC0,0x4F,0x68,0x44,0xAE);
+DEFINE_GUID(IID_IDirectInput8A, 0xBF798030,0x483A,0x4DA2,0xAA,0x99,0x5D,0x64,0xED,0x36,0x97,0x00);
+DEFINE_GUID(IID_IDirectInput8W, 0xBF798031,0x483A,0x4DA2,0xAA,0x99,0x5D,0x64,0xED,0x36,0x97,0x00);
+DEFINE_GUID(IID_IDirectInputDeviceA, 0x5944E680,0xC92E,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(IID_IDirectInputDeviceW, 0x5944E681,0xC92E,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(IID_IDirectInputDevice2A, 0x5944E682,0xC92E,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(IID_IDirectInputDevice2W, 0x5944E683,0xC92E,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(IID_IDirectInputDevice7A, 0x57D7C6BC,0x2356,0x11D3,0x8E,0x9D,0x00,0xC0,0x4F,0x68,0x44,0xAE);
+DEFINE_GUID(IID_IDirectInputDevice7W, 0x57D7C6BD,0x2356,0x11D3,0x8E,0x9D,0x00,0xC0,0x4F,0x68,0x44,0xAE);
+DEFINE_GUID(IID_IDirectInputDevice8A, 0x54D41080,0xDC15,0x4833,0xA4,0x1B,0x74,0x8F,0x73,0xA3,0x81,0x79);
+DEFINE_GUID(IID_IDirectInputDevice8W, 0x54D41081,0xDC15,0x4833,0xA4,0x1B,0x74,0x8F,0x73,0xA3,0x81,0x79);
+DEFINE_GUID(IID_IDirectInputEffect, 0xE7E1F7C0,0x88D2,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+
+/* Predefined object types */
+DEFINE_GUID(GUID_XAxis, 0xA36D02E0,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_YAxis, 0xA36D02E1,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_ZAxis, 0xA36D02E2,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_RxAxis,0xA36D02F4,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_RyAxis,0xA36D02F5,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_RzAxis,0xA36D02E3,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_Slider,0xA36D02E4,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_Button,0xA36D02F0,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_Key, 0x55728220,0xD33C,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_POV, 0xA36D02F2,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_Unknown,0xA36D02F3,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+
+/* Predefined product GUIDs */
+DEFINE_GUID(GUID_SysMouse, 0x6F1D2B60,0xD5A0,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_SysKeyboard, 0x6F1D2B61,0xD5A0,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_Joystick, 0x6F1D2B70,0xD5A0,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_SysMouseEm, 0x6F1D2B80,0xD5A0,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_SysMouseEm2, 0x6F1D2B81,0xD5A0,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_SysKeyboardEm, 0x6F1D2B82,0xD5A0,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_SysKeyboardEm2,0x6F1D2B83,0xD5A0,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+
+/* predefined forcefeedback effects */
+DEFINE_GUID(GUID_ConstantForce, 0x13541C20,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+DEFINE_GUID(GUID_RampForce, 0x13541C21,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+DEFINE_GUID(GUID_Square, 0x13541C22,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+DEFINE_GUID(GUID_Sine, 0x13541C23,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+DEFINE_GUID(GUID_Triangle, 0x13541C24,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+DEFINE_GUID(GUID_SawtoothUp, 0x13541C25,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+DEFINE_GUID(GUID_SawtoothDown, 0x13541C26,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+DEFINE_GUID(GUID_Spring, 0x13541C27,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+DEFINE_GUID(GUID_Damper, 0x13541C28,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+DEFINE_GUID(GUID_Inertia, 0x13541C29,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+DEFINE_GUID(GUID_Friction, 0x13541C2A,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+DEFINE_GUID(GUID_CustomForce, 0x13541C2B,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+
+typedef struct IDirectInputA *LPDIRECTINPUTA;
+typedef struct IDirectInputW *LPDIRECTINPUTW;
+typedef struct IDirectInput2A *LPDIRECTINPUT2A;
+typedef struct IDirectInput2W *LPDIRECTINPUT2W;
+typedef struct IDirectInput7A *LPDIRECTINPUT7A;
+typedef struct IDirectInput7W *LPDIRECTINPUT7W;
+#if DIRECTINPUT_VERSION >= 0x0800
+typedef struct IDirectInput8A *LPDIRECTINPUT8A;
+typedef struct IDirectInput8W *LPDIRECTINPUT8W;
+#endif /* DI8 */
+typedef struct IDirectInputDeviceA *LPDIRECTINPUTDEVICEA;
+typedef struct IDirectInputDeviceW *LPDIRECTINPUTDEVICEW;
+#if DIRECTINPUT_VERSION >= 0x0500
+typedef struct IDirectInputDevice2A *LPDIRECTINPUTDEVICE2A;
+typedef struct IDirectInputDevice2W *LPDIRECTINPUTDEVICE2W;
+#endif /* DI5 */
+#if DIRECTINPUT_VERSION >= 0x0700
+typedef struct IDirectInputDevice7A *LPDIRECTINPUTDEVICE7A;
+typedef struct IDirectInputDevice7W *LPDIRECTINPUTDEVICE7W;
+#endif /* DI7 */
+#if DIRECTINPUT_VERSION >= 0x0800
+typedef struct IDirectInputDevice8A *LPDIRECTINPUTDEVICE8A;
+typedef struct IDirectInputDevice8W *LPDIRECTINPUTDEVICE8W;
+#endif /* DI8 */
+#if DIRECTINPUT_VERSION >= 0x0500
+typedef struct IDirectInputEffect *LPDIRECTINPUTEFFECT;
+#endif /* DI5 */
+typedef struct SysKeyboardA *LPSYSKEYBOARDA;
+typedef struct SysMouseA *LPSYSMOUSEA;
+
+#define IID_IDirectInput WINELIB_NAME_AW(IID_IDirectInput)
+#define IDirectInput WINELIB_NAME_AW(IDirectInput)
+DECL_WINELIB_TYPE_AW(LPDIRECTINPUT)
+#define IID_IDirectInput2 WINELIB_NAME_AW(IID_IDirectInput2)
+#define IDirectInput2 WINELIB_NAME_AW(IDirectInput2)
+DECL_WINELIB_TYPE_AW(LPDIRECTINPUT2)
+#define IID_IDirectInput7 WINELIB_NAME_AW(IID_IDirectInput7)
+#define IDirectInput7 WINELIB_NAME_AW(IDirectInput7)
+DECL_WINELIB_TYPE_AW(LPDIRECTINPUT7)
+#if DIRECTINPUT_VERSION >= 0x0800
+#define IID_IDirectInput8 WINELIB_NAME_AW(IID_IDirectInput8)
+#define IDirectInput8 WINELIB_NAME_AW(IDirectInput8)
+DECL_WINELIB_TYPE_AW(LPDIRECTINPUT8)
+#endif /* DI8 */
+#define IID_IDirectInputDevice WINELIB_NAME_AW(IID_IDirectInputDevice)
+#define IDirectInputDevice WINELIB_NAME_AW(IDirectInputDevice)
+DECL_WINELIB_TYPE_AW(LPDIRECTINPUTDEVICE)
+#if DIRECTINPUT_VERSION >= 0x0500
+#define IID_IDirectInputDevice2 WINELIB_NAME_AW(IID_IDirectInputDevice2)
+#define IDirectInputDevice2 WINELIB_NAME_AW(IDirectInputDevice2)
+DECL_WINELIB_TYPE_AW(LPDIRECTINPUTDEVICE2)
+#endif /* DI5 */
+#if DIRECTINPUT_VERSION >= 0x0700
+#define IID_IDirectInputDevice7 WINELIB_NAME_AW(IID_IDirectInputDevice7)
+#define IDirectInputDevice7 WINELIB_NAME_AW(IDirectInputDevice7)
+DECL_WINELIB_TYPE_AW(LPDIRECTINPUTDEVICE7)
+#endif /* DI7 */
+#if DIRECTINPUT_VERSION >= 0x0800
+#define IID_IDirectInputDevice8 WINELIB_NAME_AW(IID_IDirectInputDevice8)
+#define IDirectInputDevice8 WINELIB_NAME_AW(IDirectInputDevice8)
+DECL_WINELIB_TYPE_AW(LPDIRECTINPUTDEVICE8)
+#endif /* DI8 */
+
+#define DI_OK S_OK
+#define DI_NOTATTACHED S_FALSE
+#define DI_BUFFEROVERFLOW S_FALSE
+#define DI_PROPNOEFFECT S_FALSE
+#define DI_NOEFFECT S_FALSE
+#define DI_POLLEDDEVICE ((HRESULT)0x00000002L)
+#define DI_DOWNLOADSKIPPED ((HRESULT)0x00000003L)
+#define DI_EFFECTRESTARTED ((HRESULT)0x00000004L)
+#define DI_TRUNCATED ((HRESULT)0x00000008L)
+#define DI_SETTINGSNOTSAVED ((HRESULT)0x0000000BL)
+#define DI_TRUNCATEDANDRESTARTED ((HRESULT)0x0000000CL)
+#define DI_WRITEPROTECT ((HRESULT)0x00000013L)
+
+#define DIERR_OLDDIRECTINPUTVERSION \
+ MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_OLD_WIN_VERSION)
+#define DIERR_BETADIRECTINPUTVERSION \
+ MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_RMODE_APP)
+#define DIERR_BADDRIVERVER \
+ MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_BAD_DRIVER_LEVEL)
+#define DIERR_DEVICENOTREG REGDB_E_CLASSNOTREG
+#define DIERR_NOTFOUND \
+ MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_FILE_NOT_FOUND)
+#define DIERR_OBJECTNOTFOUND \
+ MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_FILE_NOT_FOUND)
+#define DIERR_INVALIDPARAM E_INVALIDARG
+#define DIERR_NOINTERFACE E_NOINTERFACE
+#define DIERR_GENERIC E_FAIL
+#define DIERR_OUTOFMEMORY E_OUTOFMEMORY
+#define DIERR_UNSUPPORTED E_NOTIMPL
+#define DIERR_NOTINITIALIZED \
+ MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_READY)
+#define DIERR_ALREADYINITIALIZED \
+ MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_ALREADY_INITIALIZED)
+#define DIERR_NOAGGREGATION CLASS_E_NOAGGREGATION
+#define DIERR_OTHERAPPHASPRIO E_ACCESSDENIED
+#define DIERR_INPUTLOST \
+ MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_READ_FAULT)
+#define DIERR_ACQUIRED \
+ MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_BUSY)
+#define DIERR_NOTACQUIRED \
+ MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_INVALID_ACCESS)
+#define DIERR_READONLY E_ACCESSDENIED
+#define DIERR_HANDLEEXISTS E_ACCESSDENIED
+#ifndef E_PENDING
+#define E_PENDING 0x8000000AL
+#endif
+#define DIERR_INSUFFICIENTPRIVS 0x80040200L
+#define DIERR_DEVICEFULL 0x80040201L
+#define DIERR_MOREDATA 0x80040202L
+#define DIERR_NOTDOWNLOADED 0x80040203L
+#define DIERR_HASEFFECTS 0x80040204L
+#define DIERR_NOTEXCLUSIVEACQUIRED 0x80040205L
+#define DIERR_INCOMPLETEEFFECT 0x80040206L
+#define DIERR_NOTBUFFERED 0x80040207L
+#define DIERR_EFFECTPLAYING 0x80040208L
+#define DIERR_UNPLUGGED 0x80040209L
+#define DIERR_REPORTFULL 0x8004020AL
+#define DIERR_MAPFILEFAIL 0x8004020BL
+
+#define DIENUM_STOP 0
+#define DIENUM_CONTINUE 1
+
+#define DIEDFL_ALLDEVICES 0x00000000
+#define DIEDFL_ATTACHEDONLY 0x00000001
+#define DIEDFL_FORCEFEEDBACK 0x00000100
+#define DIEDFL_INCLUDEALIASES 0x00010000
+#define DIEDFL_INCLUDEPHANTOMS 0x00020000
+#define DIEDFL_INCLUDEHIDDEN 0x00040000
+
+#define DIDEVTYPE_DEVICE 1
+#define DIDEVTYPE_MOUSE 2
+#define DIDEVTYPE_KEYBOARD 3
+#define DIDEVTYPE_JOYSTICK 4
+#define DIDEVTYPE_HID 0x00010000
+
+#define DI8DEVCLASS_ALL 0
+#define DI8DEVCLASS_DEVICE 1
+#define DI8DEVCLASS_POINTER 2
+#define DI8DEVCLASS_KEYBOARD 3
+#define DI8DEVCLASS_GAMECTRL 4
+
+#define DI8DEVTYPE_DEVICE 0x11
+#define DI8DEVTYPE_MOUSE 0x12
+#define DI8DEVTYPE_KEYBOARD 0x13
+#define DI8DEVTYPE_JOYSTICK 0x14
+#define DI8DEVTYPE_GAMEPAD 0x15
+#define DI8DEVTYPE_DRIVING 0x16
+#define DI8DEVTYPE_FLIGHT 0x17
+#define DI8DEVTYPE_1STPERSON 0x18
+#define DI8DEVTYPE_DEVICECTRL 0x19
+#define DI8DEVTYPE_SCREENPOINTER 0x1A
+#define DI8DEVTYPE_REMOTE 0x1B
+#define DI8DEVTYPE_SUPPLEMENTAL 0x1C
+
+#define DIDEVTYPEMOUSE_UNKNOWN 1
+#define DIDEVTYPEMOUSE_TRADITIONAL 2
+#define DIDEVTYPEMOUSE_FINGERSTICK 3
+#define DIDEVTYPEMOUSE_TOUCHPAD 4
+#define DIDEVTYPEMOUSE_TRACKBALL 5
+
+#define DIDEVTYPEKEYBOARD_UNKNOWN 0
+#define DIDEVTYPEKEYBOARD_PCXT 1
+#define DIDEVTYPEKEYBOARD_OLIVETTI 2
+#define DIDEVTYPEKEYBOARD_PCAT 3
+#define DIDEVTYPEKEYBOARD_PCENH 4
+#define DIDEVTYPEKEYBOARD_NOKIA1050 5
+#define DIDEVTYPEKEYBOARD_NOKIA9140 6
+#define DIDEVTYPEKEYBOARD_NEC98 7
+#define DIDEVTYPEKEYBOARD_NEC98LAPTOP 8
+#define DIDEVTYPEKEYBOARD_NEC98106 9
+#define DIDEVTYPEKEYBOARD_JAPAN106 10
+#define DIDEVTYPEKEYBOARD_JAPANAX 11
+#define DIDEVTYPEKEYBOARD_J3100 12
+
+#define DIDEVTYPEJOYSTICK_UNKNOWN 1
+#define DIDEVTYPEJOYSTICK_TRADITIONAL 2
+#define DIDEVTYPEJOYSTICK_FLIGHTSTICK 3
+#define DIDEVTYPEJOYSTICK_GAMEPAD 4
+#define DIDEVTYPEJOYSTICK_RUDDER 5
+#define DIDEVTYPEJOYSTICK_WHEEL 6
+#define DIDEVTYPEJOYSTICK_HEADTRACKER 7
+
+#define DI8DEVTYPEMOUSE_UNKNOWN 1
+#define DI8DEVTYPEMOUSE_TRADITIONAL 2
+#define DI8DEVTYPEMOUSE_FINGERSTICK 3
+#define DI8DEVTYPEMOUSE_TOUCHPAD 4
+#define DI8DEVTYPEMOUSE_TRACKBALL 5
+#define DI8DEVTYPEMOUSE_ABSOLUTE 6
+
+#define DI8DEVTYPEKEYBOARD_UNKNOWN 0
+#define DI8DEVTYPEKEYBOARD_PCXT 1
+#define DI8DEVTYPEKEYBOARD_OLIVETTI 2
+#define DI8DEVTYPEKEYBOARD_PCAT 3
+#define DI8DEVTYPEKEYBOARD_PCENH 4
+#define DI8DEVTYPEKEYBOARD_NOKIA1050 5
+#define DI8DEVTYPEKEYBOARD_NOKIA9140 6
+#define DI8DEVTYPEKEYBOARD_NEC98 7
+#define DI8DEVTYPEKEYBOARD_NEC98LAPTOP 8
+#define DI8DEVTYPEKEYBOARD_NEC98106 9
+#define DI8DEVTYPEKEYBOARD_JAPAN106 10
+#define DI8DEVTYPEKEYBOARD_JAPANAX 11
+#define DI8DEVTYPEKEYBOARD_J3100 12
+
+#define DI8DEVTYPE_LIMITEDGAMESUBTYPE 1
+
+#define DI8DEVTYPEJOYSTICK_LIMITED DI8DEVTYPE_LIMITEDGAMESUBTYPE
+#define DI8DEVTYPEJOYSTICK_STANDARD 2
+
+#define DI8DEVTYPEGAMEPAD_LIMITED DI8DEVTYPE_LIMITEDGAMESUBTYPE
+#define DI8DEVTYPEGAMEPAD_STANDARD 2
+#define DI8DEVTYPEGAMEPAD_TILT 3
+
+#define DI8DEVTYPEDRIVING_LIMITED DI8DEVTYPE_LIMITEDGAMESUBTYPE
+#define DI8DEVTYPEDRIVING_COMBINEDPEDALS 2
+#define DI8DEVTYPEDRIVING_DUALPEDALS 3
+#define DI8DEVTYPEDRIVING_THREEPEDALS 4
+#define DI8DEVTYPEDRIVING_HANDHELD 5
+
+#define DI8DEVTYPEFLIGHT_LIMITED DI8DEVTYPE_LIMITEDGAMESUBTYPE
+#define DI8DEVTYPEFLIGHT_STICK 2
+#define DI8DEVTYPEFLIGHT_YOKE 3
+#define DI8DEVTYPEFLIGHT_RC 4
+
+#define DI8DEVTYPE1STPERSON_LIMITED DI8DEVTYPE_LIMITEDGAMESUBTYPE
+#define DI8DEVTYPE1STPERSON_UNKNOWN 2
+#define DI8DEVTYPE1STPERSON_SIXDOF 3
+#define DI8DEVTYPE1STPERSON_SHOOTER 4
+
+#define DI8DEVTYPESCREENPTR_UNKNOWN 2
+#define DI8DEVTYPESCREENPTR_LIGHTGUN 3
+#define DI8DEVTYPESCREENPTR_LIGHTPEN 4
+#define DI8DEVTYPESCREENPTR_TOUCH 5
+
+#define DI8DEVTYPEREMOTE_UNKNOWN 2
+
+#define DI8DEVTYPEDEVICECTRL_UNKNOWN 2
+#define DI8DEVTYPEDEVICECTRL_COMMSSELECTION 3
+#define DI8DEVTYPEDEVICECTRL_COMMSSELECTION_HARDWIRED 4
+
+#define DI8DEVTYPESUPPLEMENTAL_UNKNOWN 2
+#define DI8DEVTYPESUPPLEMENTAL_2NDHANDCONTROLLER 3
+#define DI8DEVTYPESUPPLEMENTAL_HEADTRACKER 4
+#define DI8DEVTYPESUPPLEMENTAL_HANDTRACKER 5
+#define DI8DEVTYPESUPPLEMENTAL_SHIFTSTICKGATE 6
+#define DI8DEVTYPESUPPLEMENTAL_SHIFTER 7
+#define DI8DEVTYPESUPPLEMENTAL_THROTTLE 8
+#define DI8DEVTYPESUPPLEMENTAL_SPLITTHROTTLE 9
+#define DI8DEVTYPESUPPLEMENTAL_COMBINEDPEDALS 10
+#define DI8DEVTYPESUPPLEMENTAL_DUALPEDALS 11
+#define DI8DEVTYPESUPPLEMENTAL_THREEPEDALS 12
+#define DI8DEVTYPESUPPLEMENTAL_RUDDERPEDALS 13
+
+#define GET_DIDEVICE_TYPE(dwDevType) LOBYTE(dwDevType)
+#define GET_DIDEVICE_SUBTYPE(dwDevType) HIBYTE(dwDevType)
+
+typedef struct DIDEVICEOBJECTINSTANCE_DX3A {
+ DWORD dwSize;
+ GUID guidType;
+ DWORD dwOfs;
+ DWORD dwType;
+ DWORD dwFlags;
+ CHAR tszName[MAX_PATH];
+} DIDEVICEOBJECTINSTANCE_DX3A, *LPDIDEVICEOBJECTINSTANCE_DX3A;
+typedef const DIDEVICEOBJECTINSTANCE_DX3A *LPCDIDEVICEOBJECTINSTANCE_DX3A;
+typedef struct DIDEVICEOBJECTINSTANCE_DX3W {
+ DWORD dwSize;
+ GUID guidType;
+ DWORD dwOfs;
+ DWORD dwType;
+ DWORD dwFlags;
+ WCHAR tszName[MAX_PATH];
+} DIDEVICEOBJECTINSTANCE_DX3W, *LPDIDEVICEOBJECTINSTANCE_DX3W;
+typedef const DIDEVICEOBJECTINSTANCE_DX3W *LPCDIDEVICEOBJECTINSTANCE_DX3W;
+
+DECL_WINELIB_TYPE_AW(DIDEVICEOBJECTINSTANCE_DX3)
+DECL_WINELIB_TYPE_AW(LPDIDEVICEOBJECTINSTANCE_DX3)
+DECL_WINELIB_TYPE_AW(LPCDIDEVICEOBJECTINSTANCE_DX3)
+
+typedef struct DIDEVICEOBJECTINSTANCEA {
+ DWORD dwSize;
+ GUID guidType;
+ DWORD dwOfs;
+ DWORD dwType;
+ DWORD dwFlags;
+ CHAR tszName[MAX_PATH];
+#if(DIRECTINPUT_VERSION >= 0x0500)
+ DWORD dwFFMaxForce;
+ DWORD dwFFForceResolution;
+ WORD wCollectionNumber;
+ WORD wDesignatorIndex;
+ WORD wUsagePage;
+ WORD wUsage;
+ DWORD dwDimension;
+ WORD wExponent;
+ WORD wReserved;
+#endif /* DIRECTINPUT_VERSION >= 0x0500 */
+} DIDEVICEOBJECTINSTANCEA, *LPDIDEVICEOBJECTINSTANCEA;
+typedef const DIDEVICEOBJECTINSTANCEA *LPCDIDEVICEOBJECTINSTANCEA;
+
+typedef struct DIDEVICEOBJECTINSTANCEW {
+ DWORD dwSize;
+ GUID guidType;
+ DWORD dwOfs;
+ DWORD dwType;
+ DWORD dwFlags;
+ WCHAR tszName[MAX_PATH];
+#if(DIRECTINPUT_VERSION >= 0x0500)
+ DWORD dwFFMaxForce;
+ DWORD dwFFForceResolution;
+ WORD wCollectionNumber;
+ WORD wDesignatorIndex;
+ WORD wUsagePage;
+ WORD wUsage;
+ DWORD dwDimension;
+ WORD wExponent;
+ WORD wReserved;
+#endif /* DIRECTINPUT_VERSION >= 0x0500 */
+} DIDEVICEOBJECTINSTANCEW, *LPDIDEVICEOBJECTINSTANCEW;
+typedef const DIDEVICEOBJECTINSTANCEW *LPCDIDEVICEOBJECTINSTANCEW;
+
+DECL_WINELIB_TYPE_AW(DIDEVICEOBJECTINSTANCE)
+DECL_WINELIB_TYPE_AW(LPDIDEVICEOBJECTINSTANCE)
+DECL_WINELIB_TYPE_AW(LPCDIDEVICEOBJECTINSTANCE)
+
+typedef struct DIDEVICEINSTANCE_DX3A {
+ DWORD dwSize;
+ GUID guidInstance;
+ GUID guidProduct;
+ DWORD dwDevType;
+ CHAR tszInstanceName[MAX_PATH];
+ CHAR tszProductName[MAX_PATH];
+} DIDEVICEINSTANCE_DX3A, *LPDIDEVICEINSTANCE_DX3A;
+typedef const DIDEVICEINSTANCE_DX3A *LPCDIDEVICEINSTANCE_DX3A;
+typedef struct DIDEVICEINSTANCE_DX3W {
+ DWORD dwSize;
+ GUID guidInstance;
+ GUID guidProduct;
+ DWORD dwDevType;
+ WCHAR tszInstanceName[MAX_PATH];
+ WCHAR tszProductName[MAX_PATH];
+} DIDEVICEINSTANCE_DX3W, *LPDIDEVICEINSTANCE_DX3W;
+typedef const DIDEVICEINSTANCE_DX3W *LPCDIDEVICEINSTANCE_DX3W;
+
+DECL_WINELIB_TYPE_AW(DIDEVICEINSTANCE_DX3)
+DECL_WINELIB_TYPE_AW(LPDIDEVICEINSTANCE_DX3)
+DECL_WINELIB_TYPE_AW(LPCDIDEVICEINSTANCE_DX3)
+
+typedef struct DIDEVICEINSTANCEA {
+ DWORD dwSize;
+ GUID guidInstance;
+ GUID guidProduct;
+ DWORD dwDevType;
+ CHAR tszInstanceName[MAX_PATH];
+ CHAR tszProductName[MAX_PATH];
+#if(DIRECTINPUT_VERSION >= 0x0500)
+ GUID guidFFDriver;
+ WORD wUsagePage;
+ WORD wUsage;
+#endif /* DIRECTINPUT_VERSION >= 0x0500 */
+} DIDEVICEINSTANCEA, *LPDIDEVICEINSTANCEA;
+typedef const DIDEVICEINSTANCEA *LPCDIDEVICEINSTANCEA;
+
+typedef struct DIDEVICEINSTANCEW {
+ DWORD dwSize;
+ GUID guidInstance;
+ GUID guidProduct;
+ DWORD dwDevType;
+ WCHAR tszInstanceName[MAX_PATH];
+ WCHAR tszProductName[MAX_PATH];
+#if(DIRECTINPUT_VERSION >= 0x0500)
+ GUID guidFFDriver;
+ WORD wUsagePage;
+ WORD wUsage;
+#endif /* DIRECTINPUT_VERSION >= 0x0500 */
+} DIDEVICEINSTANCEW, *LPDIDEVICEINSTANCEW;
+typedef const DIDEVICEINSTANCEW *LPCDIDEVICEINSTANCEW;
+
+DECL_WINELIB_TYPE_AW(DIDEVICEINSTANCE)
+DECL_WINELIB_TYPE_AW(LPDIDEVICEINSTANCE)
+DECL_WINELIB_TYPE_AW(LPCDIDEVICEINSTANCE)
+
+typedef BOOL (CALLBACK *LPDIENUMDEVICESCALLBACKA)(LPCDIDEVICEINSTANCEA,LPVOID);
+typedef BOOL (CALLBACK *LPDIENUMDEVICESCALLBACKW)(LPCDIDEVICEINSTANCEW,LPVOID);
+DECL_WINELIB_TYPE_AW(LPDIENUMDEVICESCALLBACK)
+
+#define DIEDBS_MAPPEDPRI1 0x00000001
+#define DIEDBS_MAPPEDPRI2 0x00000002
+#define DIEDBS_RECENTDEVICE 0x00000010
+#define DIEDBS_NEWDEVICE 0x00000020
+
+#define DIEDBSFL_ATTACHEDONLY 0x00000000
+#define DIEDBSFL_THISUSER 0x00000010
+#define DIEDBSFL_FORCEFEEDBACK DIEDFL_FORCEFEEDBACK
+#define DIEDBSFL_AVAILABLEDEVICES 0x00001000
+#define DIEDBSFL_MULTIMICEKEYBOARDS 0x00002000
+#define DIEDBSFL_NONGAMINGDEVICES 0x00004000
+#define DIEDBSFL_VALID 0x00007110
+
+#if DIRECTINPUT_VERSION >= 0x0800
+typedef BOOL (CALLBACK *LPDIENUMDEVICESBYSEMANTICSCBA)(LPCDIDEVICEINSTANCEA,LPDIRECTINPUTDEVICE8A,DWORD,DWORD,LPVOID);
+typedef BOOL (CALLBACK *LPDIENUMDEVICESBYSEMANTICSCBW)(LPCDIDEVICEINSTANCEW,LPDIRECTINPUTDEVICE8W,DWORD,DWORD,LPVOID);
+DECL_WINELIB_TYPE_AW(LPDIENUMDEVICESBYSEMANTICSCB)
+#endif
+
+typedef BOOL (CALLBACK *LPDICONFIGUREDEVICESCALLBACK)(LPUNKNOWN,LPVOID);
+
+typedef BOOL (CALLBACK *LPDIENUMDEVICEOBJECTSCALLBACKA)(LPCDIDEVICEOBJECTINSTANCEA,LPVOID);
+typedef BOOL (CALLBACK *LPDIENUMDEVICEOBJECTSCALLBACKW)(LPCDIDEVICEOBJECTINSTANCEW,LPVOID);
+DECL_WINELIB_TYPE_AW(LPDIENUMDEVICEOBJECTSCALLBACK)
+
+#if DIRECTINPUT_VERSION >= 0x0500
+typedef BOOL (CALLBACK *LPDIENUMCREATEDEFFECTOBJECTSCALLBACK)(LPDIRECTINPUTEFFECT, LPVOID);
+#endif
+
+#define DIK_ESCAPE 0x01
+#define DIK_1 0x02
+#define DIK_2 0x03
+#define DIK_3 0x04
+#define DIK_4 0x05
+#define DIK_5 0x06
+#define DIK_6 0x07
+#define DIK_7 0x08
+#define DIK_8 0x09
+#define DIK_9 0x0A
+#define DIK_0 0x0B
+#define DIK_MINUS 0x0C /* - on main keyboard */
+#define DIK_EQUALS 0x0D
+#define DIK_BACK 0x0E /* backspace */
+#define DIK_TAB 0x0F
+#define DIK_Q 0x10
+#define DIK_W 0x11
+#define DIK_E 0x12
+#define DIK_R 0x13
+#define DIK_T 0x14
+#define DIK_Y 0x15
+#define DIK_U 0x16
+#define DIK_I 0x17
+#define DIK_O 0x18
+#define DIK_P 0x19
+#define DIK_LBRACKET 0x1A
+#define DIK_RBRACKET 0x1B
+#define DIK_RETURN 0x1C /* Enter on main keyboard */
+#define DIK_LCONTROL 0x1D
+#define DIK_A 0x1E
+#define DIK_S 0x1F
+#define DIK_D 0x20
+#define DIK_F 0x21
+#define DIK_G 0x22
+#define DIK_H 0x23
+#define DIK_J 0x24
+#define DIK_K 0x25
+#define DIK_L 0x26
+#define DIK_SEMICOLON 0x27
+#define DIK_APOSTROPHE 0x28
+#define DIK_GRAVE 0x29 /* accent grave */
+#define DIK_LSHIFT 0x2A
+#define DIK_BACKSLASH 0x2B
+#define DIK_Z 0x2C
+#define DIK_X 0x2D
+#define DIK_C 0x2E
+#define DIK_V 0x2F
+#define DIK_B 0x30
+#define DIK_N 0x31
+#define DIK_M 0x32
+#define DIK_COMMA 0x33
+#define DIK_PERIOD 0x34 /* . on main keyboard */
+#define DIK_SLASH 0x35 /* / on main keyboard */
+#define DIK_RSHIFT 0x36
+#define DIK_MULTIPLY 0x37 /* * on numeric keypad */
+#define DIK_LMENU 0x38 /* left Alt */
+#define DIK_SPACE 0x39
+#define DIK_CAPITAL 0x3A
+#define DIK_F1 0x3B
+#define DIK_F2 0x3C
+#define DIK_F3 0x3D
+#define DIK_F4 0x3E
+#define DIK_F5 0x3F
+#define DIK_F6 0x40
+#define DIK_F7 0x41
+#define DIK_F8 0x42
+#define DIK_F9 0x43
+#define DIK_F10 0x44
+#define DIK_NUMLOCK 0x45
+#define DIK_SCROLL 0x46 /* Scroll Lock */
+#define DIK_NUMPAD7 0x47
+#define DIK_NUMPAD8 0x48
+#define DIK_NUMPAD9 0x49
+#define DIK_SUBTRACT 0x4A /* - on numeric keypad */
+#define DIK_NUMPAD4 0x4B
+#define DIK_NUMPAD5 0x4C
+#define DIK_NUMPAD6 0x4D
+#define DIK_ADD 0x4E /* + on numeric keypad */
+#define DIK_NUMPAD1 0x4F
+#define DIK_NUMPAD2 0x50
+#define DIK_NUMPAD3 0x51
+#define DIK_NUMPAD0 0x52
+#define DIK_DECIMAL 0x53 /* . on numeric keypad */
+#define DIK_OEM_102 0x56 /* < > | on UK/Germany keyboards */
+#define DIK_F11 0x57
+#define DIK_F12 0x58
+#define DIK_F13 0x64 /* (NEC PC98) */
+#define DIK_F14 0x65 /* (NEC PC98) */
+#define DIK_F15 0x66 /* (NEC PC98) */
+#define DIK_KANA 0x70 /* (Japanese keyboard) */
+#define DIK_ABNT_C1 0x73 /* / ? on Portugese (Brazilian) keyboards */
+#define DIK_CONVERT 0x79 /* (Japanese keyboard) */
+#define DIK_NOCONVERT 0x7B /* (Japanese keyboard) */
+#define DIK_YEN 0x7D /* (Japanese keyboard) */
+#define DIK_ABNT_C2 0x7E /* Numpad . on Portugese (Brazilian) keyboards */
+#define DIK_NUMPADEQUALS 0x8D /* = on numeric keypad (NEC PC98) */
+#define DIK_CIRCUMFLEX 0x90 /* (Japanese keyboard) */
+#define DIK_AT 0x91 /* (NEC PC98) */
+#define DIK_COLON 0x92 /* (NEC PC98) */
+#define DIK_UNDERLINE 0x93 /* (NEC PC98) */
+#define DIK_KANJI 0x94 /* (Japanese keyboard) */
+#define DIK_STOP 0x95 /* (NEC PC98) */
+#define DIK_AX 0x96 /* (Japan AX) */
+#define DIK_UNLABELED 0x97 /* (J3100) */
+#define DIK_NEXTTRACK 0x99 /* Next Track */
+#define DIK_NUMPADENTER 0x9C /* Enter on numeric keypad */
+#define DIK_RCONTROL 0x9D
+#define DIK_MUTE 0xA0 /* Mute */
+#define DIK_CALCULATOR 0xA1 /* Calculator */
+#define DIK_PLAYPAUSE 0xA2 /* Play / Pause */
+#define DIK_MEDIASTOP 0xA4 /* Media Stop */
+#define DIK_VOLUMEDOWN 0xAE /* Volume - */
+#define DIK_VOLUMEUP 0xB0 /* Volume + */
+#define DIK_WEBHOME 0xB2 /* Web home */
+#define DIK_NUMPADCOMMA 0xB3 /* , on numeric keypad (NEC PC98) */
+#define DIK_DIVIDE 0xB5 /* / on numeric keypad */
+#define DIK_SYSRQ 0xB7
+#define DIK_RMENU 0xB8 /* right Alt */
+#define DIK_PAUSE 0xC5 /* Pause */
+#define DIK_HOME 0xC7 /* Home on arrow keypad */
+#define DIK_UP 0xC8 /* UpArrow on arrow keypad */
+#define DIK_PRIOR 0xC9 /* PgUp on arrow keypad */
+#define DIK_LEFT 0xCB /* LeftArrow on arrow keypad */
+#define DIK_RIGHT 0xCD /* RightArrow on arrow keypad */
+#define DIK_END 0xCF /* End on arrow keypad */
+#define DIK_DOWN 0xD0 /* DownArrow on arrow keypad */
+#define DIK_NEXT 0xD1 /* PgDn on arrow keypad */
+#define DIK_INSERT 0xD2 /* Insert on arrow keypad */
+#define DIK_DELETE 0xD3 /* Delete on arrow keypad */
+#define DIK_LWIN 0xDB /* Left Windows key */
+#define DIK_RWIN 0xDC /* Right Windows key */
+#define DIK_APPS 0xDD /* AppMenu key */
+#define DIK_POWER 0xDE
+#define DIK_SLEEP 0xDF
+#define DIK_WAKE 0xE3 /* System Wake */
+#define DIK_WEBSEARCH 0xE5 /* Web Search */
+#define DIK_WEBFAVORITES 0xE6 /* Web Favorites */
+#define DIK_WEBREFRESH 0xE7 /* Web Refresh */
+#define DIK_WEBSTOP 0xE8 /* Web Stop */
+#define DIK_WEBFORWARD 0xE9 /* Web Forward */
+#define DIK_WEBBACK 0xEA /* Web Back */
+#define DIK_MYCOMPUTER 0xEB /* My Computer */
+#define DIK_MAIL 0xEC /* Mail */
+#define DIK_MEDIASELECT 0xED /* Media Select */
+
+#define DIK_BACKSPACE DIK_BACK /* backspace */
+#define DIK_NUMPADSTAR DIK_MULTIPLY /* * on numeric keypad */
+#define DIK_LALT DIK_LMENU /* left Alt */
+#define DIK_CAPSLOCK DIK_CAPITAL /* CapsLock */
+#define DIK_NUMPADMINUS DIK_SUBTRACT /* - on numeric keypad */
+#define DIK_NUMPADPLUS DIK_ADD /* + on numeric keypad */
+#define DIK_NUMPADPERIOD DIK_DECIMAL /* . on numeric keypad */
+#define DIK_NUMPADSLASH DIK_DIVIDE /* / on numeric keypad */
+#define DIK_RALT DIK_RMENU /* right Alt */
+#define DIK_UPARROW DIK_UP /* UpArrow on arrow keypad */
+#define DIK_PGUP DIK_PRIOR /* PgUp on arrow keypad */
+#define DIK_LEFTARROW DIK_LEFT /* LeftArrow on arrow keypad */
+#define DIK_RIGHTARROW DIK_RIGHT /* RightArrow on arrow keypad */
+#define DIK_DOWNARROW DIK_DOWN /* DownArrow on arrow keypad */
+#define DIK_PGDN DIK_NEXT /* PgDn on arrow keypad */
+
+#define DIDFT_ALL 0x00000000
+#define DIDFT_RELAXIS 0x00000001
+#define DIDFT_ABSAXIS 0x00000002
+#define DIDFT_AXIS 0x00000003
+#define DIDFT_PSHBUTTON 0x00000004
+#define DIDFT_TGLBUTTON 0x00000008
+#define DIDFT_BUTTON 0x0000000C
+#define DIDFT_POV 0x00000010
+#define DIDFT_COLLECTION 0x00000040
+#define DIDFT_NODATA 0x00000080
+#define DIDFT_ANYINSTANCE 0x00FFFF00
+#define DIDFT_INSTANCEMASK DIDFT_ANYINSTANCE
+#define DIDFT_MAKEINSTANCE(n) ((WORD)(n) << 8)
+#define DIDFT_GETTYPE(n) LOBYTE(n)
+#define DIDFT_GETINSTANCE(n) LOWORD((n) >> 8)
+#define DIDFT_FFACTUATOR 0x01000000
+#define DIDFT_FFEFFECTTRIGGER 0x02000000
+#if DIRECTINPUT_VERSION >= 0x050a
+#define DIDFT_OUTPUT 0x10000000
+#define DIDFT_VENDORDEFINED 0x04000000
+#define DIDFT_ALIAS 0x08000000
+#endif /* DI5a */
+#ifndef DIDFT_OPTIONAL
+#define DIDFT_OPTIONAL 0x80000000
+#endif
+#define DIDFT_ENUMCOLLECTION(n) ((WORD)(n) << 8)
+#define DIDFT_NOCOLLECTION 0x00FFFF00
+
+#define DIDF_ABSAXIS 0x00000001
+#define DIDF_RELAXIS 0x00000002
+
+#define DIGDD_PEEK 0x00000001
+
+#define DISEQUENCE_COMPARE(dwSq1,cmp,dwSq2) ((int)((dwSq1) - (dwSq2)) cmp 0)
+
+typedef struct DIDEVICEOBJECTDATA_DX3 {
+ DWORD dwOfs;
+ DWORD dwData;
+ DWORD dwTimeStamp;
+ DWORD dwSequence;
+} DIDEVICEOBJECTDATA_DX3,*LPDIDEVICEOBJECTDATA_DX3;
+typedef const DIDEVICEOBJECTDATA_DX3 *LPCDIDEVICEOBJECTDATA_DX3;
+
+typedef struct DIDEVICEOBJECTDATA {
+ DWORD dwOfs;
+ DWORD dwData;
+ DWORD dwTimeStamp;
+ DWORD dwSequence;
+#if(DIRECTINPUT_VERSION >= 0x0800)
+ UINT_PTR uAppData;
+#endif /* DIRECTINPUT_VERSION >= 0x0800 */
+} DIDEVICEOBJECTDATA, *LPDIDEVICEOBJECTDATA;
+typedef const DIDEVICEOBJECTDATA *LPCDIDEVICEOBJECTDATA;
+
+typedef struct _DIOBJECTDATAFORMAT {
+ const GUID *pguid;
+ DWORD dwOfs;
+ DWORD dwType;
+ DWORD dwFlags;
+} DIOBJECTDATAFORMAT, *LPDIOBJECTDATAFORMAT;
+typedef const DIOBJECTDATAFORMAT *LPCDIOBJECTDATAFORMAT;
+
+typedef struct _DIDATAFORMAT {
+ DWORD dwSize;
+ DWORD dwObjSize;
+ DWORD dwFlags;
+ DWORD dwDataSize;
+ DWORD dwNumObjs;
+ LPDIOBJECTDATAFORMAT rgodf;
+} DIDATAFORMAT, *LPDIDATAFORMAT;
+typedef const DIDATAFORMAT *LPCDIDATAFORMAT;
+
+#if DIRECTINPUT_VERSION >= 0x0500
+#define DIDOI_FFACTUATOR 0x00000001
+#define DIDOI_FFEFFECTTRIGGER 0x00000002
+#define DIDOI_POLLED 0x00008000
+#define DIDOI_ASPECTPOSITION 0x00000100
+#define DIDOI_ASPECTVELOCITY 0x00000200
+#define DIDOI_ASPECTACCEL 0x00000300
+#define DIDOI_ASPECTFORCE 0x00000400
+#define DIDOI_ASPECTMASK 0x00000F00
+#endif /* DI5 */
+#if DIRECTINPUT_VERSION >= 0x050a
+#define DIDOI_GUIDISUSAGE 0x00010000
+#endif /* DI5a */
+
+typedef struct DIPROPHEADER {
+ DWORD dwSize;
+ DWORD dwHeaderSize;
+ DWORD dwObj;
+ DWORD dwHow;
+} DIPROPHEADER,*LPDIPROPHEADER;
+typedef const DIPROPHEADER *LPCDIPROPHEADER;
+
+#define DIPH_DEVICE 0
+#define DIPH_BYOFFSET 1
+#define DIPH_BYID 2
+#if DIRECTINPUT_VERSION >= 0x050a
+#define DIPH_BYUSAGE 3
+
+#define DIMAKEUSAGEDWORD(UsagePage, Usage) (DWORD)MAKELONG(Usage, UsagePage)
+#endif /* DI5a */
+
+typedef struct DIPROPDWORD {
+ DIPROPHEADER diph;
+ DWORD dwData;
+} DIPROPDWORD, *LPDIPROPDWORD;
+typedef const DIPROPDWORD *LPCDIPROPDWORD;
+
+typedef struct DIPROPRANGE {
+ DIPROPHEADER diph;
+ LONG lMin;
+ LONG lMax;
+} DIPROPRANGE, *LPDIPROPRANGE;
+typedef const DIPROPRANGE *LPCDIPROPRANGE;
+
+#define DIPROPRANGE_NOMIN ((LONG)0x80000000)
+#define DIPROPRANGE_NOMAX ((LONG)0x7FFFFFFF)
+
+#if DIRECTINPUT_VERSION >= 0x050a
+typedef struct DIPROPCAL {
+ DIPROPHEADER diph;
+ LONG lMin;
+ LONG lCenter;
+ LONG lMax;
+} DIPROPCAL, *LPDIPROPCAL;
+typedef const DIPROPCAL *LPCDIPROPCAL;
+
+typedef struct DIPROPCALPOV {
+ DIPROPHEADER diph;
+ LONG lMin[5];
+ LONG lMax[5];
+} DIPROPCALPOV, *LPDIPROPCALPOV;
+typedef const DIPROPCALPOV *LPCDIPROPCALPOV;
+
+typedef struct DIPROPGUIDANDPATH {
+ DIPROPHEADER diph;
+ GUID guidClass;
+ WCHAR wszPath[MAX_PATH];
+} DIPROPGUIDANDPATH, *LPDIPROPGUIDANDPATH;
+typedef const DIPROPGUIDANDPATH *LPCDIPROPGUIDANDPATH;
+
+typedef struct DIPROPSTRING {
+ DIPROPHEADER diph;
+ WCHAR wsz[MAX_PATH];
+} DIPROPSTRING, *LPDIPROPSTRING;
+typedef const DIPROPSTRING *LPCDIPROPSTRING;
+#endif /* DI5a */
+
+#if DIRECTINPUT_VERSION >= 0x0800
+typedef struct DIPROPPOINTER {
+ DIPROPHEADER diph;
+ UINT_PTR uData;
+} DIPROPPOINTER, *LPDIPROPPOINTER;
+typedef const DIPROPPOINTER *LPCDIPROPPOINTER;
+#endif /* DI8 */
+
+/* special property GUIDs */
+#ifdef __cplusplus
+#define MAKEDIPROP(prop) (*(const GUID *)(prop))
+#else
+#define MAKEDIPROP(prop) ((REFGUID)(prop))
+#endif
+#define DIPROP_BUFFERSIZE MAKEDIPROP(1)
+#define DIPROP_AXISMODE MAKEDIPROP(2)
+
+#define DIPROPAXISMODE_ABS 0
+#define DIPROPAXISMODE_REL 1
+
+#define DIPROP_GRANULARITY MAKEDIPROP(3)
+#define DIPROP_RANGE MAKEDIPROP(4)
+#define DIPROP_DEADZONE MAKEDIPROP(5)
+#define DIPROP_SATURATION MAKEDIPROP(6)
+#define DIPROP_FFGAIN MAKEDIPROP(7)
+#define DIPROP_FFLOAD MAKEDIPROP(8)
+#define DIPROP_AUTOCENTER MAKEDIPROP(9)
+
+#define DIPROPAUTOCENTER_OFF 0
+#define DIPROPAUTOCENTER_ON 1
+
+#define DIPROP_CALIBRATIONMODE MAKEDIPROP(10)
+
+#define DIPROPCALIBRATIONMODE_COOKED 0
+#define DIPROPCALIBRATIONMODE_RAW 1
+
+#if DIRECTINPUT_VERSION >= 0x050a
+#define DIPROP_CALIBRATION MAKEDIPROP(11)
+#define DIPROP_GUIDANDPATH MAKEDIPROP(12)
+#define DIPROP_INSTANCENAME MAKEDIPROP(13)
+#define DIPROP_PRODUCTNAME MAKEDIPROP(14)
+#endif
+
+#if DIRECTINPUT_VERSION >= 0x5B2
+#define DIPROP_JOYSTICKID MAKEDIPROP(15)
+#define DIPROP_GETPORTDISPLAYNAME MAKEDIPROP(16)
+#endif
+
+#if DIRECTINPUT_VERSION >= 0x0700
+#define DIPROP_PHYSICALRANGE MAKEDIPROP(18)
+#define DIPROP_LOGICALRANGE MAKEDIPROP(19)
+#endif
+
+#if(DIRECTINPUT_VERSION >= 0x0800)
+#define DIPROP_KEYNAME MAKEDIPROP(20)
+#define DIPROP_CPOINTS MAKEDIPROP(21)
+#define DIPROP_APPDATA MAKEDIPROP(22)
+#define DIPROP_SCANCODE MAKEDIPROP(23)
+#define DIPROP_VIDPID MAKEDIPROP(24)
+#define DIPROP_USERNAME MAKEDIPROP(25)
+#define DIPROP_TYPENAME MAKEDIPROP(26)
+
+#define MAXCPOINTSNUM 8
+
+typedef struct _CPOINT {
+ LONG lP;
+ DWORD dwLog;
+} CPOINT, *PCPOINT;
+
+typedef struct DIPROPCPOINTS {
+ DIPROPHEADER diph;
+ DWORD dwCPointsNum;
+ CPOINT cp[MAXCPOINTSNUM];
+} DIPROPCPOINTS, *LPDIPROPCPOINTS;
+typedef const DIPROPCPOINTS *LPCDIPROPCPOINTS;
+#endif /* DI8 */
+
+
+typedef struct DIDEVCAPS_DX3 {
+ DWORD dwSize;
+ DWORD dwFlags;
+ DWORD dwDevType;
+ DWORD dwAxes;
+ DWORD dwButtons;
+ DWORD dwPOVs;
+} DIDEVCAPS_DX3, *LPDIDEVCAPS_DX3;
+
+typedef struct DIDEVCAPS {
+ DWORD dwSize;
+ DWORD dwFlags;
+ DWORD dwDevType;
+ DWORD dwAxes;
+ DWORD dwButtons;
+ DWORD dwPOVs;
+#if(DIRECTINPUT_VERSION >= 0x0500)
+ DWORD dwFFSamplePeriod;
+ DWORD dwFFMinTimeResolution;
+ DWORD dwFirmwareRevision;
+ DWORD dwHardwareRevision;
+ DWORD dwFFDriverVersion;
+#endif /* DIRECTINPUT_VERSION >= 0x0500 */
+} DIDEVCAPS,*LPDIDEVCAPS;
+
+#define DIDC_ATTACHED 0x00000001
+#define DIDC_POLLEDDEVICE 0x00000002
+#define DIDC_EMULATED 0x00000004
+#define DIDC_POLLEDDATAFORMAT 0x00000008
+#define DIDC_FORCEFEEDBACK 0x00000100
+#define DIDC_FFATTACK 0x00000200
+#define DIDC_FFFADE 0x00000400
+#define DIDC_SATURATION 0x00000800
+#define DIDC_POSNEGCOEFFICIENTS 0x00001000
+#define DIDC_POSNEGSATURATION 0x00002000
+#define DIDC_DEADBAND 0x00004000
+#define DIDC_STARTDELAY 0x00008000
+#define DIDC_ALIAS 0x00010000
+#define DIDC_PHANTOM 0x00020000
+#define DIDC_HIDDEN 0x00040000
+
+
+/* SetCooperativeLevel dwFlags */
+#define DISCL_EXCLUSIVE 0x00000001
+#define DISCL_NONEXCLUSIVE 0x00000002
+#define DISCL_FOREGROUND 0x00000004
+#define DISCL_BACKGROUND 0x00000008
+#define DISCL_NOWINKEY 0x00000010
+
+#if (DIRECTINPUT_VERSION >= 0x0500)
+/* Device FF flags */
+#define DISFFC_RESET 0x00000001
+#define DISFFC_STOPALL 0x00000002
+#define DISFFC_PAUSE 0x00000004
+#define DISFFC_CONTINUE 0x00000008
+#define DISFFC_SETACTUATORSON 0x00000010
+#define DISFFC_SETACTUATORSOFF 0x00000020
+
+#define DIGFFS_EMPTY 0x00000001
+#define DIGFFS_STOPPED 0x00000002
+#define DIGFFS_PAUSED 0x00000004
+#define DIGFFS_ACTUATORSON 0x00000010
+#define DIGFFS_ACTUATORSOFF 0x00000020
+#define DIGFFS_POWERON 0x00000040
+#define DIGFFS_POWEROFF 0x00000080
+#define DIGFFS_SAFETYSWITCHON 0x00000100
+#define DIGFFS_SAFETYSWITCHOFF 0x00000200
+#define DIGFFS_USERFFSWITCHON 0x00000400
+#define DIGFFS_USERFFSWITCHOFF 0x00000800
+#define DIGFFS_DEVICELOST 0x80000000
+
+/* Effect flags */
+#define DIEFT_ALL 0x00000000
+
+#define DIEFT_CONSTANTFORCE 0x00000001
+#define DIEFT_RAMPFORCE 0x00000002
+#define DIEFT_PERIODIC 0x00000003
+#define DIEFT_CONDITION 0x00000004
+#define DIEFT_CUSTOMFORCE 0x00000005
+#define DIEFT_HARDWARE 0x000000FF
+#define DIEFT_FFATTACK 0x00000200
+#define DIEFT_FFFADE 0x00000400
+#define DIEFT_SATURATION 0x00000800
+#define DIEFT_POSNEGCOEFFICIENTS 0x00001000
+#define DIEFT_POSNEGSATURATION 0x00002000
+#define DIEFT_DEADBAND 0x00004000
+#define DIEFT_STARTDELAY 0x00008000
+#define DIEFT_GETTYPE(n) LOBYTE(n)
+
+#define DIEFF_OBJECTIDS 0x00000001
+#define DIEFF_OBJECTOFFSETS 0x00000002
+#define DIEFF_CARTESIAN 0x00000010
+#define DIEFF_POLAR 0x00000020
+#define DIEFF_SPHERICAL 0x00000040
+
+#define DIEP_DURATION 0x00000001
+#define DIEP_SAMPLEPERIOD 0x00000002
+#define DIEP_GAIN 0x00000004
+#define DIEP_TRIGGERBUTTON 0x00000008
+#define DIEP_TRIGGERREPEATINTERVAL 0x00000010
+#define DIEP_AXES 0x00000020
+#define DIEP_DIRECTION 0x00000040
+#define DIEP_ENVELOPE 0x00000080
+#define DIEP_TYPESPECIFICPARAMS 0x00000100
+#if(DIRECTINPUT_VERSION >= 0x0600)
+#define DIEP_STARTDELAY 0x00000200
+#define DIEP_ALLPARAMS_DX5 0x000001FF
+#define DIEP_ALLPARAMS 0x000003FF
+#else
+#define DIEP_ALLPARAMS 0x000001FF
+#endif /* DIRECTINPUT_VERSION >= 0x0600 */
+#define DIEP_START 0x20000000
+#define DIEP_NORESTART 0x40000000
+#define DIEP_NODOWNLOAD 0x80000000
+#define DIEB_NOTRIGGER 0xFFFFFFFF
+
+#define DIES_SOLO 0x00000001
+#define DIES_NODOWNLOAD 0x80000000
+
+#define DIEGES_PLAYING 0x00000001
+#define DIEGES_EMULATED 0x00000002
+
+#define DI_DEGREES 100
+#define DI_FFNOMINALMAX 10000
+#define DI_SECONDS 1000000
+
+typedef struct DICONSTANTFORCE {
+ LONG lMagnitude;
+} DICONSTANTFORCE, *LPDICONSTANTFORCE;
+typedef const DICONSTANTFORCE *LPCDICONSTANTFORCE;
+
+typedef struct DIRAMPFORCE {
+ LONG lStart;
+ LONG lEnd;
+} DIRAMPFORCE, *LPDIRAMPFORCE;
+typedef const DIRAMPFORCE *LPCDIRAMPFORCE;
+
+typedef struct DIPERIODIC {
+ DWORD dwMagnitude;
+ LONG lOffset;
+ DWORD dwPhase;
+ DWORD dwPeriod;
+} DIPERIODIC, *LPDIPERIODIC;
+typedef const DIPERIODIC *LPCDIPERIODIC;
+
+typedef struct DICONDITION {
+ LONG lOffset;
+ LONG lPositiveCoefficient;
+ LONG lNegativeCoefficient;
+ DWORD dwPositiveSaturation;
+ DWORD dwNegativeSaturation;
+ LONG lDeadBand;
+} DICONDITION, *LPDICONDITION;
+typedef const DICONDITION *LPCDICONDITION;
+
+typedef struct DICUSTOMFORCE {
+ DWORD cChannels;
+ DWORD dwSamplePeriod;
+ DWORD cSamples;
+ LPLONG rglForceData;
+} DICUSTOMFORCE, *LPDICUSTOMFORCE;
+typedef const DICUSTOMFORCE *LPCDICUSTOMFORCE;
+
+typedef struct DIENVELOPE {
+ DWORD dwSize;
+ DWORD dwAttackLevel;
+ DWORD dwAttackTime;
+ DWORD dwFadeLevel;
+ DWORD dwFadeTime;
+} DIENVELOPE, *LPDIENVELOPE;
+typedef const DIENVELOPE *LPCDIENVELOPE;
+
+typedef struct DIEFFECT_DX5 {
+ DWORD dwSize;
+ DWORD dwFlags;
+ DWORD dwDuration;
+ DWORD dwSamplePeriod;
+ DWORD dwGain;
+ DWORD dwTriggerButton;
+ DWORD dwTriggerRepeatInterval;
+ DWORD cAxes;
+ LPDWORD rgdwAxes;
+ LPLONG rglDirection;
+ LPDIENVELOPE lpEnvelope;
+ DWORD cbTypeSpecificParams;
+ LPVOID lpvTypeSpecificParams;
+} DIEFFECT_DX5, *LPDIEFFECT_DX5;
+typedef const DIEFFECT_DX5 *LPCDIEFFECT_DX5;
+
+typedef struct DIEFFECT {
+ DWORD dwSize;
+ DWORD dwFlags;
+ DWORD dwDuration;
+ DWORD dwSamplePeriod;
+ DWORD dwGain;
+ DWORD dwTriggerButton;
+ DWORD dwTriggerRepeatInterval;
+ DWORD cAxes;
+ LPDWORD rgdwAxes;
+ LPLONG rglDirection;
+ LPDIENVELOPE lpEnvelope;
+ DWORD cbTypeSpecificParams;
+ LPVOID lpvTypeSpecificParams;
+#if(DIRECTINPUT_VERSION >= 0x0600)
+ DWORD dwStartDelay;
+#endif /* DIRECTINPUT_VERSION >= 0x0600 */
+} DIEFFECT, *LPDIEFFECT;
+typedef const DIEFFECT *LPCDIEFFECT;
+typedef DIEFFECT DIEFFECT_DX6;
+typedef LPDIEFFECT LPDIEFFECT_DX6;
+
+typedef struct DIEFFECTINFOA {
+ DWORD dwSize;
+ GUID guid;
+ DWORD dwEffType;
+ DWORD dwStaticParams;
+ DWORD dwDynamicParams;
+ CHAR tszName[MAX_PATH];
+} DIEFFECTINFOA, *LPDIEFFECTINFOA;
+typedef const DIEFFECTINFOA *LPCDIEFFECTINFOA;
+
+typedef struct DIEFFECTINFOW {
+ DWORD dwSize;
+ GUID guid;
+ DWORD dwEffType;
+ DWORD dwStaticParams;
+ DWORD dwDynamicParams;
+ WCHAR tszName[MAX_PATH];
+} DIEFFECTINFOW, *LPDIEFFECTINFOW;
+typedef const DIEFFECTINFOW *LPCDIEFFECTINFOW;
+
+DECL_WINELIB_TYPE_AW(DIEFFECTINFO)
+DECL_WINELIB_TYPE_AW(LPDIEFFECTINFO)
+DECL_WINELIB_TYPE_AW(LPCDIEFFECTINFO)
+
+typedef BOOL (CALLBACK *LPDIENUMEFFECTSCALLBACKA)(LPCDIEFFECTINFOA, LPVOID);
+typedef BOOL (CALLBACK *LPDIENUMEFFECTSCALLBACKW)(LPCDIEFFECTINFOW, LPVOID);
+
+typedef struct DIEFFESCAPE {
+ DWORD dwSize;
+ DWORD dwCommand;
+ LPVOID lpvInBuffer;
+ DWORD cbInBuffer;
+ LPVOID lpvOutBuffer;
+ DWORD cbOutBuffer;
+} DIEFFESCAPE, *LPDIEFFESCAPE;
+
+typedef struct DIJOYSTATE {
+ LONG lX;
+ LONG lY;
+ LONG lZ;
+ LONG lRx;
+ LONG lRy;
+ LONG lRz;
+ LONG rglSlider[2];
+ DWORD rgdwPOV[4];
+ BYTE rgbButtons[32];
+} DIJOYSTATE, *LPDIJOYSTATE;
+
+typedef struct DIJOYSTATE2 {
+ LONG lX;
+ LONG lY;
+ LONG lZ;
+ LONG lRx;
+ LONG lRy;
+ LONG lRz;
+ LONG rglSlider[2];
+ DWORD rgdwPOV[4];
+ BYTE rgbButtons[128];
+ LONG lVX; /* 'v' as in velocity */
+ LONG lVY;
+ LONG lVZ;
+ LONG lVRx;
+ LONG lVRy;
+ LONG lVRz;
+ LONG rglVSlider[2];
+ LONG lAX; /* 'a' as in acceleration */
+ LONG lAY;
+ LONG lAZ;
+ LONG lARx;
+ LONG lARy;
+ LONG lARz;
+ LONG rglASlider[2];
+ LONG lFX; /* 'f' as in force */
+ LONG lFY;
+ LONG lFZ;
+ LONG lFRx; /* 'fr' as in rotational force aka torque */
+ LONG lFRy;
+ LONG lFRz;
+ LONG rglFSlider[2];
+} DIJOYSTATE2, *LPDIJOYSTATE2;
+
+#define DIJOFS_X FIELD_OFFSET(DIJOYSTATE, lX)
+#define DIJOFS_Y FIELD_OFFSET(DIJOYSTATE, lY)
+#define DIJOFS_Z FIELD_OFFSET(DIJOYSTATE, lZ)
+#define DIJOFS_RX FIELD_OFFSET(DIJOYSTATE, lRx)
+#define DIJOFS_RY FIELD_OFFSET(DIJOYSTATE, lRy)
+#define DIJOFS_RZ FIELD_OFFSET(DIJOYSTATE, lRz)
+#define DIJOFS_SLIDER(n) (FIELD_OFFSET(DIJOYSTATE, rglSlider) + \
+ (n) * sizeof(LONG))
+#define DIJOFS_POV(n) (FIELD_OFFSET(DIJOYSTATE, rgdwPOV) + \
+ (n) * sizeof(DWORD))
+#define DIJOFS_BUTTON(n) (FIELD_OFFSET(DIJOYSTATE, rgbButtons) + (n))
+#define DIJOFS_BUTTON0 DIJOFS_BUTTON(0)
+#define DIJOFS_BUTTON1 DIJOFS_BUTTON(1)
+#define DIJOFS_BUTTON2 DIJOFS_BUTTON(2)
+#define DIJOFS_BUTTON3 DIJOFS_BUTTON(3)
+#define DIJOFS_BUTTON4 DIJOFS_BUTTON(4)
+#define DIJOFS_BUTTON5 DIJOFS_BUTTON(5)
+#define DIJOFS_BUTTON6 DIJOFS_BUTTON(6)
+#define DIJOFS_BUTTON7 DIJOFS_BUTTON(7)
+#define DIJOFS_BUTTON8 DIJOFS_BUTTON(8)
+#define DIJOFS_BUTTON9 DIJOFS_BUTTON(9)
+#define DIJOFS_BUTTON10 DIJOFS_BUTTON(10)
+#define DIJOFS_BUTTON11 DIJOFS_BUTTON(11)
+#define DIJOFS_BUTTON12 DIJOFS_BUTTON(12)
+#define DIJOFS_BUTTON13 DIJOFS_BUTTON(13)
+#define DIJOFS_BUTTON14 DIJOFS_BUTTON(14)
+#define DIJOFS_BUTTON15 DIJOFS_BUTTON(15)
+#define DIJOFS_BUTTON16 DIJOFS_BUTTON(16)
+#define DIJOFS_BUTTON17 DIJOFS_BUTTON(17)
+#define DIJOFS_BUTTON18 DIJOFS_BUTTON(18)
+#define DIJOFS_BUTTON19 DIJOFS_BUTTON(19)
+#define DIJOFS_BUTTON20 DIJOFS_BUTTON(20)
+#define DIJOFS_BUTTON21 DIJOFS_BUTTON(21)
+#define DIJOFS_BUTTON22 DIJOFS_BUTTON(22)
+#define DIJOFS_BUTTON23 DIJOFS_BUTTON(23)
+#define DIJOFS_BUTTON24 DIJOFS_BUTTON(24)
+#define DIJOFS_BUTTON25 DIJOFS_BUTTON(25)
+#define DIJOFS_BUTTON26 DIJOFS_BUTTON(26)
+#define DIJOFS_BUTTON27 DIJOFS_BUTTON(27)
+#define DIJOFS_BUTTON28 DIJOFS_BUTTON(28)
+#define DIJOFS_BUTTON29 DIJOFS_BUTTON(29)
+#define DIJOFS_BUTTON30 DIJOFS_BUTTON(30)
+#define DIJOFS_BUTTON31 DIJOFS_BUTTON(31)
+#endif /* DIRECTINPUT_VERSION >= 0x0500 */
+
+/* DInput 7 structures, types */
+#if(DIRECTINPUT_VERSION >= 0x0700)
+typedef struct DIFILEEFFECT {
+ DWORD dwSize;
+ GUID GuidEffect;
+ LPCDIEFFECT lpDiEffect;
+ CHAR szFriendlyName[MAX_PATH];
+} DIFILEEFFECT, *LPDIFILEEFFECT;
+
+typedef const DIFILEEFFECT *LPCDIFILEEFFECT;
+typedef BOOL (CALLBACK *LPDIENUMEFFECTSINFILECALLBACK)(LPCDIFILEEFFECT , LPVOID);
+#endif /* DIRECTINPUT_VERSION >= 0x0700 */
+
+/* DInput 8 structures and types */
+#if DIRECTINPUT_VERSION >= 0x0800
+typedef struct _DIACTIONA {
+ UINT_PTR uAppData;
+ DWORD dwSemantic;
+ DWORD dwFlags;
+ __GNU_EXTENSION union {
+ LPCSTR lptszActionName;
+ UINT uResIdString;
+ } DUMMYUNIONNAME;
+ GUID guidInstance;
+ DWORD dwObjID;
+ DWORD dwHow;
+} DIACTIONA, *LPDIACTIONA;
+typedef const DIACTIONA *LPCDIACTIONA;
+
+typedef struct _DIACTIONW {
+ UINT_PTR uAppData;
+ DWORD dwSemantic;
+ DWORD dwFlags;
+ __GNU_EXTENSION union {
+ LPCWSTR lptszActionName;
+ UINT uResIdString;
+ } DUMMYUNIONNAME;
+ GUID guidInstance;
+ DWORD dwObjID;
+ DWORD dwHow;
+} DIACTIONW, *LPDIACTIONW;
+typedef const DIACTIONW *LPCDIACTIONW;
+
+DECL_WINELIB_TYPE_AW(DIACTION)
+DECL_WINELIB_TYPE_AW(LPDIACTION)
+DECL_WINELIB_TYPE_AW(LPCDIACTION)
+
+#define DIA_FORCEFEEDBACK 0x00000001
+#define DIA_APPMAPPED 0x00000002
+#define DIA_APPNOMAP 0x00000004
+#define DIA_NORANGE 0x00000008
+#define DIA_APPFIXED 0x00000010
+
+#define DIAH_UNMAPPED 0x00000000
+#define DIAH_USERCONFIG 0x00000001
+#define DIAH_APPREQUESTED 0x00000002
+#define DIAH_HWAPP 0x00000004
+#define DIAH_HWDEFAULT 0x00000008
+#define DIAH_DEFAULT 0x00000020
+#define DIAH_ERROR 0x80000000
+
+typedef struct _DIACTIONFORMATA {
+ DWORD dwSize;
+ DWORD dwActionSize;
+ DWORD dwDataSize;
+ DWORD dwNumActions;
+ LPDIACTIONA rgoAction;
+ GUID guidActionMap;
+ DWORD dwGenre;
+ DWORD dwBufferSize;
+ LONG lAxisMin;
+ LONG lAxisMax;
+ HINSTANCE hInstString;
+ FILETIME ftTimeStamp;
+ DWORD dwCRC;
+ CHAR tszActionMap[MAX_PATH];
+} DIACTIONFORMATA, *LPDIACTIONFORMATA;
+typedef const DIACTIONFORMATA *LPCDIACTIONFORMATA;
+
+typedef struct _DIACTIONFORMATW {
+ DWORD dwSize;
+ DWORD dwActionSize;
+ DWORD dwDataSize;
+ DWORD dwNumActions;
+ LPDIACTIONW rgoAction;
+ GUID guidActionMap;
+ DWORD dwGenre;
+ DWORD dwBufferSize;
+ LONG lAxisMin;
+ LONG lAxisMax;
+ HINSTANCE hInstString;
+ FILETIME ftTimeStamp;
+ DWORD dwCRC;
+ WCHAR tszActionMap[MAX_PATH];
+} DIACTIONFORMATW, *LPDIACTIONFORMATW;
+typedef const DIACTIONFORMATW *LPCDIACTIONFORMATW;
+
+DECL_WINELIB_TYPE_AW(DIACTIONFORMAT)
+DECL_WINELIB_TYPE_AW(LPDIACTIONFORMAT)
+DECL_WINELIB_TYPE_AW(LPCDIACTIONFORMAT)
+
+#define DIAFTS_NEWDEVICELOW 0xFFFFFFFF
+#define DIAFTS_NEWDEVICEHIGH 0xFFFFFFFF
+#define DIAFTS_UNUSEDDEVICELOW 0x00000000
+#define DIAFTS_UNUSEDDEVICEHIGH 0x00000000
+
+#define DIDBAM_DEFAULT 0x00000000
+#define DIDBAM_PRESERVE 0x00000001
+#define DIDBAM_INITIALIZE 0x00000002
+#define DIDBAM_HWDEFAULTS 0x00000004
+
+#define DIDSAM_DEFAULT 0x00000000
+#define DIDSAM_NOUSER 0x00000001
+#define DIDSAM_FORCESAVE 0x00000002
+
+#define DICD_DEFAULT 0x00000000
+#define DICD_EDIT 0x00000001
+
+#ifndef D3DCOLOR_DEFINED
+typedef DWORD D3DCOLOR;
+#define D3DCOLOR_DEFINED
+#endif
+
+typedef struct _DICOLORSET {
+ DWORD dwSize;
+ D3DCOLOR cTextFore;
+ D3DCOLOR cTextHighlight;
+ D3DCOLOR cCalloutLine;
+ D3DCOLOR cCalloutHighlight;
+ D3DCOLOR cBorder;
+ D3DCOLOR cControlFill;
+ D3DCOLOR cHighlightFill;
+ D3DCOLOR cAreaFill;
+} DICOLORSET, *LPDICOLORSET;
+typedef const DICOLORSET *LPCDICOLORSET;
+
+typedef struct _DICONFIGUREDEVICESPARAMSA {
+ DWORD dwSize;
+ DWORD dwcUsers;
+ LPSTR lptszUserNames;
+ DWORD dwcFormats;
+ LPDIACTIONFORMATA lprgFormats;
+ HWND hwnd;
+ DICOLORSET dics;
+ LPUNKNOWN lpUnkDDSTarget;
+} DICONFIGUREDEVICESPARAMSA, *LPDICONFIGUREDEVICESPARAMSA;
+typedef const DICONFIGUREDEVICESPARAMSA *LPCDICONFIGUREDEVICESPARAMSA;
+
+typedef struct _DICONFIGUREDEVICESPARAMSW {
+ DWORD dwSize;
+ DWORD dwcUsers;
+ LPWSTR lptszUserNames;
+ DWORD dwcFormats;
+ LPDIACTIONFORMATW lprgFormats;
+ HWND hwnd;
+ DICOLORSET dics;
+ LPUNKNOWN lpUnkDDSTarget;
+} DICONFIGUREDEVICESPARAMSW, *LPDICONFIGUREDEVICESPARAMSW;
+typedef const DICONFIGUREDEVICESPARAMSW *LPCDICONFIGUREDEVICESPARAMSW;
+
+DECL_WINELIB_TYPE_AW(DICONFIGUREDEVICESPARAMS)
+DECL_WINELIB_TYPE_AW(LPDICONFIGUREDEVICESPARAMS)
+DECL_WINELIB_TYPE_AW(LPCDICONFIGUREDEVICESPARAMS)
+
+#define DIDIFT_CONFIGURATION 0x00000001
+#define DIDIFT_OVERLAY 0x00000002
+
+#define DIDAL_CENTERED 0x00000000
+#define DIDAL_LEFTALIGNED 0x00000001
+#define DIDAL_RIGHTALIGNED 0x00000002
+#define DIDAL_MIDDLE 0x00000000
+#define DIDAL_TOPALIGNED 0x00000004
+#define DIDAL_BOTTOMALIGNED 0x00000008
+
+typedef struct _DIDEVICEIMAGEINFOA {
+ CHAR tszImagePath[MAX_PATH];
+ DWORD dwFlags;
+ DWORD dwViewID;
+ RECT rcOverlay;
+ DWORD dwObjID;
+ DWORD dwcValidPts;
+ POINT rgptCalloutLine[5];
+ RECT rcCalloutRect;
+ DWORD dwTextAlign;
+} DIDEVICEIMAGEINFOA, *LPDIDEVICEIMAGEINFOA;
+typedef const DIDEVICEIMAGEINFOA *LPCDIDEVICEIMAGEINFOA;
+
+typedef struct _DIDEVICEIMAGEINFOW {
+ WCHAR tszImagePath[MAX_PATH];
+ DWORD dwFlags;
+ DWORD dwViewID;
+ RECT rcOverlay;
+ DWORD dwObjID;
+ DWORD dwcValidPts;
+ POINT rgptCalloutLine[5];
+ RECT rcCalloutRect;
+ DWORD dwTextAlign;
+} DIDEVICEIMAGEINFOW, *LPDIDEVICEIMAGEINFOW;
+typedef const DIDEVICEIMAGEINFOW *LPCDIDEVICEIMAGEINFOW;
+
+DECL_WINELIB_TYPE_AW(DIDEVICEIMAGEINFO)
+DECL_WINELIB_TYPE_AW(LPDIDEVICEIMAGEINFO)
+DECL_WINELIB_TYPE_AW(LPCDIDEVICEIMAGEINFO)
+
+typedef struct _DIDEVICEIMAGEINFOHEADERA {
+ DWORD dwSize;
+ DWORD dwSizeImageInfo;
+ DWORD dwcViews;
+ DWORD dwcButtons;
+ DWORD dwcAxes;
+ DWORD dwcPOVs;
+ DWORD dwBufferSize;
+ DWORD dwBufferUsed;
+ LPDIDEVICEIMAGEINFOA lprgImageInfoArray;
+} DIDEVICEIMAGEINFOHEADERA, *LPDIDEVICEIMAGEINFOHEADERA;
+typedef const DIDEVICEIMAGEINFOHEADERA *LPCDIDEVICEIMAGEINFOHEADERA;
+
+typedef struct _DIDEVICEIMAGEINFOHEADERW {
+ DWORD dwSize;
+ DWORD dwSizeImageInfo;
+ DWORD dwcViews;
+ DWORD dwcButtons;
+ DWORD dwcAxes;
+ DWORD dwcPOVs;
+ DWORD dwBufferSize;
+ DWORD dwBufferUsed;
+ LPDIDEVICEIMAGEINFOW lprgImageInfoArray;
+} DIDEVICEIMAGEINFOHEADERW, *LPDIDEVICEIMAGEINFOHEADERW;
+typedef const DIDEVICEIMAGEINFOHEADERW *LPCDIDEVICEIMAGEINFOHEADERW;
+
+DECL_WINELIB_TYPE_AW(DIDEVICEIMAGEINFOHEADER)
+DECL_WINELIB_TYPE_AW(LPDIDEVICEIMAGEINFOHEADER)
+DECL_WINELIB_TYPE_AW(LPCDIDEVICEIMAGEINFOHEADER)
+
+#endif /* DI8 */
+
+
+/*****************************************************************************
+ * IDirectInputEffect interface
+ */
+#if (DIRECTINPUT_VERSION >= 0x0500)
+#undef INTERFACE
+#define INTERFACE IDirectInputEffect
+DECLARE_INTERFACE_(IDirectInputEffect,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectInputEffect methods ***/
+ STDMETHOD(Initialize)(THIS_ HINSTANCE, DWORD, REFGUID) PURE;
+ STDMETHOD(GetEffectGuid)(THIS_ LPGUID) PURE;
+ STDMETHOD(GetParameters)(THIS_ LPDIEFFECT, DWORD) PURE;
+ STDMETHOD(SetParameters)(THIS_ LPCDIEFFECT, DWORD) PURE;
+ STDMETHOD(Start)(THIS_ DWORD, DWORD) PURE;
+ STDMETHOD(Stop)(THIS) PURE;
+ STDMETHOD(GetEffectStatus)(THIS_ LPDWORD) PURE;
+ STDMETHOD(Download)(THIS) PURE;
+ STDMETHOD(Unload)(THIS) PURE;
+ STDMETHOD(Escape)(THIS_ LPDIEFFESCAPE) PURE;
+};
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectInputEffect_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectInputEffect_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirectInputEffect_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirectInputEffect methods ***/
+#define IDirectInputEffect_Initialize(p,a,b,c) (p)->lpVtbl->Initialize(p,a,b,c)
+#define IDirectInputEffect_GetEffectGuid(p,a) (p)->lpVtbl->GetEffectGuid(p,a)
+#define IDirectInputEffect_GetParameters(p,a,b) (p)->lpVtbl->GetParameters(p,a,b)
+#define IDirectInputEffect_SetParameters(p,a,b) (p)->lpVtbl->SetParameters(p,a,b)
+#define IDirectInputEffect_Start(p,a,b) (p)->lpVtbl->Start(p,a,b)
+#define IDirectInputEffect_Stop(p) (p)->lpVtbl->Stop(p)
+#define IDirectInputEffect_GetEffectStatus(p,a) (p)->lpVtbl->GetEffectStatus(p,a)
+#define IDirectInputEffect_Download(p) (p)->lpVtbl->Download(p)
+#define IDirectInputEffect_Unload(p) (p)->lpVtbl->Unload(p)
+#define IDirectInputEffect_Escape(p,a) (p)->lpVtbl->Escape(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirectInputEffect_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectInputEffect_AddRef(p) (p)->AddRef()
+#define IDirectInputEffect_Release(p) (p)->Release()
+/*** IDirectInputEffect methods ***/
+#define IDirectInputEffect_Initialize(p,a,b,c) (p)->Initialize(a,b,c)
+#define IDirectInputEffect_GetEffectGuid(p,a) (p)->GetEffectGuid(a)
+#define IDirectInputEffect_GetParameters(p,a,b) (p)->GetParameters(a,b)
+#define IDirectInputEffect_SetParameters(p,a,b) (p)->SetParameters(a,b)
+#define IDirectInputEffect_Start(p,a,b) (p)->Start(a,b)
+#define IDirectInputEffect_Stop(p) (p)->Stop()
+#define IDirectInputEffect_GetEffectStatus(p,a) (p)->GetEffectStatus(a)
+#define IDirectInputEffect_Download(p) (p)->Download()
+#define IDirectInputEffect_Unload(p) (p)->Unload()
+#define IDirectInputEffect_Escape(p,a) (p)->Escape(a)
+#endif
+
+#endif /* DI5 */
+
+
+/*****************************************************************************
+ * IDirectInputDeviceA interface
+ */
+#undef INTERFACE
+#define INTERFACE IDirectInputDeviceA
+DECLARE_INTERFACE_(IDirectInputDeviceA,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectInputDeviceA methods ***/
+ STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS lpDIDevCaps) PURE;
+ STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(GetProperty)(THIS_ REFGUID rguidProp, LPDIPROPHEADER pdiph) PURE;
+ STDMETHOD(SetProperty)(THIS_ REFGUID rguidProp, LPCDIPROPHEADER pdiph) PURE;
+ STDMETHOD(Acquire)(THIS) PURE;
+ STDMETHOD(Unacquire)(THIS) PURE;
+ STDMETHOD(GetDeviceState)(THIS_ DWORD cbData, LPVOID lpvData) PURE;
+ STDMETHOD(GetDeviceData)(THIS_ DWORD cbObjectData, LPDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD dwFlags) PURE;
+ STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT lpdf) PURE;
+ STDMETHOD(SetEventNotification)(THIS_ HANDLE hEvent) PURE;
+ STDMETHOD(SetCooperativeLevel)(THIS_ HWND hwnd, DWORD dwFlags) PURE;
+ STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEA pdidoi, DWORD dwObj, DWORD dwHow) PURE;
+ STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEA pdidi) PURE;
+ STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE;
+ STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion, REFGUID rguid) PURE;
+};
+
+/*****************************************************************************
+ * IDirectInputDeviceW interface
+ */
+#undef INTERFACE
+#define INTERFACE IDirectInputDeviceW
+DECLARE_INTERFACE_(IDirectInputDeviceW,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectInputDeviceW methods ***/
+ STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS lpDIDevCaps) PURE;
+ STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKW lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(GetProperty)(THIS_ REFGUID rguidProp, LPDIPROPHEADER pdiph) PURE;
+ STDMETHOD(SetProperty)(THIS_ REFGUID rguidProp, LPCDIPROPHEADER pdiph) PURE;
+ STDMETHOD(Acquire)(THIS) PURE;
+ STDMETHOD(Unacquire)(THIS) PURE;
+ STDMETHOD(GetDeviceState)(THIS_ DWORD cbData, LPVOID lpvData) PURE;
+ STDMETHOD(GetDeviceData)(THIS_ DWORD cbObjectData, LPDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD dwFlags) PURE;
+ STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT lpdf) PURE;
+ STDMETHOD(SetEventNotification)(THIS_ HANDLE hEvent) PURE;
+ STDMETHOD(SetCooperativeLevel)(THIS_ HWND hwnd, DWORD dwFlags) PURE;
+ STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEW pdidoi, DWORD dwObj, DWORD dwHow) PURE;
+ STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEW pdidi) PURE;
+ STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE;
+ STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion, REFGUID rguid) PURE;
+};
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectInputDevice_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectInputDevice_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirectInputDevice_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirectInputDevice methods ***/
+#define IDirectInputDevice_GetCapabilities(p,a) (p)->lpVtbl->GetCapabilities(p,a)
+#define IDirectInputDevice_EnumObjects(p,a,b,c) (p)->lpVtbl->EnumObjects(p,a,b,c)
+#define IDirectInputDevice_GetProperty(p,a,b) (p)->lpVtbl->GetProperty(p,a,b)
+#define IDirectInputDevice_SetProperty(p,a,b) (p)->lpVtbl->SetProperty(p,a,b)
+#define IDirectInputDevice_Acquire(p) (p)->lpVtbl->Acquire(p)
+#define IDirectInputDevice_Unacquire(p) (p)->lpVtbl->Unacquire(p)
+#define IDirectInputDevice_GetDeviceState(p,a,b) (p)->lpVtbl->GetDeviceState(p,a,b)
+#define IDirectInputDevice_GetDeviceData(p,a,b,c,d) (p)->lpVtbl->GetDeviceData(p,a,b,c,d)
+#define IDirectInputDevice_SetDataFormat(p,a) (p)->lpVtbl->SetDataFormat(p,a)
+#define IDirectInputDevice_SetEventNotification(p,a) (p)->lpVtbl->SetEventNotification(p,a)
+#define IDirectInputDevice_SetCooperativeLevel(p,a,b) (p)->lpVtbl->SetCooperativeLevel(p,a,b)
+#define IDirectInputDevice_GetObjectInfo(p,a,b,c) (p)->lpVtbl->GetObjectInfo(p,a,b,c)
+#define IDirectInputDevice_GetDeviceInfo(p,a) (p)->lpVtbl->GetDeviceInfo(p,a)
+#define IDirectInputDevice_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b)
+#define IDirectInputDevice_Initialize(p,a,b,c) (p)->lpVtbl->Initialize(p,a,b,c)
+#else
+/*** IUnknown methods ***/
+#define IDirectInputDevice_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectInputDevice_AddRef(p) (p)->AddRef()
+#define IDirectInputDevice_Release(p) (p)->Release()
+/*** IDirectInputDevice methods ***/
+#define IDirectInputDevice_GetCapabilities(p,a) (p)->GetCapabilities(a)
+#define IDirectInputDevice_EnumObjects(p,a,b,c) (p)->EnumObjects(a,b,c)
+#define IDirectInputDevice_GetProperty(p,a,b) (p)->GetProperty(a,b)
+#define IDirectInputDevice_SetProperty(p,a,b) (p)->SetProperty(a,b)
+#define IDirectInputDevice_Acquire(p) (p)->Acquire()
+#define IDirectInputDevice_Unacquire(p) (p)->Unacquire()
+#define IDirectInputDevice_GetDeviceState(p,a,b) (p)->GetDeviceState(a,b)
+#define IDirectInputDevice_GetDeviceData(p,a,b,c,d) (p)->GetDeviceData(a,b,c,d)
+#define IDirectInputDevice_SetDataFormat(p,a) (p)->SetDataFormat(a)
+#define IDirectInputDevice_SetEventNotification(p,a) (p)->SetEventNotification(a)
+#define IDirectInputDevice_SetCooperativeLevel(p,a,b) (p)->SetCooperativeLevel(a,b)
+#define IDirectInputDevice_GetObjectInfo(p,a,b,c) (p)->GetObjectInfo(a,b,c)
+#define IDirectInputDevice_GetDeviceInfo(p,a) (p)->GetDeviceInfo(a)
+#define IDirectInputDevice_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b)
+#define IDirectInputDevice_Initialize(p,a,b,c) (p)->Initialize(a,b,c)
+#endif
+
+
+#if (DIRECTINPUT_VERSION >= 0x0500)
+/*****************************************************************************
+ * IDirectInputDevice2A interface
+ */
+#undef INTERFACE
+#define INTERFACE IDirectInputDevice2A
+DECLARE_INTERFACE_(IDirectInputDevice2A,IDirectInputDeviceA)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectInputDeviceA methods ***/
+ STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS lpDIDevCaps) PURE;
+ STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(GetProperty)(THIS_ REFGUID rguidProp, LPDIPROPHEADER pdiph) PURE;
+ STDMETHOD(SetProperty)(THIS_ REFGUID rguidProp, LPCDIPROPHEADER pdiph) PURE;
+ STDMETHOD(Acquire)(THIS) PURE;
+ STDMETHOD(Unacquire)(THIS) PURE;
+ STDMETHOD(GetDeviceState)(THIS_ DWORD cbData, LPVOID lpvData) PURE;
+ STDMETHOD(GetDeviceData)(THIS_ DWORD cbObjectData, LPDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD dwFlags) PURE;
+ STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT lpdf) PURE;
+ STDMETHOD(SetEventNotification)(THIS_ HANDLE hEvent) PURE;
+ STDMETHOD(SetCooperativeLevel)(THIS_ HWND hwnd, DWORD dwFlags) PURE;
+ STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEA pdidoi, DWORD dwObj, DWORD dwHow) PURE;
+ STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEA pdidi) PURE;
+ STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE;
+ STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion, REFGUID rguid) PURE;
+ /*** IDirectInputDevice2A methods ***/
+ STDMETHOD(CreateEffect)(THIS_ REFGUID rguid, LPCDIEFFECT lpeff, LPDIRECTINPUTEFFECT *ppdeff, LPUNKNOWN punkOuter) PURE;
+ STDMETHOD(EnumEffects)(THIS_ LPDIENUMEFFECTSCALLBACKA lpCallback, LPVOID pvRef, DWORD dwEffType) PURE;
+ STDMETHOD(GetEffectInfo)(THIS_ LPDIEFFECTINFOA pdei, REFGUID rguid) PURE;
+ STDMETHOD(GetForceFeedbackState)(THIS_ LPDWORD pdwOut) PURE;
+ STDMETHOD(SendForceFeedbackCommand)(THIS_ DWORD dwFlags) PURE;
+ STDMETHOD(EnumCreatedEffectObjects)(THIS_ LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback, LPVOID pvRef, DWORD fl) PURE;
+ STDMETHOD(Escape)(THIS_ LPDIEFFESCAPE pesc) PURE;
+ STDMETHOD(Poll)(THIS) PURE;
+ STDMETHOD(SendDeviceData)(THIS_ DWORD cbObjectData, LPCDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD fl) PURE;
+};
+
+/*****************************************************************************
+ * IDirectInputDevice2W interface
+ */
+#undef INTERFACE
+#define INTERFACE IDirectInputDevice2W
+DECLARE_INTERFACE_(IDirectInputDevice2W,IDirectInputDeviceW)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectInputDeviceW methods ***/
+ STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS lpDIDevCaps) PURE;
+ STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKW lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(GetProperty)(THIS_ REFGUID rguidProp, LPDIPROPHEADER pdiph) PURE;
+ STDMETHOD(SetProperty)(THIS_ REFGUID rguidProp, LPCDIPROPHEADER pdiph) PURE;
+ STDMETHOD(Acquire)(THIS) PURE;
+ STDMETHOD(Unacquire)(THIS) PURE;
+ STDMETHOD(GetDeviceState)(THIS_ DWORD cbData, LPVOID lpvData) PURE;
+ STDMETHOD(GetDeviceData)(THIS_ DWORD cbObjectData, LPDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD dwFlags) PURE;
+ STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT lpdf) PURE;
+ STDMETHOD(SetEventNotification)(THIS_ HANDLE hEvent) PURE;
+ STDMETHOD(SetCooperativeLevel)(THIS_ HWND hwnd, DWORD dwFlags) PURE;
+ STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEW pdidoi, DWORD dwObj, DWORD dwHow) PURE;
+ STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEW pdidi) PURE;
+ STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE;
+ STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion, REFGUID rguid) PURE;
+ /*** IDirectInputDevice2W methods ***/
+ STDMETHOD(CreateEffect)(THIS_ REFGUID rguid, LPCDIEFFECT lpeff, LPDIRECTINPUTEFFECT *ppdeff, LPUNKNOWN punkOuter) PURE;
+ STDMETHOD(EnumEffects)(THIS_ LPDIENUMEFFECTSCALLBACKW lpCallback, LPVOID pvRef, DWORD dwEffType) PURE;
+ STDMETHOD(GetEffectInfo)(THIS_ LPDIEFFECTINFOW pdei, REFGUID rguid) PURE;
+ STDMETHOD(GetForceFeedbackState)(THIS_ LPDWORD pdwOut) PURE;
+ STDMETHOD(SendForceFeedbackCommand)(THIS_ DWORD dwFlags) PURE;
+ STDMETHOD(EnumCreatedEffectObjects)(THIS_ LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback, LPVOID pvRef, DWORD fl) PURE;
+ STDMETHOD(Escape)(THIS_ LPDIEFFESCAPE pesc) PURE;
+ STDMETHOD(Poll)(THIS) PURE;
+ STDMETHOD(SendDeviceData)(THIS_ DWORD cbObjectData, LPCDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD fl) PURE;
+};
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectInputDevice2_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectInputDevice2_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirectInputDevice2_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirectInputDevice methods ***/
+#define IDirectInputDevice2_GetCapabilities(p,a) (p)->lpVtbl->GetCapabilities(p,a)
+#define IDirectInputDevice2_EnumObjects(p,a,b,c) (p)->lpVtbl->EnumObjects(p,a,b,c)
+#define IDirectInputDevice2_GetProperty(p,a,b) (p)->lpVtbl->GetProperty(p,a,b)
+#define IDirectInputDevice2_SetProperty(p,a,b) (p)->lpVtbl->SetProperty(p,a,b)
+#define IDirectInputDevice2_Acquire(p) (p)->lpVtbl->Acquire(p)
+#define IDirectInputDevice2_Unacquire(p) (p)->lpVtbl->Unacquire(p)
+#define IDirectInputDevice2_GetDeviceState(p,a,b) (p)->lpVtbl->GetDeviceState(p,a,b)
+#define IDirectInputDevice2_GetDeviceData(p,a,b,c,d) (p)->lpVtbl->GetDeviceData(p,a,b,c,d)
+#define IDirectInputDevice2_SetDataFormat(p,a) (p)->lpVtbl->SetDataFormat(p,a)
+#define IDirectInputDevice2_SetEventNotification(p,a) (p)->lpVtbl->SetEventNotification(p,a)
+#define IDirectInputDevice2_SetCooperativeLevel(p,a,b) (p)->lpVtbl->SetCooperativeLevel(p,a,b)
+#define IDirectInputDevice2_GetObjectInfo(p,a,b,c) (p)->lpVtbl->GetObjectInfo(p,a,b,c)
+#define IDirectInputDevice2_GetDeviceInfo(p,a) (p)->lpVtbl->GetDeviceInfo(p,a)
+#define IDirectInputDevice2_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b)
+#define IDirectInputDevice2_Initialize(p,a,b,c) (p)->lpVtbl->Initialize(p,a,b,c)
+/*** IDirectInputDevice2 methods ***/
+#define IDirectInputDevice2_CreateEffect(p,a,b,c,d) (p)->lpVtbl->CreateEffect(p,a,b,c,d)
+#define IDirectInputDevice2_EnumEffects(p,a,b,c) (p)->lpVtbl->EnumEffects(p,a,b,c)
+#define IDirectInputDevice2_GetEffectInfo(p,a,b) (p)->lpVtbl->GetEffectInfo(p,a,b)
+#define IDirectInputDevice2_GetForceFeedbackState(p,a) (p)->lpVtbl->GetForceFeedbackState(p,a)
+#define IDirectInputDevice2_SendForceFeedbackCommand(p,a) (p)->lpVtbl->SendForceFeedbackCommand(p,a)
+#define IDirectInputDevice2_EnumCreatedEffectObjects(p,a,b,c) (p)->lpVtbl->EnumCreatedEffectObjects(p,a,b,c)
+#define IDirectInputDevice2_Escape(p,a) (p)->lpVtbl->Escape(p,a)
+#define IDirectInputDevice2_Poll(p) (p)->lpVtbl->Poll(p)
+#define IDirectInputDevice2_SendDeviceData(p,a,b,c,d) (p)->lpVtbl->SendDeviceData(p,a,b,c,d)
+#else
+/*** IUnknown methods ***/
+#define IDirectInputDevice2_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectInputDevice2_AddRef(p) (p)->AddRef()
+#define IDirectInputDevice2_Release(p) (p)->Release()
+/*** IDirectInputDevice methods ***/
+#define IDirectInputDevice2_GetCapabilities(p,a) (p)->GetCapabilities(a)
+#define IDirectInputDevice2_EnumObjects(p,a,b,c) (p)->EnumObjects(a,b,c)
+#define IDirectInputDevice2_GetProperty(p,a,b) (p)->GetProperty(a,b)
+#define IDirectInputDevice2_SetProperty(p,a,b) (p)->SetProperty(a,b)
+#define IDirectInputDevice2_Acquire(p) (p)->Acquire()
+#define IDirectInputDevice2_Unacquire(p) (p)->Unacquire()
+#define IDirectInputDevice2_GetDeviceState(p,a,b) (p)->GetDeviceState(a,b)
+#define IDirectInputDevice2_GetDeviceData(p,a,b,c,d) (p)->GetDeviceData(a,b,c,d)
+#define IDirectInputDevice2_SetDataFormat(p,a) (p)->SetDataFormat(a)
+#define IDirectInputDevice2_SetEventNotification(p,a) (p)->SetEventNotification(a)
+#define IDirectInputDevice2_SetCooperativeLevel(p,a,b) (p)->SetCooperativeLevel(a,b)
+#define IDirectInputDevice2_GetObjectInfo(p,a,b,c) (p)->GetObjectInfo(a,b,c)
+#define IDirectInputDevice2_GetDeviceInfo(p,a) (p)->GetDeviceInfo(a)
+#define IDirectInputDevice2_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b)
+#define IDirectInputDevice2_Initialize(p,a,b,c) (p)->Initialize(a,b,c)
+/*** IDirectInputDevice2 methods ***/
+#define IDirectInputDevice2_CreateEffect(p,a,b,c,d) (p)->CreateEffect(a,b,c,d)
+#define IDirectInputDevice2_EnumEffects(p,a,b,c) (p)->EnumEffects(a,b,c)
+#define IDirectInputDevice2_GetEffectInfo(p,a,b) (p)->GetEffectInfo(a,b)
+#define IDirectInputDevice2_GetForceFeedbackState(p,a) (p)->GetForceFeedbackState(a)
+#define IDirectInputDevice2_SendForceFeedbackCommand(p,a) (p)->SendForceFeedbackCommand(a)
+#define IDirectInputDevice2_EnumCreatedEffectObjects(p,a,b,c) (p)->EnumCreatedEffectObjects(a,b,c)
+#define IDirectInputDevice2_Escape(p,a) (p)->Escape(a)
+#define IDirectInputDevice2_Poll(p) (p)->Poll()
+#define IDirectInputDevice2_SendDeviceData(p,a,b,c,d) (p)->SendDeviceData(a,b,c,d)
+#endif
+#endif /* DI5 */
+
+#if DIRECTINPUT_VERSION >= 0x0700
+/*****************************************************************************
+ * IDirectInputDevice7A interface
+ */
+#undef INTERFACE
+#define INTERFACE IDirectInputDevice7A
+DECLARE_INTERFACE_(IDirectInputDevice7A,IDirectInputDevice2A)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectInputDeviceA methods ***/
+ STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS lpDIDevCaps) PURE;
+ STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(GetProperty)(THIS_ REFGUID rguidProp, LPDIPROPHEADER pdiph) PURE;
+ STDMETHOD(SetProperty)(THIS_ REFGUID rguidProp, LPCDIPROPHEADER pdiph) PURE;
+ STDMETHOD(Acquire)(THIS) PURE;
+ STDMETHOD(Unacquire)(THIS) PURE;
+ STDMETHOD(GetDeviceState)(THIS_ DWORD cbData, LPVOID lpvData) PURE;
+ STDMETHOD(GetDeviceData)(THIS_ DWORD cbObjectData, LPDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD dwFlags) PURE;
+ STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT lpdf) PURE;
+ STDMETHOD(SetEventNotification)(THIS_ HANDLE hEvent) PURE;
+ STDMETHOD(SetCooperativeLevel)(THIS_ HWND hwnd, DWORD dwFlags) PURE;
+ STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEA pdidoi, DWORD dwObj, DWORD dwHow) PURE;
+ STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEA pdidi) PURE;
+ STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE;
+ STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion, REFGUID rguid) PURE;
+ /*** IDirectInputDevice2A methods ***/
+ STDMETHOD(CreateEffect)(THIS_ REFGUID rguid, LPCDIEFFECT lpeff, LPDIRECTINPUTEFFECT *ppdeff, LPUNKNOWN punkOuter) PURE;
+ STDMETHOD(EnumEffects)(THIS_ LPDIENUMEFFECTSCALLBACKA lpCallback, LPVOID pvRef, DWORD dwEffType) PURE;
+ STDMETHOD(GetEffectInfo)(THIS_ LPDIEFFECTINFOA pdei, REFGUID rguid) PURE;
+ STDMETHOD(GetForceFeedbackState)(THIS_ LPDWORD pdwOut) PURE;
+ STDMETHOD(SendForceFeedbackCommand)(THIS_ DWORD dwFlags) PURE;
+ STDMETHOD(EnumCreatedEffectObjects)(THIS_ LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback, LPVOID pvRef, DWORD fl) PURE;
+ STDMETHOD(Escape)(THIS_ LPDIEFFESCAPE pesc) PURE;
+ STDMETHOD(Poll)(THIS) PURE;
+ STDMETHOD(SendDeviceData)(THIS_ DWORD cbObjectData, LPCDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD fl) PURE;
+ /*** IDirectInputDevice7A methods ***/
+ STDMETHOD(EnumEffectsInFile)(THIS_ LPCSTR lpszFileName,LPDIENUMEFFECTSINFILECALLBACK pec,LPVOID pvRef,DWORD dwFlags) PURE;
+ STDMETHOD(WriteEffectToFile)(THIS_ LPCSTR lpszFileName,DWORD dwEntries,LPDIFILEEFFECT rgDiFileEft,DWORD dwFlags) PURE;
+};
+
+/*****************************************************************************
+ * IDirectInputDevice7W interface
+ */
+#undef INTERFACE
+#define INTERFACE IDirectInputDevice7W
+DECLARE_INTERFACE_(IDirectInputDevice7W,IDirectInputDevice2W)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectInputDeviceW methods ***/
+ STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS lpDIDevCaps) PURE;
+ STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKW lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(GetProperty)(THIS_ REFGUID rguidProp, LPDIPROPHEADER pdiph) PURE;
+ STDMETHOD(SetProperty)(THIS_ REFGUID rguidProp, LPCDIPROPHEADER pdiph) PURE;
+ STDMETHOD(Acquire)(THIS) PURE;
+ STDMETHOD(Unacquire)(THIS) PURE;
+ STDMETHOD(GetDeviceState)(THIS_ DWORD cbData, LPVOID lpvData) PURE;
+ STDMETHOD(GetDeviceData)(THIS_ DWORD cbObjectData, LPDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD dwFlags) PURE;
+ STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT lpdf) PURE;
+ STDMETHOD(SetEventNotification)(THIS_ HANDLE hEvent) PURE;
+ STDMETHOD(SetCooperativeLevel)(THIS_ HWND hwnd, DWORD dwFlags) PURE;
+ STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEW pdidoi, DWORD dwObj, DWORD dwHow) PURE;
+ STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEW pdidi) PURE;
+ STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE;
+ STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion, REFGUID rguid) PURE;
+ /*** IDirectInputDevice2W methods ***/
+ STDMETHOD(CreateEffect)(THIS_ REFGUID rguid, LPCDIEFFECT lpeff, LPDIRECTINPUTEFFECT *ppdeff, LPUNKNOWN punkOuter) PURE;
+ STDMETHOD(EnumEffects)(THIS_ LPDIENUMEFFECTSCALLBACKW lpCallback, LPVOID pvRef, DWORD dwEffType) PURE;
+ STDMETHOD(GetEffectInfo)(THIS_ LPDIEFFECTINFOW pdei, REFGUID rguid) PURE;
+ STDMETHOD(GetForceFeedbackState)(THIS_ LPDWORD pdwOut) PURE;
+ STDMETHOD(SendForceFeedbackCommand)(THIS_ DWORD dwFlags) PURE;
+ STDMETHOD(EnumCreatedEffectObjects)(THIS_ LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback, LPVOID pvRef, DWORD fl) PURE;
+ STDMETHOD(Escape)(THIS_ LPDIEFFESCAPE pesc) PURE;
+ STDMETHOD(Poll)(THIS) PURE;
+ STDMETHOD(SendDeviceData)(THIS_ DWORD cbObjectData, LPCDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD fl) PURE;
+ /*** IDirectInputDevice7W methods ***/
+ STDMETHOD(EnumEffectsInFile)(THIS_ LPCWSTR lpszFileName,LPDIENUMEFFECTSINFILECALLBACK pec,LPVOID pvRef,DWORD dwFlags) PURE;
+ STDMETHOD(WriteEffectToFile)(THIS_ LPCWSTR lpszFileName,DWORD dwEntries,LPDIFILEEFFECT rgDiFileEft,DWORD dwFlags) PURE;
+};
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectInputDevice7_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectInputDevice7_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirectInputDevice7_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirectInputDevice methods ***/
+#define IDirectInputDevice7_GetCapabilities(p,a) (p)->lpVtbl->GetCapabilities(p,a)
+#define IDirectInputDevice7_EnumObjects(p,a,b,c) (p)->lpVtbl->EnumObjects(p,a,b,c)
+#define IDirectInputDevice7_GetProperty(p,a,b) (p)->lpVtbl->GetProperty(p,a,b)
+#define IDirectInputDevice7_SetProperty(p,a,b) (p)->lpVtbl->SetProperty(p,a,b)
+#define IDirectInputDevice7_Acquire(p) (p)->lpVtbl->Acquire(p)
+#define IDirectInputDevice7_Unacquire(p) (p)->lpVtbl->Unacquire(p)
+#define IDirectInputDevice7_GetDeviceState(p,a,b) (p)->lpVtbl->GetDeviceState(p,a,b)
+#define IDirectInputDevice7_GetDeviceData(p,a,b,c,d) (p)->lpVtbl->GetDeviceData(p,a,b,c,d)
+#define IDirectInputDevice7_SetDataFormat(p,a) (p)->lpVtbl->SetDataFormat(p,a)
+#define IDirectInputDevice7_SetEventNotification(p,a) (p)->lpVtbl->SetEventNotification(p,a)
+#define IDirectInputDevice7_SetCooperativeLevel(p,a,b) (p)->lpVtbl->SetCooperativeLevel(p,a,b)
+#define IDirectInputDevice7_GetObjectInfo(p,a,b,c) (p)->lpVtbl->GetObjectInfo(p,a,b,c)
+#define IDirectInputDevice7_GetDeviceInfo(p,a) (p)->lpVtbl->GetDeviceInfo(p,a)
+#define IDirectInputDevice7_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b)
+#define IDirectInputDevice7_Initialize(p,a,b,c) (p)->lpVtbl->Initialize(p,a,b,c)
+/*** IDirectInputDevice2 methods ***/
+#define IDirectInputDevice7_CreateEffect(p,a,b,c,d) (p)->lpVtbl->CreateEffect(p,a,b,c,d)
+#define IDirectInputDevice7_EnumEffects(p,a,b,c) (p)->lpVtbl->EnumEffects(p,a,b,c)
+#define IDirectInputDevice7_GetEffectInfo(p,a,b) (p)->lpVtbl->GetEffectInfo(p,a,b)
+#define IDirectInputDevice7_GetForceFeedbackState(p,a) (p)->lpVtbl->GetForceFeedbackState(p,a)
+#define IDirectInputDevice7_SendForceFeedbackCommand(p,a) (p)->lpVtbl->SendForceFeedbackCommand(p,a)
+#define IDirectInputDevice7_EnumCreatedEffectObjects(p,a,b,c) (p)->lpVtbl->EnumCreatedEffectObjects(p,a,b,c)
+#define IDirectInputDevice7_Escape(p,a) (p)->lpVtbl->Escape(p,a)
+#define IDirectInputDevice7_Poll(p) (p)->lpVtbl->Poll(p)
+#define IDirectInputDevice7_SendDeviceData(p,a,b,c,d) (p)->lpVtbl->SendDeviceData(p,a,b,c,d)
+/*** IDirectInputDevice7 methods ***/
+#define IDirectInputDevice7_EnumEffectsInFile(p,a,b,c,d) (p)->lpVtbl->EnumEffectsInFile(p,a,b,c,d)
+#define IDirectInputDevice7_WriteEffectToFile(p,a,b,c,d) (p)->lpVtbl->WriteEffectToFile(p,a,b,c,d)
+#else
+/*** IUnknown methods ***/
+#define IDirectInputDevice7_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectInputDevice7_AddRef(p) (p)->AddRef()
+#define IDirectInputDevice7_Release(p) (p)->Release()
+/*** IDirectInputDevice methods ***/
+#define IDirectInputDevice7_GetCapabilities(p,a) (p)->GetCapabilities(a)
+#define IDirectInputDevice7_EnumObjects(p,a,b,c) (p)->EnumObjects(a,b,c)
+#define IDirectInputDevice7_GetProperty(p,a,b) (p)->GetProperty(a,b)
+#define IDirectInputDevice7_SetProperty(p,a,b) (p)->SetProperty(a,b)
+#define IDirectInputDevice7_Acquire(p) (p)->Acquire()
+#define IDirectInputDevice7_Unacquire(p) (p)->Unacquire()
+#define IDirectInputDevice7_GetDeviceState(p,a,b) (p)->GetDeviceState(a,b)
+#define IDirectInputDevice7_GetDeviceData(p,a,b,c,d) (p)->GetDeviceData(a,b,c,d)
+#define IDirectInputDevice7_SetDataFormat(p,a) (p)->SetDataFormat(a)
+#define IDirectInputDevice7_SetEventNotification(p,a) (p)->SetEventNotification(a)
+#define IDirectInputDevice7_SetCooperativeLevel(p,a,b) (p)->SetCooperativeLevel(a,b)
+#define IDirectInputDevice7_GetObjectInfo(p,a,b,c) (p)->GetObjectInfo(a,b,c)
+#define IDirectInputDevice7_GetDeviceInfo(p,a) (p)->GetDeviceInfo(a)
+#define IDirectInputDevice7_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b)
+#define IDirectInputDevice7_Initialize(p,a,b,c) (p)->Initialize(a,b,c)
+/*** IDirectInputDevice2 methods ***/
+#define IDirectInputDevice7_CreateEffect(p,a,b,c,d) (p)->CreateEffect(a,b,c,d)
+#define IDirectInputDevice7_EnumEffects(p,a,b,c) (p)->EnumEffects(a,b,c)
+#define IDirectInputDevice7_GetEffectInfo(p,a,b) (p)->GetEffectInfo(a,b)
+#define IDirectInputDevice7_GetForceFeedbackState(p,a) (p)->GetForceFeedbackState(a)
+#define IDirectInputDevice7_SendForceFeedbackCommand(p,a) (p)->SendForceFeedbackCommand(a)
+#define IDirectInputDevice7_EnumCreatedEffectObjects(p,a,b,c) (p)->EnumCreatedEffectObjects(a,b,c)
+#define IDirectInputDevice7_Escape(p,a) (p)->Escape(a)
+#define IDirectInputDevice7_Poll(p) (p)->Poll()
+#define IDirectInputDevice7_SendDeviceData(p,a,b,c,d) (p)->SendDeviceData(a,b,c,d)
+/*** IDirectInputDevice7 methods ***/
+#define IDirectInputDevice7_EnumEffectsInFile(p,a,b,c,d) (p)->EnumEffectsInFile(a,b,c,d)
+#define IDirectInputDevice7_WriteEffectToFile(p,a,b,c,d) (p)->WriteEffectToFile(a,b,c,d)
+#endif
+
+#endif /* DI7 */
+
+#if DIRECTINPUT_VERSION >= 0x0800
+/*****************************************************************************
+ * IDirectInputDevice8A interface
+ */
+#undef INTERFACE
+#define INTERFACE IDirectInputDevice8A
+DECLARE_INTERFACE_(IDirectInputDevice8A,IDirectInputDevice7A)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectInputDeviceA methods ***/
+ STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS lpDIDevCaps) PURE;
+ STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(GetProperty)(THIS_ REFGUID rguidProp, LPDIPROPHEADER pdiph) PURE;
+ STDMETHOD(SetProperty)(THIS_ REFGUID rguidProp, LPCDIPROPHEADER pdiph) PURE;
+ STDMETHOD(Acquire)(THIS) PURE;
+ STDMETHOD(Unacquire)(THIS) PURE;
+ STDMETHOD(GetDeviceState)(THIS_ DWORD cbData, LPVOID lpvData) PURE;
+ STDMETHOD(GetDeviceData)(THIS_ DWORD cbObjectData, LPDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD dwFlags) PURE;
+ STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT lpdf) PURE;
+ STDMETHOD(SetEventNotification)(THIS_ HANDLE hEvent) PURE;
+ STDMETHOD(SetCooperativeLevel)(THIS_ HWND hwnd, DWORD dwFlags) PURE;
+ STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEA pdidoi, DWORD dwObj, DWORD dwHow) PURE;
+ STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEA pdidi) PURE;
+ STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE;
+ STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion, REFGUID rguid) PURE;
+ /*** IDirectInputDevice2A methods ***/
+ STDMETHOD(CreateEffect)(THIS_ REFGUID rguid, LPCDIEFFECT lpeff, LPDIRECTINPUTEFFECT *ppdeff, LPUNKNOWN punkOuter) PURE;
+ STDMETHOD(EnumEffects)(THIS_ LPDIENUMEFFECTSCALLBACKA lpCallback, LPVOID pvRef, DWORD dwEffType) PURE;
+ STDMETHOD(GetEffectInfo)(THIS_ LPDIEFFECTINFOA pdei, REFGUID rguid) PURE;
+ STDMETHOD(GetForceFeedbackState)(THIS_ LPDWORD pdwOut) PURE;
+ STDMETHOD(SendForceFeedbackCommand)(THIS_ DWORD dwFlags) PURE;
+ STDMETHOD(EnumCreatedEffectObjects)(THIS_ LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback, LPVOID pvRef, DWORD fl) PURE;
+ STDMETHOD(Escape)(THIS_ LPDIEFFESCAPE pesc) PURE;
+ STDMETHOD(Poll)(THIS) PURE;
+ STDMETHOD(SendDeviceData)(THIS_ DWORD cbObjectData, LPCDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD fl) PURE;
+ /*** IDirectInputDevice7A methods ***/
+ STDMETHOD(EnumEffectsInFile)(THIS_ LPCSTR lpszFileName,LPDIENUMEFFECTSINFILECALLBACK pec,LPVOID pvRef,DWORD dwFlags) PURE;
+ STDMETHOD(WriteEffectToFile)(THIS_ LPCSTR lpszFileName,DWORD dwEntries,LPDIFILEEFFECT rgDiFileEft,DWORD dwFlags) PURE;
+ /*** IDirectInputDevice8A methods ***/
+ STDMETHOD(BuildActionMap)(THIS_ LPDIACTIONFORMATA lpdiaf, LPCSTR lpszUserName, DWORD dwFlags) PURE;
+ STDMETHOD(SetActionMap)(THIS_ LPDIACTIONFORMATA lpdiaf, LPCSTR lpszUserName, DWORD dwFlags) PURE;
+ STDMETHOD(GetImageInfo)(THIS_ LPDIDEVICEIMAGEINFOHEADERA lpdiDevImageInfoHeader) PURE;
+};
+
+/*****************************************************************************
+ * IDirectInputDevice8W interface
+ */
+#undef INTERFACE
+#define INTERFACE IDirectInputDevice8W
+DECLARE_INTERFACE_(IDirectInputDevice8W,IDirectInputDevice7W)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectInputDeviceW methods ***/
+ STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS lpDIDevCaps) PURE;
+ STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKW lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(GetProperty)(THIS_ REFGUID rguidProp, LPDIPROPHEADER pdiph) PURE;
+ STDMETHOD(SetProperty)(THIS_ REFGUID rguidProp, LPCDIPROPHEADER pdiph) PURE;
+ STDMETHOD(Acquire)(THIS) PURE;
+ STDMETHOD(Unacquire)(THIS) PURE;
+ STDMETHOD(GetDeviceState)(THIS_ DWORD cbData, LPVOID lpvData) PURE;
+ STDMETHOD(GetDeviceData)(THIS_ DWORD cbObjectData, LPDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD dwFlags) PURE;
+ STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT lpdf) PURE;
+ STDMETHOD(SetEventNotification)(THIS_ HANDLE hEvent) PURE;
+ STDMETHOD(SetCooperativeLevel)(THIS_ HWND hwnd, DWORD dwFlags) PURE;
+ STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEW pdidoi, DWORD dwObj, DWORD dwHow) PURE;
+ STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEW pdidi) PURE;
+ STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE;
+ STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion, REFGUID rguid) PURE;
+ /*** IDirectInputDevice2W methods ***/
+ STDMETHOD(CreateEffect)(THIS_ REFGUID rguid, LPCDIEFFECT lpeff, LPDIRECTINPUTEFFECT *ppdeff, LPUNKNOWN punkOuter) PURE;
+ STDMETHOD(EnumEffects)(THIS_ LPDIENUMEFFECTSCALLBACKW lpCallback, LPVOID pvRef, DWORD dwEffType) PURE;
+ STDMETHOD(GetEffectInfo)(THIS_ LPDIEFFECTINFOW pdei, REFGUID rguid) PURE;
+ STDMETHOD(GetForceFeedbackState)(THIS_ LPDWORD pdwOut) PURE;
+ STDMETHOD(SendForceFeedbackCommand)(THIS_ DWORD dwFlags) PURE;
+ STDMETHOD(EnumCreatedEffectObjects)(THIS_ LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback, LPVOID pvRef, DWORD fl) PURE;
+ STDMETHOD(Escape)(THIS_ LPDIEFFESCAPE pesc) PURE;
+ STDMETHOD(Poll)(THIS) PURE;
+ STDMETHOD(SendDeviceData)(THIS_ DWORD cbObjectData, LPCDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD fl) PURE;
+ /*** IDirectInputDevice7W methods ***/
+ STDMETHOD(EnumEffectsInFile)(THIS_ LPCWSTR lpszFileName,LPDIENUMEFFECTSINFILECALLBACK pec,LPVOID pvRef,DWORD dwFlags) PURE;
+ STDMETHOD(WriteEffectToFile)(THIS_ LPCWSTR lpszFileName,DWORD dwEntries,LPDIFILEEFFECT rgDiFileEft,DWORD dwFlags) PURE;
+ /*** IDirectInputDevice8W methods ***/
+ STDMETHOD(BuildActionMap)(THIS_ LPDIACTIONFORMATW lpdiaf, LPCWSTR lpszUserName, DWORD dwFlags) PURE;
+ STDMETHOD(SetActionMap)(THIS_ LPDIACTIONFORMATW lpdiaf, LPCWSTR lpszUserName, DWORD dwFlags) PURE;
+ STDMETHOD(GetImageInfo)(THIS_ LPDIDEVICEIMAGEINFOHEADERW lpdiDevImageInfoHeader) PURE;
+};
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectInputDevice8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectInputDevice8_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirectInputDevice8_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirectInputDevice methods ***/
+#define IDirectInputDevice8_GetCapabilities(p,a) (p)->lpVtbl->GetCapabilities(p,a)
+#define IDirectInputDevice8_EnumObjects(p,a,b,c) (p)->lpVtbl->EnumObjects(p,a,b,c)
+#define IDirectInputDevice8_GetProperty(p,a,b) (p)->lpVtbl->GetProperty(p,a,b)
+#define IDirectInputDevice8_SetProperty(p,a,b) (p)->lpVtbl->SetProperty(p,a,b)
+#define IDirectInputDevice8_Acquire(p) (p)->lpVtbl->Acquire(p)
+#define IDirectInputDevice8_Unacquire(p) (p)->lpVtbl->Unacquire(p)
+#define IDirectInputDevice8_GetDeviceState(p,a,b) (p)->lpVtbl->GetDeviceState(p,a,b)
+#define IDirectInputDevice8_GetDeviceData(p,a,b,c,d) (p)->lpVtbl->GetDeviceData(p,a,b,c,d)
+#define IDirectInputDevice8_SetDataFormat(p,a) (p)->lpVtbl->SetDataFormat(p,a)
+#define IDirectInputDevice8_SetEventNotification(p,a) (p)->lpVtbl->SetEventNotification(p,a)
+#define IDirectInputDevice8_SetCooperativeLevel(p,a,b) (p)->lpVtbl->SetCooperativeLevel(p,a,b)
+#define IDirectInputDevice8_GetObjectInfo(p,a,b,c) (p)->lpVtbl->GetObjectInfo(p,a,b,c)
+#define IDirectInputDevice8_GetDeviceInfo(p,a) (p)->lpVtbl->GetDeviceInfo(p,a)
+#define IDirectInputDevice8_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b)
+#define IDirectInputDevice8_Initialize(p,a,b,c) (p)->lpVtbl->Initialize(p,a,b,c)
+/*** IDirectInputDevice2 methods ***/
+#define IDirectInputDevice8_CreateEffect(p,a,b,c,d) (p)->lpVtbl->CreateEffect(p,a,b,c,d)
+#define IDirectInputDevice8_EnumEffects(p,a,b,c) (p)->lpVtbl->EnumEffects(p,a,b,c)
+#define IDirectInputDevice8_GetEffectInfo(p,a,b) (p)->lpVtbl->GetEffectInfo(p,a,b)
+#define IDirectInputDevice8_GetForceFeedbackState(p,a) (p)->lpVtbl->GetForceFeedbackState(p,a)
+#define IDirectInputDevice8_SendForceFeedbackCommand(p,a) (p)->lpVtbl->SendForceFeedbackCommand(p,a)
+#define IDirectInputDevice8_EnumCreatedEffectObjects(p,a,b,c) (p)->lpVtbl->EnumCreatedEffectObjects(p,a,b,c)
+#define IDirectInputDevice8_Escape(p,a) (p)->lpVtbl->Escape(p,a)
+#define IDirectInputDevice8_Poll(p) (p)->lpVtbl->Poll(p)
+#define IDirectInputDevice8_SendDeviceData(p,a,b,c,d) (p)->lpVtbl->SendDeviceData(p,a,b,c,d)
+/*** IDirectInputDevice7 methods ***/
+#define IDirectInputDevice8_EnumEffectsInFile(p,a,b,c,d) (p)->lpVtbl->EnumEffectsInFile(p,a,b,c,d)
+#define IDirectInputDevice8_WriteEffectToFile(p,a,b,c,d) (p)->lpVtbl->WriteEffectToFile(p,a,b,c,d)
+/*** IDirectInputDevice8 methods ***/
+#define IDirectInputDevice8_BuildActionMap(p,a,b,c) (p)->lpVtbl->BuildActionMap(p,a,b,c)
+#define IDirectInputDevice8_SetActionMap(p,a,b,c) (p)->lpVtbl->SetActionMap(p,a,b,c)
+#define IDirectInputDevice8_GetImageInfo(p,a) (p)->lpVtbl->GetImageInfo(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirectInputDevice8_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectInputDevice8_AddRef(p) (p)->AddRef()
+#define IDirectInputDevice8_Release(p) (p)->Release()
+/*** IDirectInputDevice methods ***/
+#define IDirectInputDevice8_GetCapabilities(p,a) (p)->GetCapabilities(a)
+#define IDirectInputDevice8_EnumObjects(p,a,b,c) (p)->EnumObjects(a,b,c)
+#define IDirectInputDevice8_GetProperty(p,a,b) (p)->GetProperty(a,b)
+#define IDirectInputDevice8_SetProperty(p,a,b) (p)->SetProperty(a,b)
+#define IDirectInputDevice8_Acquire(p) (p)->Acquire()
+#define IDirectInputDevice8_Unacquire(p) (p)->Unacquire()
+#define IDirectInputDevice8_GetDeviceState(p,a,b) (p)->GetDeviceState(a,b)
+#define IDirectInputDevice8_GetDeviceData(p,a,b,c,d) (p)->GetDeviceData(a,b,c,d)
+#define IDirectInputDevice8_SetDataFormat(p,a) (p)->SetDataFormat(a)
+#define IDirectInputDevice8_SetEventNotification(p,a) (p)->SetEventNotification(a)
+#define IDirectInputDevice8_SetCooperativeLevel(p,a,b) (p)->SetCooperativeLevel(a,b)
+#define IDirectInputDevice8_GetObjectInfo(p,a,b,c) (p)->GetObjectInfo(a,b,c)
+#define IDirectInputDevice8_GetDeviceInfo(p,a) (p)->GetDeviceInfo(a)
+#define IDirectInputDevice8_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b)
+#define IDirectInputDevice8_Initialize(p,a,b,c) (p)->Initialize(a,b,c)
+/*** IDirectInputDevice2 methods ***/
+#define IDirectInputDevice8_CreateEffect(p,a,b,c,d) (p)->CreateEffect(a,b,c,d)
+#define IDirectInputDevice8_EnumEffects(p,a,b,c) (p)->EnumEffects(a,b,c)
+#define IDirectInputDevice8_GetEffectInfo(p,a,b) (p)->GetEffectInfo(a,b)
+#define IDirectInputDevice8_GetForceFeedbackState(p,a) (p)->GetForceFeedbackState(a)
+#define IDirectInputDevice8_SendForceFeedbackCommand(p,a) (p)->SendForceFeedbackCommand(a)
+#define IDirectInputDevice8_EnumCreatedEffectObjects(p,a,b,c) (p)->EnumCreatedEffectObjects(a,b,c)
+#define IDirectInputDevice8_Escape(p,a) (p)->Escape(a)
+#define IDirectInputDevice8_Poll(p) (p)->Poll()
+#define IDirectInputDevice8_SendDeviceData(p,a,b,c,d) (p)->SendDeviceData(a,b,c,d)
+/*** IDirectInputDevice7 methods ***/
+#define IDirectInputDevice8_EnumEffectsInFile(p,a,b,c,d) (p)->EnumEffectsInFile(a,b,c,d)
+#define IDirectInputDevice8_WriteEffectToFile(p,a,b,c,d) (p)->WriteEffectToFile(a,b,c,d)
+/*** IDirectInputDevice8 methods ***/
+#define IDirectInputDevice8_BuildActionMap(p,a,b,c) (p)->BuildActionMap(a,b,c)
+#define IDirectInputDevice8_SetActionMap(p,a,b,c) (p)->SetActionMap(a,b,c)
+#define IDirectInputDevice8_GetImageInfo(p,a) (p)->GetImageInfo(a)
+#endif
+
+#endif /* DI8 */
+
+/* "Standard" Mouse report... */
+typedef struct DIMOUSESTATE {
+ LONG lX;
+ LONG lY;
+ LONG lZ;
+ BYTE rgbButtons[4];
+} DIMOUSESTATE;
+
+#if DIRECTINPUT_VERSION >= 0x0700
+/* "Standard" Mouse report for DInput 7... */
+typedef struct DIMOUSESTATE2 {
+ LONG lX;
+ LONG lY;
+ LONG lZ;
+ BYTE rgbButtons[8];
+} DIMOUSESTATE2;
+#endif /* DI7 */
+
+#define DIMOFS_X FIELD_OFFSET(DIMOUSESTATE, lX)
+#define DIMOFS_Y FIELD_OFFSET(DIMOUSESTATE, lY)
+#define DIMOFS_Z FIELD_OFFSET(DIMOUSESTATE, lZ)
+#define DIMOFS_BUTTON0 (FIELD_OFFSET(DIMOUSESTATE, rgbButtons) + 0)
+#define DIMOFS_BUTTON1 (FIELD_OFFSET(DIMOUSESTATE, rgbButtons) + 1)
+#define DIMOFS_BUTTON2 (FIELD_OFFSET(DIMOUSESTATE, rgbButtons) + 2)
+#define DIMOFS_BUTTON3 (FIELD_OFFSET(DIMOUSESTATE, rgbButtons) + 3)
+#if DIRECTINPUT_VERSION >= 0x0700
+#define DIMOFS_BUTTON4 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 4)
+#define DIMOFS_BUTTON5 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 5)
+#define DIMOFS_BUTTON6 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 6)
+#define DIMOFS_BUTTON7 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 7)
+#endif /* DI7 */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern const DIDATAFORMAT c_dfDIMouse;
+#if DIRECTINPUT_VERSION >= 0x0700
+extern const DIDATAFORMAT c_dfDIMouse2; /* DX 7 */
+#endif /* DI7 */
+extern const DIDATAFORMAT c_dfDIKeyboard;
+#if DIRECTINPUT_VERSION >= 0x0500
+extern const DIDATAFORMAT c_dfDIJoystick;
+extern const DIDATAFORMAT c_dfDIJoystick2;
+#endif /* DI5 */
+#ifdef __cplusplus
+};
+#endif
+
+/*****************************************************************************
+ * IDirectInputA interface
+ */
+#undef INTERFACE
+#define INTERFACE IDirectInputA
+DECLARE_INTERFACE_(IDirectInputA,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectInputA methods ***/
+ STDMETHOD(CreateDevice)(THIS_ REFGUID rguid, LPDIRECTINPUTDEVICEA *lplpDirectInputDevice, LPUNKNOWN pUnkOuter) PURE;
+ STDMETHOD(EnumDevices)(THIS_ DWORD dwDevType, LPDIENUMDEVICESCALLBACKA lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(GetDeviceStatus)(THIS_ REFGUID rguidInstance) PURE;
+ STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE;
+ STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion) PURE;
+};
+
+/*****************************************************************************
+ * IDirectInputW interface
+ */
+#undef INTERFACE
+#define INTERFACE IDirectInputW
+DECLARE_INTERFACE_(IDirectInputW,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectInputW methods ***/
+ STDMETHOD(CreateDevice)(THIS_ REFGUID rguid, LPDIRECTINPUTDEVICEW *lplpDirectInputDevice, LPUNKNOWN pUnkOuter) PURE;
+ STDMETHOD(EnumDevices)(THIS_ DWORD dwDevType, LPDIENUMDEVICESCALLBACKW lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(GetDeviceStatus)(THIS_ REFGUID rguidInstance) PURE;
+ STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE;
+ STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion) PURE;
+};
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectInput_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectInput_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirectInput_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirectInput methods ***/
+#define IDirectInput_CreateDevice(p,a,b,c) (p)->lpVtbl->CreateDevice(p,a,b,c)
+#define IDirectInput_EnumDevices(p,a,b,c,d) (p)->lpVtbl->EnumDevices(p,a,b,c,d)
+#define IDirectInput_GetDeviceStatus(p,a) (p)->lpVtbl->GetDeviceStatus(p,a)
+#define IDirectInput_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b)
+#define IDirectInput_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IDirectInput_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectInput_AddRef(p) (p)->AddRef()
+#define IDirectInput_Release(p) (p)->Release()
+/*** IDirectInput methods ***/
+#define IDirectInput_CreateDevice(p,a,b,c) (p)->CreateDevice(a,b,c)
+#define IDirectInput_EnumDevices(p,a,b,c,d) (p)->EnumDevices(a,b,c,d)
+#define IDirectInput_GetDeviceStatus(p,a) (p)->GetDeviceStatus(a)
+#define IDirectInput_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b)
+#define IDirectInput_Initialize(p,a,b) (p)->Initialize(a,b)
+#endif
+
+/*****************************************************************************
+ * IDirectInput2A interface
+ */
+#undef INTERFACE
+#define INTERFACE IDirectInput2A
+DECLARE_INTERFACE_(IDirectInput2A,IDirectInputA)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectInputA methods ***/
+ STDMETHOD(CreateDevice)(THIS_ REFGUID rguid, LPDIRECTINPUTDEVICEA *lplpDirectInputDevice, LPUNKNOWN pUnkOuter) PURE;
+ STDMETHOD(EnumDevices)(THIS_ DWORD dwDevType, LPDIENUMDEVICESCALLBACKA lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(GetDeviceStatus)(THIS_ REFGUID rguidInstance) PURE;
+ STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE;
+ STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion) PURE;
+ /*** IDirectInput2A methods ***/
+ STDMETHOD(FindDevice)(THIS_ REFGUID rguid, LPCSTR pszName, LPGUID pguidInstance) PURE;
+};
+
+/*****************************************************************************
+ * IDirectInput2W interface
+ */
+#undef INTERFACE
+#define INTERFACE IDirectInput2W
+DECLARE_INTERFACE_(IDirectInput2W,IDirectInputW)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectInputW methods ***/
+ STDMETHOD(CreateDevice)(THIS_ REFGUID rguid, LPDIRECTINPUTDEVICEW *lplpDirectInputDevice, LPUNKNOWN pUnkOuter) PURE;
+ STDMETHOD(EnumDevices)(THIS_ DWORD dwDevType, LPDIENUMDEVICESCALLBACKW lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(GetDeviceStatus)(THIS_ REFGUID rguidInstance) PURE;
+ STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE;
+ STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion) PURE;
+ /*** IDirectInput2W methods ***/
+ STDMETHOD(FindDevice)(THIS_ REFGUID rguid, LPCWSTR pszName, LPGUID pguidInstance) PURE;
+};
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectInput2_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectInput2_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirectInput2_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirectInput methods ***/
+#define IDirectInput2_CreateDevice(p,a,b,c) (p)->lpVtbl->CreateDevice(p,a,b,c)
+#define IDirectInput2_EnumDevices(p,a,b,c,d) (p)->lpVtbl->EnumDevices(p,a,b,c,d)
+#define IDirectInput2_GetDeviceStatus(p,a) (p)->lpVtbl->GetDeviceStatus(p,a)
+#define IDirectInput2_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b)
+#define IDirectInput2_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b)
+/*** IDirectInput2 methods ***/
+#define IDirectInput2_FindDevice(p,a,b,c) (p)->lpVtbl->FindDevice(p,a,b,c)
+#else
+/*** IUnknown methods ***/
+#define IDirectInput2_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectInput2_AddRef(p) (p)->AddRef()
+#define IDirectInput2_Release(p) (p)->Release()
+/*** IDirectInput methods ***/
+#define IDirectInput2_CreateDevice(p,a,b,c) (p)->CreateDevice(a,b,c)
+#define IDirectInput2_EnumDevices(p,a,b,c,d) (p)->EnumDevices(a,b,c,d)
+#define IDirectInput2_GetDeviceStatus(p,a) (p)->GetDeviceStatus(a)
+#define IDirectInput2_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b)
+#define IDirectInput2_Initialize(p,a,b) (p)->Initialize(a,b)
+/*** IDirectInput2 methods ***/
+#define IDirectInput2_FindDevice(p,a,b,c) (p)->FindDevice(a,b,c)
+#endif
+
+/*****************************************************************************
+ * IDirectInput7A interface
+ */
+#undef INTERFACE
+#define INTERFACE IDirectInput7A
+DECLARE_INTERFACE_(IDirectInput7A,IDirectInput2A)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectInputA methods ***/
+ STDMETHOD(CreateDevice)(THIS_ REFGUID rguid, LPDIRECTINPUTDEVICEA *lplpDirectInputDevice, LPUNKNOWN pUnkOuter) PURE;
+ STDMETHOD(EnumDevices)(THIS_ DWORD dwDevType, LPDIENUMDEVICESCALLBACKA lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(GetDeviceStatus)(THIS_ REFGUID rguidInstance) PURE;
+ STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE;
+ STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion) PURE;
+ /*** IDirectInput2A methods ***/
+ STDMETHOD(FindDevice)(THIS_ REFGUID rguid, LPCSTR pszName, LPGUID pguidInstance) PURE;
+ /*** IDirectInput7A methods ***/
+ STDMETHOD(CreateDeviceEx)(THIS_ REFGUID rguid, REFIID riid, LPVOID *pvOut, LPUNKNOWN lpUnknownOuter) PURE;
+};
+
+/*****************************************************************************
+ * IDirectInput7W interface
+ */
+#undef INTERFACE
+#define INTERFACE IDirectInput7W
+DECLARE_INTERFACE_(IDirectInput7W,IDirectInput2W)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectInputW methods ***/
+ STDMETHOD(CreateDevice)(THIS_ REFGUID rguid, LPDIRECTINPUTDEVICEW *lplpDirectInputDevice, LPUNKNOWN pUnkOuter) PURE;
+ STDMETHOD(EnumDevices)(THIS_ DWORD dwDevType, LPDIENUMDEVICESCALLBACKW lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(GetDeviceStatus)(THIS_ REFGUID rguidInstance) PURE;
+ STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE;
+ STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion) PURE;
+ /*** IDirectInput2W methods ***/
+ STDMETHOD(FindDevice)(THIS_ REFGUID rguid, LPCWSTR pszName, LPGUID pguidInstance) PURE;
+ /*** IDirectInput7W methods ***/
+ STDMETHOD(CreateDeviceEx)(THIS_ REFGUID rguid, REFIID riid, LPVOID *pvOut, LPUNKNOWN lpUnknownOuter) PURE;
+};
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectInput7_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectInput7_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirectInput7_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirectInput methods ***/
+#define IDirectInput7_CreateDevice(p,a,b,c) (p)->lpVtbl->CreateDevice(p,a,b,c)
+#define IDirectInput7_EnumDevices(p,a,b,c,d) (p)->lpVtbl->EnumDevices(p,a,b,c,d)
+#define IDirectInput7_GetDeviceStatus(p,a) (p)->lpVtbl->GetDeviceStatus(p,a)
+#define IDirectInput7_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b)
+#define IDirectInput7_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b)
+/*** IDirectInput2 methods ***/
+#define IDirectInput7_FindDevice(p,a,b,c) (p)->lpVtbl->FindDevice(p,a,b,c)
+/*** IDirectInput7 methods ***/
+#define IDirectInput7_CreateDeviceEx(p,a,b,c,d) (p)->lpVtbl->CreateDeviceEx(p,a,b,c,d)
+#else
+/*** IUnknown methods ***/
+#define IDirectInput7_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectInput7_AddRef(p) (p)->AddRef()
+#define IDirectInput7_Release(p) (p)->Release()
+/*** IDirectInput methods ***/
+#define IDirectInput7_CreateDevice(p,a,b,c) (p)->CreateDevice(a,b,c)
+#define IDirectInput7_EnumDevices(p,a,b,c,d) (p)->EnumDevices(a,b,c,d)
+#define IDirectInput7_GetDeviceStatus(p,a) (p)->GetDeviceStatus(a)
+#define IDirectInput7_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b)
+#define IDirectInput7_Initialize(p,a,b) (p)->Initialize(a,b)
+/*** IDirectInput2 methods ***/
+#define IDirectInput7_FindDevice(p,a,b,c) (p)->FindDevice(a,b,c)
+/*** IDirectInput7 methods ***/
+#define IDirectInput7_CreateDeviceEx(p,a,b,c,d) (p)->CreateDeviceEx(a,b,c,d)
+#endif
+
+
+#if DIRECTINPUT_VERSION >= 0x0800
+/*****************************************************************************
+ * IDirectInput8A interface
+ */
+#undef INTERFACE
+#define INTERFACE IDirectInput8A
+DECLARE_INTERFACE_(IDirectInput8A,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectInput8A methods ***/
+ STDMETHOD(CreateDevice)(THIS_ REFGUID rguid, LPDIRECTINPUTDEVICE8A *lplpDirectInputDevice, LPUNKNOWN pUnkOuter) PURE;
+ STDMETHOD(EnumDevices)(THIS_ DWORD dwDevType, LPDIENUMDEVICESCALLBACKA lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(GetDeviceStatus)(THIS_ REFGUID rguidInstance) PURE;
+ STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE;
+ STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion) PURE;
+ STDMETHOD(FindDevice)(THIS_ REFGUID rguid, LPCSTR pszName, LPGUID pguidInstance) PURE;
+ STDMETHOD(EnumDevicesBySemantics)(THIS_ LPCSTR ptszUserName, LPDIACTIONFORMATA lpdiActionFormat, LPDIENUMDEVICESBYSEMANTICSCBA lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(ConfigureDevices)(THIS_ LPDICONFIGUREDEVICESCALLBACK lpdiCallback, LPDICONFIGUREDEVICESPARAMSA lpdiCDParams, DWORD dwFlags, LPVOID pvRefData) PURE;
+};
+
+/*****************************************************************************
+ * IDirectInput8W interface
+ */
+#undef INTERFACE
+#define INTERFACE IDirectInput8W
+DECLARE_INTERFACE_(IDirectInput8W,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectInput8W methods ***/
+ STDMETHOD(CreateDevice)(THIS_ REFGUID rguid, LPDIRECTINPUTDEVICE8W *lplpDirectInputDevice, LPUNKNOWN pUnkOuter) PURE;
+ STDMETHOD(EnumDevices)(THIS_ DWORD dwDevType, LPDIENUMDEVICESCALLBACKW lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(GetDeviceStatus)(THIS_ REFGUID rguidInstance) PURE;
+ STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE;
+ STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion) PURE;
+ STDMETHOD(FindDevice)(THIS_ REFGUID rguid, LPCWSTR pszName, LPGUID pguidInstance) PURE;
+ STDMETHOD(EnumDevicesBySemantics)(THIS_ LPCWSTR ptszUserName, LPDIACTIONFORMATW lpdiActionFormat, LPDIENUMDEVICESBYSEMANTICSCBW lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(ConfigureDevices)(THIS_ LPDICONFIGUREDEVICESCALLBACK lpdiCallback, LPDICONFIGUREDEVICESPARAMSW lpdiCDParams, DWORD dwFlags, LPVOID pvRefData) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectInput8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectInput8_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirectInput8_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirectInput8 methods ***/
+#define IDirectInput8_CreateDevice(p,a,b,c) (p)->lpVtbl->CreateDevice(p,a,b,c)
+#define IDirectInput8_EnumDevices(p,a,b,c,d) (p)->lpVtbl->EnumDevices(p,a,b,c,d)
+#define IDirectInput8_GetDeviceStatus(p,a) (p)->lpVtbl->GetDeviceStatus(p,a)
+#define IDirectInput8_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b)
+#define IDirectInput8_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b)
+#define IDirectInput8_FindDevice(p,a,b,c) (p)->lpVtbl->FindDevice(p,a,b,c)
+#define IDirectInput8_EnumDevicesBySemantics(p,a,b,c,d,e) (p)->lpVtbl->EnumDevicesBySemantics(p,a,b,c,d,e)
+#define IDirectInput8_ConfigureDevices(p,a,b,c,d) (p)->lpVtbl->ConfigureDevices(p,a,b,c,d)
+#else
+/*** IUnknown methods ***/
+#define IDirectInput8_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectInput8_AddRef(p) (p)->AddRef()
+#define IDirectInput8_Release(p) (p)->Release()
+/*** IDirectInput8 methods ***/
+#define IDirectInput8_CreateDevice(p,a,b,c) (p)->CreateDevice(a,b,c)
+#define IDirectInput8_EnumDevices(p,a,b,c,d) (p)->EnumDevices(a,b,c,d)
+#define IDirectInput8_GetDeviceStatus(p,a) (p)->GetDeviceStatus(a)
+#define IDirectInput8_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b)
+#define IDirectInput8_Initialize(p,a,b) (p)->Initialize(a,b)
+#define IDirectInput8_FindDevice(p,a,b,c) (p)->FindDevice(a,b,c)
+#define IDirectInput8_EnumDevicesBySemantics(p,a,b,c,d,e) (p)->EnumDevicesBySemantics(a,b,c,d,e)
+#define IDirectInput8_ConfigureDevices(p,a,b,c,d) (p)->ConfigureDevices(a,b,c,d)
+#endif
+
+#endif /* DI8 */
+
+/* Export functions */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if DIRECTINPUT_VERSION >= 0x0800
+HRESULT WINAPI DirectInput8Create(HINSTANCE,DWORD,REFIID,LPVOID *,LPUNKNOWN);
+#else /* DI < 8 */
+HRESULT WINAPI DirectInputCreateA(HINSTANCE,DWORD,LPDIRECTINPUTA *,LPUNKNOWN);
+HRESULT WINAPI DirectInputCreateW(HINSTANCE,DWORD,LPDIRECTINPUTW *,LPUNKNOWN);
+#define DirectInputCreate WINELIB_NAME_AW(DirectInputCreate)
+
+HRESULT WINAPI DirectInputCreateEx(HINSTANCE,DWORD,REFIID,LPVOID *,LPUNKNOWN);
+#endif /* DI8 */
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif /* __DINPUT_INCLUDED__ */
diff --git a/src/external/glfw/deps/mingw/xinput.h b/src/external/glfw/deps/mingw/xinput.h
new file mode 100644
index 000000000..d3ca726ce
--- /dev/null
+++ b/src/external/glfw/deps/mingw/xinput.h
@@ -0,0 +1,239 @@
+/*
+ * The Wine project - Xinput Joystick Library
+ * Copyright 2008 Andrew Fenn
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __WINE_XINPUT_H
+#define __WINE_XINPUT_H
+
+#include
+
+/*
+ * Bitmasks for the joysticks buttons, determines what has
+ * been pressed on the joystick, these need to be mapped
+ * to whatever device you're using instead of an xbox 360
+ * joystick
+ */
+
+#define XINPUT_GAMEPAD_DPAD_UP 0x0001
+#define XINPUT_GAMEPAD_DPAD_DOWN 0x0002
+#define XINPUT_GAMEPAD_DPAD_LEFT 0x0004
+#define XINPUT_GAMEPAD_DPAD_RIGHT 0x0008
+#define XINPUT_GAMEPAD_START 0x0010
+#define XINPUT_GAMEPAD_BACK 0x0020
+#define XINPUT_GAMEPAD_LEFT_THUMB 0x0040
+#define XINPUT_GAMEPAD_RIGHT_THUMB 0x0080
+#define XINPUT_GAMEPAD_LEFT_SHOULDER 0x0100
+#define XINPUT_GAMEPAD_RIGHT_SHOULDER 0x0200
+#define XINPUT_GAMEPAD_A 0x1000
+#define XINPUT_GAMEPAD_B 0x2000
+#define XINPUT_GAMEPAD_X 0x4000
+#define XINPUT_GAMEPAD_Y 0x8000
+
+/*
+ * Defines the flags used to determine if the user is pushing
+ * down on a button, not holding a button, etc
+ */
+
+#define XINPUT_KEYSTROKE_KEYDOWN 0x0001
+#define XINPUT_KEYSTROKE_KEYUP 0x0002
+#define XINPUT_KEYSTROKE_REPEAT 0x0004
+
+/*
+ * Defines the codes which are returned by XInputGetKeystroke
+ */
+
+#define VK_PAD_A 0x5800
+#define VK_PAD_B 0x5801
+#define VK_PAD_X 0x5802
+#define VK_PAD_Y 0x5803
+#define VK_PAD_RSHOULDER 0x5804
+#define VK_PAD_LSHOULDER 0x5805
+#define VK_PAD_LTRIGGER 0x5806
+#define VK_PAD_RTRIGGER 0x5807
+#define VK_PAD_DPAD_UP 0x5810
+#define VK_PAD_DPAD_DOWN 0x5811
+#define VK_PAD_DPAD_LEFT 0x5812
+#define VK_PAD_DPAD_RIGHT 0x5813
+#define VK_PAD_START 0x5814
+#define VK_PAD_BACK 0x5815
+#define VK_PAD_LTHUMB_PRESS 0x5816
+#define VK_PAD_RTHUMB_PRESS 0x5817
+#define VK_PAD_LTHUMB_UP 0x5820
+#define VK_PAD_LTHUMB_DOWN 0x5821
+#define VK_PAD_LTHUMB_RIGHT 0x5822
+#define VK_PAD_LTHUMB_LEFT 0x5823
+#define VK_PAD_LTHUMB_UPLEFT 0x5824
+#define VK_PAD_LTHUMB_UPRIGHT 0x5825
+#define VK_PAD_LTHUMB_DOWNRIGHT 0x5826
+#define VK_PAD_LTHUMB_DOWNLEFT 0x5827
+#define VK_PAD_RTHUMB_UP 0x5830
+#define VK_PAD_RTHUMB_DOWN 0x5831
+#define VK_PAD_RTHUMB_RIGHT 0x5832
+#define VK_PAD_RTHUMB_LEFT 0x5833
+#define VK_PAD_RTHUMB_UPLEFT 0x5834
+#define VK_PAD_RTHUMB_UPRIGHT 0x5835
+#define VK_PAD_RTHUMB_DOWNRIGHT 0x5836
+#define VK_PAD_RTHUMB_DOWNLEFT 0x5837
+
+/*
+ * Deadzones are for analogue joystick controls on the joypad
+ * which determine when input should be assumed to be in the
+ * middle of the pad. This is a threshold to stop a joypad
+ * controlling the game when the player isn't touching the
+ * controls.
+ */
+
+#define XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE 7849
+#define XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE 8689
+#define XINPUT_GAMEPAD_TRIGGER_THRESHOLD 30
+
+
+/*
+ * Defines what type of abilities the type of joystick has
+ * DEVTYPE_GAMEPAD is available for all joysticks, however
+ * there may be more specific identifiers for other joysticks
+ * which are being used.
+ */
+
+#define XINPUT_DEVTYPE_GAMEPAD 0x01
+#define XINPUT_DEVSUBTYPE_GAMEPAD 0x01
+#define XINPUT_DEVSUBTYPE_WHEEL 0x02
+#define XINPUT_DEVSUBTYPE_ARCADE_STICK 0x03
+#define XINPUT_DEVSUBTYPE_FLIGHT_SICK 0x04
+#define XINPUT_DEVSUBTYPE_DANCE_PAD 0x05
+#define XINPUT_DEVSUBTYPE_GUITAR 0x06
+#define XINPUT_DEVSUBTYPE_DRUM_KIT 0x08
+
+/*
+ * These are used with the XInputGetCapabilities function to
+ * determine the abilities to the joystick which has been
+ * plugged in.
+ */
+
+#define XINPUT_CAPS_VOICE_SUPPORTED 0x0004
+#define XINPUT_FLAG_GAMEPAD 0x00000001
+
+/*
+ * Defines the status of the battery if one is used in the
+ * attached joystick. The first two define if the joystick
+ * supports a battery. Disconnected means that the joystick
+ * isn't connected. Wired shows that the joystick is a wired
+ * joystick.
+ */
+
+#define BATTERY_DEVTYPE_GAMEPAD 0x00
+#define BATTERY_DEVTYPE_HEADSET 0x01
+#define BATTERY_TYPE_DISCONNECTED 0x00
+#define BATTERY_TYPE_WIRED 0x01
+#define BATTERY_TYPE_ALKALINE 0x02
+#define BATTERY_TYPE_NIMH 0x03
+#define BATTERY_TYPE_UNKNOWN 0xFF
+#define BATTERY_LEVEL_EMPTY 0x00
+#define BATTERY_LEVEL_LOW 0x01
+#define BATTERY_LEVEL_MEDIUM 0x02
+#define BATTERY_LEVEL_FULL 0x03
+
+/*
+ * How many joysticks can be used with this library. Games that
+ * use the xinput library will not go over this number.
+ */
+
+#define XUSER_MAX_COUNT 4
+#define XUSER_INDEX_ANY 0x000000FF
+
+/*
+ * Defines the structure of an xbox 360 joystick.
+ */
+
+typedef struct _XINPUT_GAMEPAD {
+ WORD wButtons;
+ BYTE bLeftTrigger;
+ BYTE bRightTrigger;
+ SHORT sThumbLX;
+ SHORT sThumbLY;
+ SHORT sThumbRX;
+ SHORT sThumbRY;
+} XINPUT_GAMEPAD, *PXINPUT_GAMEPAD;
+
+typedef struct _XINPUT_STATE {
+ DWORD dwPacketNumber;
+ XINPUT_GAMEPAD Gamepad;
+} XINPUT_STATE, *PXINPUT_STATE;
+
+/*
+ * Defines the structure of how much vibration is set on both the
+ * right and left motors in a joystick. If you're not using a 360
+ * joystick you will have to map these to your device.
+ */
+
+typedef struct _XINPUT_VIBRATION {
+ WORD wLeftMotorSpeed;
+ WORD wRightMotorSpeed;
+} XINPUT_VIBRATION, *PXINPUT_VIBRATION;
+
+/*
+ * Defines the structure for what kind of abilities the joystick has
+ * such abilities are things such as if the joystick has the ability
+ * to send and receive audio, if the joystick is in fact a driving
+ * wheel or perhaps if the joystick is some kind of dance pad or
+ * guitar.
+ */
+
+typedef struct _XINPUT_CAPABILITIES {
+ BYTE Type;
+ BYTE SubType;
+ WORD Flags;
+ XINPUT_GAMEPAD Gamepad;
+ XINPUT_VIBRATION Vibration;
+} XINPUT_CAPABILITIES, *PXINPUT_CAPABILITIES;
+
+/*
+ * Defines the structure for a joystick input event which is
+ * retrieved using the function XInputGetKeystroke
+ */
+typedef struct _XINPUT_KEYSTROKE {
+ WORD VirtualKey;
+ WCHAR Unicode;
+ WORD Flags;
+ BYTE UserIndex;
+ BYTE HidCode;
+} XINPUT_KEYSTROKE, *PXINPUT_KEYSTROKE;
+
+typedef struct _XINPUT_BATTERY_INFORMATION
+{
+ BYTE BatteryType;
+ BYTE BatteryLevel;
+} XINPUT_BATTERY_INFORMATION, *PXINPUT_BATTERY_INFORMATION;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void WINAPI XInputEnable(WINBOOL);
+DWORD WINAPI XInputSetState(DWORD, XINPUT_VIBRATION*);
+DWORD WINAPI XInputGetState(DWORD, XINPUT_STATE*);
+DWORD WINAPI XInputGetKeystroke(DWORD, DWORD, PXINPUT_KEYSTROKE);
+DWORD WINAPI XInputGetCapabilities(DWORD, DWORD, XINPUT_CAPABILITIES*);
+DWORD WINAPI XInputGetDSoundAudioDeviceGuids(DWORD, GUID*, GUID*);
+DWORD WINAPI XInputGetBatteryInformation(DWORD, BYTE, XINPUT_BATTERY_INFORMATION*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __WINE_XINPUT_H */
diff --git a/src/external/glfw/deps/vs2008/stdint.h b/src/external/glfw/deps/vs2008/stdint.h
new file mode 100644
index 000000000..d02608a59
--- /dev/null
+++ b/src/external/glfw/deps/vs2008/stdint.h
@@ -0,0 +1,247 @@
+// ISO C9x compliant stdint.h for Microsoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
+//
+// Copyright (c) 2006-2008 Alexander Chemeris
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// 3. The name of the author may be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
+
+#ifndef _MSC_STDINT_H_ // [
+#define _MSC_STDINT_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#include
+
+// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
+// compiling for ARM we should wrap include with 'extern "C++" {}'
+// or compiler give many errors like this:
+// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
+#ifdef __cplusplus
+extern "C" {
+#endif
+# include
+#ifdef __cplusplus
+}
+#endif
+
+// Define _W64 macros to mark types changing their size, like intptr_t.
+#ifndef _W64
+# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
+# define _W64 __w64
+# else
+# define _W64
+# endif
+#endif
+
+
+// 7.18.1 Integer types
+
+// 7.18.1.1 Exact-width integer types
+
+// Visual Studio 6 and Embedded Visual C++ 4 doesn't
+// realize that, e.g. char has the same size as __int8
+// so we give up on __intX for them.
+#if (_MSC_VER < 1300)
+ typedef signed char int8_t;
+ typedef signed short int16_t;
+ typedef signed int int32_t;
+ typedef unsigned char uint8_t;
+ typedef unsigned short uint16_t;
+ typedef unsigned int uint32_t;
+#else
+ typedef signed __int8 int8_t;
+ typedef signed __int16 int16_t;
+ typedef signed __int32 int32_t;
+ typedef unsigned __int8 uint8_t;
+ typedef unsigned __int16 uint16_t;
+ typedef unsigned __int32 uint32_t;
+#endif
+typedef signed __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+
+
+// 7.18.1.2 Minimum-width integer types
+typedef int8_t int_least8_t;
+typedef int16_t int_least16_t;
+typedef int32_t int_least32_t;
+typedef int64_t int_least64_t;
+typedef uint8_t uint_least8_t;
+typedef uint16_t uint_least16_t;
+typedef uint32_t uint_least32_t;
+typedef uint64_t uint_least64_t;
+
+// 7.18.1.3 Fastest minimum-width integer types
+typedef int8_t int_fast8_t;
+typedef int16_t int_fast16_t;
+typedef int32_t int_fast32_t;
+typedef int64_t int_fast64_t;
+typedef uint8_t uint_fast8_t;
+typedef uint16_t uint_fast16_t;
+typedef uint32_t uint_fast32_t;
+typedef uint64_t uint_fast64_t;
+
+// 7.18.1.4 Integer types capable of holding object pointers
+#ifdef _WIN64 // [
+ typedef signed __int64 intptr_t;
+ typedef unsigned __int64 uintptr_t;
+#else // _WIN64 ][
+ typedef _W64 signed int intptr_t;
+ typedef _W64 unsigned int uintptr_t;
+#endif // _WIN64 ]
+
+// 7.18.1.5 Greatest-width integer types
+typedef int64_t intmax_t;
+typedef uint64_t uintmax_t;
+
+
+// 7.18.2 Limits of specified-width integer types
+
+#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
+
+// 7.18.2.1 Limits of exact-width integer types
+#define INT8_MIN ((int8_t)_I8_MIN)
+#define INT8_MAX _I8_MAX
+#define INT16_MIN ((int16_t)_I16_MIN)
+#define INT16_MAX _I16_MAX
+#define INT32_MIN ((int32_t)_I32_MIN)
+#define INT32_MAX _I32_MAX
+#define INT64_MIN ((int64_t)_I64_MIN)
+#define INT64_MAX _I64_MAX
+#define UINT8_MAX _UI8_MAX
+#define UINT16_MAX _UI16_MAX
+#define UINT32_MAX _UI32_MAX
+#define UINT64_MAX _UI64_MAX
+
+// 7.18.2.2 Limits of minimum-width integer types
+#define INT_LEAST8_MIN INT8_MIN
+#define INT_LEAST8_MAX INT8_MAX
+#define INT_LEAST16_MIN INT16_MIN
+#define INT_LEAST16_MAX INT16_MAX
+#define INT_LEAST32_MIN INT32_MIN
+#define INT_LEAST32_MAX INT32_MAX
+#define INT_LEAST64_MIN INT64_MIN
+#define INT_LEAST64_MAX INT64_MAX
+#define UINT_LEAST8_MAX UINT8_MAX
+#define UINT_LEAST16_MAX UINT16_MAX
+#define UINT_LEAST32_MAX UINT32_MAX
+#define UINT_LEAST64_MAX UINT64_MAX
+
+// 7.18.2.3 Limits of fastest minimum-width integer types
+#define INT_FAST8_MIN INT8_MIN
+#define INT_FAST8_MAX INT8_MAX
+#define INT_FAST16_MIN INT16_MIN
+#define INT_FAST16_MAX INT16_MAX
+#define INT_FAST32_MIN INT32_MIN
+#define INT_FAST32_MAX INT32_MAX
+#define INT_FAST64_MIN INT64_MIN
+#define INT_FAST64_MAX INT64_MAX
+#define UINT_FAST8_MAX UINT8_MAX
+#define UINT_FAST16_MAX UINT16_MAX
+#define UINT_FAST32_MAX UINT32_MAX
+#define UINT_FAST64_MAX UINT64_MAX
+
+// 7.18.2.4 Limits of integer types capable of holding object pointers
+#ifdef _WIN64 // [
+# define INTPTR_MIN INT64_MIN
+# define INTPTR_MAX INT64_MAX
+# define UINTPTR_MAX UINT64_MAX
+#else // _WIN64 ][
+# define INTPTR_MIN INT32_MIN
+# define INTPTR_MAX INT32_MAX
+# define UINTPTR_MAX UINT32_MAX
+#endif // _WIN64 ]
+
+// 7.18.2.5 Limits of greatest-width integer types
+#define INTMAX_MIN INT64_MIN
+#define INTMAX_MAX INT64_MAX
+#define UINTMAX_MAX UINT64_MAX
+
+// 7.18.3 Limits of other integer types
+
+#ifdef _WIN64 // [
+# define PTRDIFF_MIN _I64_MIN
+# define PTRDIFF_MAX _I64_MAX
+#else // _WIN64 ][
+# define PTRDIFF_MIN _I32_MIN
+# define PTRDIFF_MAX _I32_MAX
+#endif // _WIN64 ]
+
+#define SIG_ATOMIC_MIN INT_MIN
+#define SIG_ATOMIC_MAX INT_MAX
+
+#ifndef SIZE_MAX // [
+# ifdef _WIN64 // [
+# define SIZE_MAX _UI64_MAX
+# else // _WIN64 ][
+# define SIZE_MAX _UI32_MAX
+# endif // _WIN64 ]
+#endif // SIZE_MAX ]
+
+// WCHAR_MIN and WCHAR_MAX are also defined in
+#ifndef WCHAR_MIN // [
+# define WCHAR_MIN 0
+#endif // WCHAR_MIN ]
+#ifndef WCHAR_MAX // [
+# define WCHAR_MAX _UI16_MAX
+#endif // WCHAR_MAX ]
+
+#define WINT_MIN 0
+#define WINT_MAX _UI16_MAX
+
+#endif // __STDC_LIMIT_MACROS ]
+
+
+// 7.18.4 Limits of other integer types
+
+#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
+
+// 7.18.4.1 Macros for minimum-width integer constants
+
+#define INT8_C(val) val##i8
+#define INT16_C(val) val##i16
+#define INT32_C(val) val##i32
+#define INT64_C(val) val##i64
+
+#define UINT8_C(val) val##ui8
+#define UINT16_C(val) val##ui16
+#define UINT32_C(val) val##ui32
+#define UINT64_C(val) val##ui64
+
+// 7.18.4.2 Macros for greatest-width integer constants
+#define INTMAX_C INT64_C
+#define UINTMAX_C UINT64_C
+
+#endif // __STDC_CONSTANT_MACROS ]
+
+
+#endif // _MSC_STDINT_H_ ]
diff --git a/src/external/glfw/deps/vulkan/vk_platform.h b/src/external/glfw/deps/vulkan/vk_platform.h
new file mode 100644
index 000000000..0fa62ee23
--- /dev/null
+++ b/src/external/glfw/deps/vulkan/vk_platform.h
@@ -0,0 +1,120 @@
+//
+// File: vk_platform.h
+//
+/*
+** Copyright (c) 2014-2015 The Khronos Group Inc.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+
+#ifndef VK_PLATFORM_H_
+#define VK_PLATFORM_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif // __cplusplus
+
+/*
+***************************************************************************************************
+* Platform-specific directives and type declarations
+***************************************************************************************************
+*/
+
+/* Platform-specific calling convention macros.
+ *
+ * Platforms should define these so that Vulkan clients call Vulkan commands
+ * with the same calling conventions that the Vulkan implementation expects.
+ *
+ * VKAPI_ATTR - Placed before the return type in function declarations.
+ * Useful for C++11 and GCC/Clang-style function attribute syntax.
+ * VKAPI_CALL - Placed after the return type in function declarations.
+ * Useful for MSVC-style calling convention syntax.
+ * VKAPI_PTR - Placed between the '(' and '*' in function pointer types.
+ *
+ * Function declaration: VKAPI_ATTR void VKAPI_CALL vkCommand(void);
+ * Function pointer type: typedef void (VKAPI_PTR *PFN_vkCommand)(void);
+ */
+#if defined(_WIN32)
+ // On Windows, Vulkan commands use the stdcall convention
+ #define VKAPI_ATTR
+ #define VKAPI_CALL __stdcall
+ #define VKAPI_PTR VKAPI_CALL
+#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7
+ #error "Vulkan isn't supported for the 'armeabi' NDK ABI"
+#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE)
+ // On Android 32-bit ARM targets, Vulkan functions use the "hardfloat"
+ // calling convention, i.e. float parameters are passed in registers. This
+ // is true even if the rest of the application passes floats on the stack,
+ // as it does by default when compiling for the armeabi-v7a NDK ABI.
+ #define VKAPI_ATTR __attribute__((pcs("aapcs-vfp")))
+ #define VKAPI_CALL
+ #define VKAPI_PTR VKAPI_ATTR
+#else
+ // On other platforms, use the default calling convention
+ #define VKAPI_ATTR
+ #define VKAPI_CALL
+ #define VKAPI_PTR
+#endif
+
+#include
+
+#if !defined(VK_NO_STDINT_H)
+ #if defined(_MSC_VER) && (_MSC_VER < 1600)
+ typedef signed __int8 int8_t;
+ typedef unsigned __int8 uint8_t;
+ typedef signed __int16 int16_t;
+ typedef unsigned __int16 uint16_t;
+ typedef signed __int32 int32_t;
+ typedef unsigned __int32 uint32_t;
+ typedef signed __int64 int64_t;
+ typedef unsigned __int64 uint64_t;
+ #else
+ #include
+ #endif
+#endif // !defined(VK_NO_STDINT_H)
+
+#ifdef __cplusplus
+} // extern "C"
+#endif // __cplusplus
+
+// Platform-specific headers required by platform window system extensions.
+// These are enabled prior to #including "vulkan.h". The same enable then
+// controls inclusion of the extension interfaces in vulkan.h.
+
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+#include